/*
 * linux/fs/befs/datastream.c
 *
 * Copyright (C) 2001 Will Dyson <will_dyson@pobox.com>
 *
 * Based on portions of file.c by Makoto Kato <m_kato@ga2.so-net.ne.jp>
 *
 * Many thanks to Dominic Giampaolo, author of "Practical File System
 * Design with the Be File System", for such a helpful book.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/buffer_head.h>
#include <linux/string.h>

#include "befs.h"
#include "datastream.h"
#include "io.h"

const befs_inode_addr BAD_IADDR = { 0, 0, 0 };

static int befs_find_brun_direct(struct super_block *sb,
				 befs_data_stream * data,
				 befs_blocknr_t blockno, befs_block_run * run);

static int befs_find_brun_indirect(struct super_block *sb,
				   befs_data_stream * data,
				   befs_blocknr_t blockno,
				   befs_block_run * run);

static int befs_find_brun_dblindirect(struct super_block *sb,
				      befs_data_stream * data,
				      befs_blocknr_t blockno,
				      befs_block_run * run);

/**
 * befs_read_datastream - get buffer_head containing data, starting from pos.
 * @sb: Filesystem superblock
 * @ds: datastrem to find data with
 * @pos: start of data
 * @off: offset of data in buffer_head->b_data
 *
 * Returns pointer to buffer_head containing data starting with offset @off,
 * if you don't need to know offset just set @off = NULL.
 */
struct buffer_head *
befs_read_datastream(struct super_block *sb, befs_data_stream * ds,
		     befs_off_t pos, uint * off)
{
	struct buffer_head *bh = NULL;
	befs_block_run run;
	befs_blocknr_t block;	/* block coresponding to pos */

	befs_debug(sb, "---> befs_read_datastream() %Lu", pos);
	block = pos >> BEFS_SB(sb)->block_shift;
	if (off)
		*off = pos - (block << BEFS_SB(sb)->block_shift);

	if (befs_fblock2brun(sb, ds, block, &run) != BEFS_OK) {
		befs_error(sb, "BeFS: Error finding disk addr of block %lu",
			   block);
		befs_debug(sb, "<--- befs_read_datastream() ERROR");
		return NULL;
	}
	bh = befs_bread_iaddr(sb, run);
	if (!bh) {
		befs_error(sb, "BeFS: Error reading block %lu from datastream",
			   block);
		return NULL;
	}

	befs_debug(sb, "<--- befs_read_datastream() read data, starting at %Lu",
		   pos);

	return bh;
}

/*
 * Takes a file position and gives back a brun who's starting block
 * is block number fblock of the file.
 * 
 * Returns BEFS_OK or BEFS_ERR.
 * 
 * Calls specialized functions for each of the three possible
 * datastream regions.
 *
 * 2001-11-15 Will Dyson
 */
int
befs_fblock2brun(struct super_block *sb, befs_data_stream * data,
		 befs_blocknr_t fblock, befs_block_run * run)
{
	int err;
	befs_off_t pos = fblock << BEFS_SB(sb)->block_shift;

	if (pos < data->max_direct_range) {
		err = befs_find_brun_direct(sb, data, fblock, run);

	} else if (pos < data->max_indirect_range) {
		err = befs_find_brun_indirect(sb, data, fblock, run);

	} else if (pos < data->max_double_indirect_range) {
		err = befs_find_brun_dblindirect(sb, data, fblock, run);

	} else {
		befs_error(sb,
			   "befs_fblock2brun() was asked to find block %lu, "
			   "which is not mapped by the datastream\n", fblock);
		err = BEFS_ERR;
	}
	return err;
}

/**
 * befs_read_lsmylink - read long symlink from datastream.
 * @sb: Filesystem superblock 
 * @ds: Datastrem to read from
 * @buf: Buffer in which to place long symlink data
 * @len: Length of the long symlink in bytes
 *
 * Returns the number of bytes read
 */
size_t
befs_read_lsymlink(struct super_block * sb, befs_data_stream * ds, void *buff,
		   befs_off_t len)
{
	befs_off_t bytes_read = 0;	/* bytes readed */
	u16 plen;
	struct buffer_head *bh = NULL;
	befs_debug(sb, "---> befs_read_lsymlink() length: %Lu", len);

	while (bytes_read < len) {
		bh = befs_read_datastream(sb, ds, bytes_read, NULL);
		if (!bh) {
			befs_error(sb, "BeFS: Error reading datastream block "
				   "starting from %Lu", bytes_read);
			befs_debug(sb, "<--- befs_read_lsymlink() ERROR");
			return bytes_read;

		}
		plen = ((bytes_read + BEFS_SB(sb)->block_size) < len) ?
		    BEFS_SB(sb)->block_size : len - bytes_read;
		memcpy(buff + bytes_read, bh->b_data, plen);
		brelse(bh);
		bytes_read += plen;
	}

	befs_debug(sb, "<--- befs_read_lsymlink() read %u bytes", bytes_read);
	return bytes_read;
}

/**
 * befs_count_blocks - blocks used by a file
 * @sb: Filesystem superblock
 * @ds: Datastream of the file
 *
 * Counts the number of fs blocks that the file represented by
 * inode occupies on the filesystem, counting both regular file
 * data and filesystem metadata (and eventually attribute data
 * when we support attributes)
*/

befs_blocknr_t
befs_count_blocks(struct super_block * sb, befs_data_stream * ds)
{
	befs_blocknr_t blocks;
	befs_blocknr_t datablocks;	/* File data blocks */
	befs_blocknr_t metablocks;	/* FS metadata blocks */
	befs_sb_info *befs_sb = BEFS_SB(sb);

	befs_debug(sb, "---> befs_count_blocks()");

	datablocks = ds->size >> befs_sb->block_shift;
	if (ds->size & (befs_sb->block_size - 1))
		datablocks += 1;

	metablocks = 1;		/* Start with 1 block for inode */

	/* Size of indirect block */
	if (ds->size > ds->max_direct_range)
		metablocks += ds->indirect.len;

	/*
	   Double indir block, plus all the indirect blocks it mapps
	   In the double-indirect range, all block runs of data are
	   BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know 
	   how many data block runs are in the double-indirect region,
	   and from that we know how many indirect blocks it takes to
	   map them. We assume that the indirect blocks are also
	   BEFS_DBLINDIR_BRUN_LEN blocks long.
	 */
	if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) {
		uint dbl_bytes;
		uint dbl_bruns;
		uint indirblocks;

		dbl_bytes =
		    ds->max_double_indirect_range - ds->max_indirect_range;
		dbl_bruns =
		    dbl_bytes / (befs_sb->block_size * BEFS_DBLINDIR_BRUN_LEN);
		indirblocks = dbl_bruns / befs_iaddrs_per_block(sb);

		metablocks += ds->double_indirect.len;
		metablocks += indirblocks;
	}

	blocks = datablocks + metablocks;
	befs_debug(sb, "<--- befs_count_blocks() %u blocks", blocks);

	return blocks;
}

/*
	Finds the block run that starts at file block number blockno
	in the file represented by the datastream data, if that 
	blockno is in the direct region of the datastream.
	
	sb: the superblock
	data: the datastream
	blockno: the blocknumber to find
	run: The found run is passed back through this pointer
	
	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
	otherwise.
	
	Algorithm:
	Linear search. Checks each element of array[] to see if it
	contains the blockno-th filesystem block. This is necessary
	because the block runs map variable amounts of data. Simply
	keeps a count of the number of blocks searched so far (sum),
	incrementing this by the length of each block run as we come
	across it. Adds sum to *count before returning (this is so
	you can search multiple arrays that are logicaly one array,
	as in the indirect region code).
	
	When/if blockno is found, if blockno is inside of a block 
	run as stored on disk, we offset the start and lenght members 
	of the block run, so that blockno is the start and len is
	still valid (the run ends in the same place).
	
	2001-11-15 Will Dyson
*/
static int
befs_find_brun_direct(struct super_block *sb, befs_data_stream * data,
		      befs_blocknr_t blockno, befs_block_run * run)
{
	int i;
	befs_block_run *array = data->direct;
	befs_blocknr_t sum;
	befs_blocknr_t max_block =
	    data->max_direct_range >> BEFS_SB(sb)->block_shift;

	befs_debug(sb, "---> befs_find_brun_direct(), find %lu", blockno);

	if (blockno > max_block) {
		befs_error(sb, "befs_find_brun_direct() passed block outside of"
			   "direct region");
		return BEFS_ERR;
	}

	for (i = 0, sum = 0; i < BEFS_NUM_DIRECT_BLOCKS;
	     sum += array[i].len, i++) {
		if (blockno >= sum && blockno < sum + (array[i].len)) {
			int offset = blockno - sum;
			run->allocation_group = array[i].allocation_group;
			run->start = array[i].start + offset;
			run->len = array[i].len - offset;

			befs_debug(sb, "---> befs_find_brun_direct(), "
				   "found %lu at direct[%d]", blockno, i);
			return BEFS_OK;
		}
	}

	befs_debug(sb, "---> befs_find_brun_direct() ERROR");
	return BEFS_ERR;
}

/*
	Finds the block run that starts at file block number blockno
	in the file represented by the datastream data, if that 
	blockno is in the indirect region of the datastream.
	
	sb: the superblock
	data: the datastream
	blockno: the blocknumber to find
	run: The found run is passed back through this pointer
	
	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
	otherwise.
	
	Algorithm:
	For each block in the indirect run of the datastream, read
	it in and search through it for	search_blk.
	
	XXX:
	Really should check to make sure blockno is inside indirect
	region.
	
	2001-11-15 Will Dyson
*/
static int
befs_find_brun_indirect(struct super_block *sb,
			befs_data_stream * data, befs_blocknr_t blockno,
			befs_block_run * run)
{
	int i, j;
	befs_blocknr_t sum = 0;
	befs_blocknr_t indir_start_blk;
	befs_blocknr_t search_blk;
	struct buffer_head *indirblock;
	befs_disk_block_run *array;

	befs_block_run indirect = data->indirect;
	befs_blocknr_t indirblockno = iaddr2blockno(sb, &indirect);
	int arraylen = befs_iaddrs_per_block(sb);

	befs_debug(sb, "---> befs_find_brun_indirect(), find %lu", blockno);

	indir_start_blk = data->max_direct_range >> BEFS_SB(sb)->block_shift;
	search_blk = blockno - indir_start_blk;

	/* Examine blocks of the indirect run one at a time */
	for (i = 0; i < indirect.len; i++) {
		indirblock = befs_bread(sb, indirblockno + i);
		if (indirblock == NULL) {
			befs_debug(sb,
				   "---> befs_find_brun_indirect() failed to "
				   "read disk block %lu from the indirect brun",
				   indirblockno + i);
			return BEFS_ERR;
		}

		array = (befs_disk_block_run *) indirblock->b_data;

		for (j = 0; j < arraylen; ++j) {
			int len = fs16_to_cpu(sb, array[j].len);

			if (search_blk >= sum && search_blk < sum + len) {
				int offset = search_blk - sum;
				run->allocation_group =
				    fs32_to_cpu(sb, array[j].allocation_group);
				run->start =
				    fs16_to_cpu(sb, array[j].start) + offset;
				run->len =
				    fs16_to_cpu(sb, array[j].len) - offset;

				brelse(indirblock);
				befs_debug(sb,
					   "<--- befs_find_brun_indirect() found "
					   "file block %lu at indirect[%d]",
					   blockno, j + (i * arraylen));
				return BEFS_OK;
			}
			sum += len;
		}

		brelse(indirblock);
	}

	/* Only fallthrough is an error */
	befs_error(sb, "BeFS: befs_find_brun_indirect() failed to find "
		   "file block %lu", blockno);

	befs_debug(sb, "<--- befs_find_brun_indirect() ERROR");
	return BEFS_ERR;
}

/*
	Finds the block run that starts at file block number blockno
	in the file represented by the datastream data, if that 
	blockno is in the double-indirect region of the datastream.
	
	sb: the superblock
	data: the datastream
	blockno: the blocknumber to find
	run: The found run is passed back through this pointer
	
	Return value is BEFS_OK if the blockrun is found, BEFS_ERR
	otherwise.
	
	Algorithm:
	The block runs in the double-indirect region are different.
	They are always allocated 4 fs blocks at a time, so each
	block run maps a constant amount of file data. This means
	that we can directly calculate how many block runs into the
	double-indirect region we need to go to get to the one that
	maps a particular filesystem block.
	
	We do this in two stages. First we calculate which of the
	inode addresses in the double-indirect block will point us
	to the indirect block that contains the mapping for the data,
	then we calculate which of the inode addresses in that 
	indirect block maps the data block we are after.
	
	Oh, and once we've done that, we actually read in the blocks 
	that contain the inode addresses we calculated above. Even 
	though the double-indirect run may be several blocks long, 
	we can calculate which of those blocks will contain the index
	we are after and only read that one. We then follow it to 
	the indirect block and perform a  similar process to find
	the actual block run that maps the data block we are interested
	in.
	
	Then we offset the run as in befs_find_brun_array() and we are 
	done.
	
	2001-11-15 Will Dyson
*/
static int
befs_find_brun_dblindirect(struct super_block *sb,
			   befs_data_stream * data, befs_blocknr_t blockno,
			   befs_block_run * run)
{
	int dblindir_indx;
	int indir_indx;
	int offset;
	int dbl_which_block;
	int which_block;
	int dbl_block_indx;
	int block_indx;
	off_t dblindir_leftover;
	befs_blocknr_t blockno_at_run_start;
	struct buffer_head *dbl_indir_block;
	struct buffer_head *indir_block;
	befs_block_run indir_run;
	befs_disk_inode_addr *iaddr_array = NULL;
	befs_sb_info *befs_sb = BEFS_SB(sb);

	befs_blocknr_t indir_start_blk =
	    data->max_indirect_range >> befs_sb->block_shift;

	off_t dbl_indir_off = blockno - indir_start_blk;

	/* number of data blocks mapped by each of the iaddrs in
	 * the indirect block pointed to by the double indirect block
	 */
	size_t iblklen = BEFS_DBLINDIR_BRUN_LEN;

	/* number of data blocks mapped by each of the iaddrs in
	 * the double indirect block
	 */
	size_t diblklen = iblklen * befs_iaddrs_per_block(sb)
	    * BEFS_DBLINDIR_BRUN_LEN;

	befs_debug(sb, "---> befs_find_brun_dblindirect() find %lu", blockno);

	/* First, discover which of the double_indir->indir blocks
	 * contains pos. Then figure out how much of pos that
	 * accounted for. Then discover which of the iaddrs in
	 * the indirect block contains pos.
	 */

	dblindir_indx = dbl_indir_off / diblklen;
	dblindir_leftover = dbl_indir_off % diblklen;
	indir_indx = dblindir_leftover / diblklen;

	/* Read double indirect block */
	dbl_which_block = dblindir_indx / befs_iaddrs_per_block(sb);
	if (dbl_which_block > data->double_indirect.len) {
		befs_error(sb, "The double-indirect index calculated by "
			   "befs_read_brun_dblindirect(), %d, is outside the range "
			   "of the double-indirect block", dblindir_indx);
		return BEFS_ERR;
	}

	dbl_indir_block =
	    befs_bread(sb, iaddr2blockno(sb, &data->double_indirect) +
					dbl_which_block);
	if (dbl_indir_block == NULL) {
		befs_error(sb, "befs_read_brun_dblindirect() couldn't read the "
			   "double-indirect block at blockno %lu",
			   iaddr2blockno(sb,
					 &data->double_indirect) +
			   dbl_which_block);
		brelse(dbl_indir_block);
		return BEFS_ERR;
	}

	dbl_block_indx =
	    dblindir_indx - (dbl_which_block * befs_iaddrs_per_block(sb));
	iaddr_array = (befs_disk_inode_addr *) dbl_indir_block->b_data;
	indir_run = fsrun_to_cpu(sb, iaddr_array[dbl_block_indx]);
	brelse(dbl_indir_block);
	iaddr_array = NULL;

	/* Read indirect block */
	which_block = indir_indx / befs_iaddrs_per_block(sb);
	if (which_block > indir_run.len) {
		befs_error(sb, "The indirect index calculated by "
			   "befs_read_brun_dblindirect(), %d, is outside the range "
			   "of the indirect block", indir_indx);
		return BEFS_ERR;
	}

	indir_block =
	    befs_bread(sb, iaddr2blockno(sb, &indir_run) + which_block);
	if (indir_block == NULL) {
		befs_error(sb, "befs_read_brun_dblindirect() couldn't read the "
			   "indirect block at blockno %lu",
			   iaddr2blockno(sb, &indir_run) + which_block);
		brelse(indir_block);
		return BEFS_ERR;
	}

	block_indx = indir_indx - (which_block * befs_iaddrs_per_block(sb));
	iaddr_array = (befs_disk_inode_addr *) indir_block->b_data;
	*run = fsrun_to_cpu(sb, iaddr_array[block_indx]);
	brelse(indir_block);
	iaddr_array = NULL;

	blockno_at_run_start = indir_start_blk;
	blockno_at_run_start += diblklen * dblindir_indx;
	blockno_at_run_start += iblklen * indir_indx;
	offset = blockno - blockno_at_run_start;

	run->start += offset;
	run->len -= offset;

	befs_debug(sb, "Found file block %lu in double_indirect[%d][%d],"
		   " double_indirect_leftover = %lu",
		   blockno, dblindir_indx, indir_indx, dblindir_leftover);

	return BEFS_OK;
}
