diff options
Diffstat (limited to 'fs/befs/datastream.c')
| -rw-r--r-- | fs/befs/datastream.c | 253 | 
1 files changed, 125 insertions, 128 deletions
diff --git a/fs/befs/datastream.c b/fs/befs/datastream.c index af1bc19b7c85..b4c7ba013c0d 100644 --- a/fs/befs/datastream.c +++ b/fs/befs/datastream.c @@ -22,22 +22,22 @@ const befs_inode_addr BAD_IADDR = { 0, 0, 0 };  static int befs_find_brun_direct(struct super_block *sb,  				 const befs_data_stream *data, -				 befs_blocknr_t blockno, befs_block_run * run); +				 befs_blocknr_t blockno, befs_block_run *run);  static int befs_find_brun_indirect(struct super_block *sb,  				   const befs_data_stream *data,  				   befs_blocknr_t blockno, -				   befs_block_run * run); +				   befs_block_run *run);  static int befs_find_brun_dblindirect(struct super_block *sb,  				      const befs_data_stream *data,  				      befs_blocknr_t blockno, -				      befs_block_run * run); +				      befs_block_run *run);  /**   * befs_read_datastream - get buffer_head containing data, starting from pos.   * @sb: Filesystem superblock - * @ds: datastrem to find data with + * @ds: datastream to find data with   * @pos: start of data   * @off: offset of data in buffer_head->b_data   * @@ -46,7 +46,7 @@ static int befs_find_brun_dblindirect(struct super_block *sb,   */  struct buffer_head *  befs_read_datastream(struct super_block *sb, const befs_data_stream *ds, -		     befs_off_t pos, uint * off) +		     befs_off_t pos, uint *off)  {  	struct buffer_head *bh;  	befs_block_run run; @@ -75,7 +75,13 @@ befs_read_datastream(struct super_block *sb, const befs_data_stream *ds,  	return bh;  } -/* +/** + * befs_fblock2brun - give back block run for fblock + * @sb: the superblock + * @data: datastream to read from + * @fblock: the blocknumber with the file position to find + * @run: The found run is passed back through this pointer + *   * Takes a file position and gives back a brun who's starting block   * is block number fblock of the file.   *  @@ -88,7 +94,7 @@ befs_read_datastream(struct super_block *sb, const befs_data_stream *ds,   */  int  befs_fblock2brun(struct super_block *sb, const befs_data_stream *data, -		 befs_blocknr_t fblock, befs_block_run * run) +		 befs_blocknr_t fblock, befs_block_run *run)  {  	int err;  	befs_off_t pos = fblock << BEFS_SB(sb)->block_shift; @@ -115,7 +121,7 @@ befs_fblock2brun(struct super_block *sb, const befs_data_stream *data,  /**   * befs_read_lsmylink - read long symlink from datastream.   * @sb: Filesystem superblock  - * @ds: Datastrem to read from + * @ds: Datastream to read from   * @buff: Buffer in which to place long symlink data   * @len: Length of the long symlink in bytes   * @@ -128,6 +134,7 @@ befs_read_lsymlink(struct super_block *sb, const befs_data_stream *ds,  	befs_off_t bytes_read = 0;	/* bytes readed */  	u16 plen;  	struct buffer_head *bh; +  	befs_debug(sb, "---> %s length: %llu", __func__, len);  	while (bytes_read < len) { @@ -183,13 +190,13 @@ befs_count_blocks(struct super_block *sb, const befs_data_stream *ds)  		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. +	 * Double indir block, plus all the indirect blocks it maps. +	 * 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; @@ -212,58 +219,50 @@ befs_count_blocks(struct super_block *sb, const befs_data_stream *ds)  	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 length 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 -*/ +/** + * befs_find_brun_direct - find a direct block run in the datastream + * @sb: the superblock + * @data: the datastream + * @blockno: the blocknumber to find + * @run: The found run is passed back through this pointer + * + * 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. + * + * 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 length members + * of the block run, so that blockno is the start and len is + * still valid (the run ends in the same place). + */  static int  befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data, -		      befs_blocknr_t blockno, befs_block_run * run) +		      befs_blocknr_t blockno, befs_block_run *run)  {  	int i;  	const 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, "---> %s, find %lu", __func__, (unsigned long)blockno); -	if (blockno > max_block) { -		befs_error(sb, "%s passed block outside of direct region", -			   __func__); -		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; @@ -275,38 +274,39 @@ befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data,  		}  	} +	befs_error(sb, "%s failed to find file block %lu", __func__, +		   (unsigned long)blockno);  	befs_debug(sb, "---> %s ERROR", __func__);  	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 -*/ +/** + * befs_find_brun_indirect - find a block run in the datastream + * @sb: the superblock + * @data: the datastream + * @blockno: the blocknumber to find + * @run: The found run is passed back through this pointer + * + * 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. + * + * 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. + */  static int  befs_find_brun_indirect(struct super_block *sb,  			const befs_data_stream *data,  			befs_blocknr_t blockno, -			befs_block_run * run) +			befs_block_run *run)  {  	int i, j;  	befs_blocknr_t sum = 0; @@ -326,11 +326,12 @@ befs_find_brun_indirect(struct super_block *sb,  	/* Examine blocks of the indirect run one at a time */  	for (i = 0; i < indirect.len; i++) { -		indirblock = befs_bread(sb, indirblockno + i); +		indirblock = sb_bread(sb, indirblockno + i);  		if (indirblock == NULL) { -			befs_debug(sb, "---> %s failed to read " +			befs_error(sb, "---> %s failed to read "  				   "disk block %lu from the indirect brun",  				   __func__, (unsigned long)indirblockno + i); +			befs_debug(sb, "<--- %s ERROR", __func__);  			return BEFS_ERR;  		} @@ -370,52 +371,51 @@ befs_find_brun_indirect(struct super_block *sb,  	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 -*/ +/** + * befs_find_brun_dblindirect - find a block run in the datastream + * @sb: the superblock + * @data: the datastream + * @blockno: the blocknumber to find + * @run: The found run is passed back through this pointer + * + * 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. + * + * 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. + */  static int  befs_find_brun_dblindirect(struct super_block *sb,  			   const befs_data_stream *data,  			   befs_blocknr_t blockno, -			   befs_block_run * run) +			   befs_block_run *run)  {  	int dblindir_indx;  	int indir_indx; @@ -430,10 +430,9 @@ befs_find_brun_dblindirect(struct super_block *sb,  	struct buffer_head *indir_block;  	befs_block_run indir_run;  	befs_disk_inode_addr *iaddr_array; -	struct befs_sb_info *befs_sb = BEFS_SB(sb);  	befs_blocknr_t indir_start_blk = -	    data->max_indirect_range >> befs_sb->block_shift; +	    data->max_indirect_range >> BEFS_SB(sb)->block_shift;  	off_t dbl_indir_off = blockno - indir_start_blk; @@ -471,7 +470,7 @@ befs_find_brun_dblindirect(struct super_block *sb,  	}  	dbl_indir_block = -	    befs_bread(sb, iaddr2blockno(sb, &data->double_indirect) + +	    sb_bread(sb, iaddr2blockno(sb, &data->double_indirect) +  					dbl_which_block);  	if (dbl_indir_block == NULL) {  		befs_error(sb, "%s couldn't read the " @@ -479,7 +478,6 @@ befs_find_brun_dblindirect(struct super_block *sb,  			   (unsigned long)  			   iaddr2blockno(sb, &data->double_indirect) +  			   dbl_which_block); -		brelse(dbl_indir_block);  		return BEFS_ERR;  	} @@ -499,12 +497,11 @@ befs_find_brun_dblindirect(struct super_block *sb,  	}  	indir_block = -	    befs_bread(sb, iaddr2blockno(sb, &indir_run) + which_block); +	    sb_bread(sb, iaddr2blockno(sb, &indir_run) + which_block);  	if (indir_block == NULL) {  		befs_error(sb, "%s couldn't read the indirect block "  			   "at blockno %lu", __func__, (unsigned long)  			   iaddr2blockno(sb, &indir_run) + which_block); -		brelse(indir_block);  		return BEFS_ERR;  	}  |