Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit df34d04a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs

Pull befs fixes from Luis de Bethencourt:
 "I recently took maintainership of the befs file system [0]. This is
  the first time I send you a git pull request, so please let me know if
  all the below is OK.

  Salah Triki and myself have been cleaning the code and fixing a few
  small bugs.

  Sorry I couldn't send this sooner in the merge window, I was waiting
  to have my GPG key signed by kernel members at ELCE in Berlin a few
  days ago."

[0] https://lkml.org/lkml/2016/7/27/502

* tag 'befs-v4.9-rc1' of git://github.com/luisbg/linux-befs: (39 commits)
  befs: befs: fix style issues in datastream.c
  befs: improve documentation in datastream.c
  befs: fix typos in datastream.c
  befs: fix typos in btree.c
  befs: fix style issues in super.c
  befs: fix comment style
  befs: add check for ag_shift in superblock
  befs: dump inode_size superblock information
  befs: remove unnecessary initialization
  befs: fix typo in befs_sb_info
  befs: add flags field to validate superblock state
  befs: fix typo in befs_find_key
  befs: remove unused BEFS_BT_PARMATCH
  fs: befs: remove ret variable
  fs: befs: remove in vain variable assignment
  fs: befs: remove unnecessary *befs_sb variable
  fs: befs: remove useless initialization to zero
  fs: befs: remove in vain variable assignment
  fs: befs: Insert NULL inode to dentry
  fs: befs: Remove useless calls to brelse in befs_find_brun_dblindirect
  ...
parents 9ffc6694 a17e7d20
Loading
Loading
Loading
Loading
+5 −14
Original line number Original line Diff line number Diff line
@@ -43,7 +43,10 @@ struct befs_sb_info {
	u32 ag_shift;
	u32 ag_shift;
	u32 num_ags;
	u32 num_ags;


	/* jornal log entry */
	/* State of the superblock */
	u32 flags;

	/* Journal log entry */
	befs_block_run log_blocks;
	befs_block_run log_blocks;
	befs_off_t log_start;
	befs_off_t log_start;
	befs_off_t log_end;
	befs_off_t log_end;
@@ -79,7 +82,7 @@ enum befs_err {
	BEFS_BT_END,
	BEFS_BT_END,
	BEFS_BT_EMPTY,
	BEFS_BT_EMPTY,
	BEFS_BT_MATCH,
	BEFS_BT_MATCH,
	BEFS_BT_PARMATCH,
	BEFS_BT_OVERFLOW,
	BEFS_BT_NOT_FOUND
	BEFS_BT_NOT_FOUND
};
};


@@ -140,18 +143,6 @@ befs_iaddrs_per_block(struct super_block *sb)
	return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr);
	return BEFS_SB(sb)->block_size / sizeof (befs_disk_inode_addr);
}
}


static inline int
befs_iaddr_is_empty(const befs_inode_addr *iaddr)
{
	return (!iaddr->allocation_group) && (!iaddr->start) && (!iaddr->len);
}

static inline size_t
befs_brun_size(struct super_block *sb, befs_block_run run)
{
	return BEFS_SB(sb)->block_size * run.len;
}

#include "endian.h"
#include "endian.h"


#endif				/* _LINUX_BEFS_H */
#endif				/* _LINUX_BEFS_H */
+27 −33
Original line number Original line Diff line number Diff line
@@ -85,7 +85,7 @@ struct befs_btree_node {
};
};


/* local constants */
/* local constants */
static const befs_off_t befs_bt_inval = 0xffffffffffffffffULL;
static const befs_off_t BEFS_BT_INVAL = 0xffffffffffffffffULL;


/* local functions */
/* local functions */
static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds,
static int befs_btree_seekleaf(struct super_block *sb, const befs_data_stream *ds,
@@ -156,8 +156,6 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds,
	sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth);
	sup->max_depth = fs32_to_cpu(sb, od_sup->max_depth);
	sup->data_type = fs32_to_cpu(sb, od_sup->data_type);
	sup->data_type = fs32_to_cpu(sb, od_sup->data_type);
	sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr);
	sup->root_node_ptr = fs64_to_cpu(sb, od_sup->root_node_ptr);
	sup->free_node_ptr = fs64_to_cpu(sb, od_sup->free_node_ptr);
	sup->max_size = fs64_to_cpu(sb, od_sup->max_size);


	brelse(bh);
	brelse(bh);
	if (sup->magic != BEFS_BTREE_MAGIC) {
	if (sup->magic != BEFS_BTREE_MAGIC) {
@@ -183,8 +181,8 @@ befs_bt_read_super(struct super_block *sb, const befs_data_stream *ds,
 * Calls befs_read_datastream to read in the indicated btree node and
 * Calls befs_read_datastream to read in the indicated btree node and
 * makes sure its header fields are in cpu byteorder, byteswapping if
 * makes sure its header fields are in cpu byteorder, byteswapping if
 * necessary.
 * necessary.
 * Note: node->bh must be NULL when this function called first
 * Note: node->bh must be NULL when this function is called the first time.
 * time. Don't forget brelse(node->bh) after last call.
 * Don't forget brelse(node->bh) after last call.
 *
 *
 * On success, returns BEFS_OK and *@node contains the btree node that
 * On success, returns BEFS_OK and *@node contains the btree node that
 * starts at @node_off, with the node->head fields in cpu byte order.
 * starts at @node_off, with the node->head fields in cpu byte order.
@@ -244,7 +242,7 @@ befs_bt_read_node(struct super_block *sb, const befs_data_stream *ds,
 *   Read the superblock and rootnode of the b+tree.
 *   Read the superblock and rootnode of the b+tree.
 *   Drill down through the interior nodes using befs_find_key().
 *   Drill down through the interior nodes using befs_find_key().
 *   Once at the correct leaf node, use befs_find_key() again to get the
 *   Once at the correct leaf node, use befs_find_key() again to get the
 *   actuall value stored with the key.
 *   actual value stored with the key.
 */
 */
int
int
befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
@@ -283,9 +281,9 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,


	while (!befs_leafnode(this_node)) {
	while (!befs_leafnode(this_node)) {
		res = befs_find_key(sb, this_node, key, &node_off);
		res = befs_find_key(sb, this_node, key, &node_off);
		if (res == BEFS_BT_NOT_FOUND)
		/* if no key set, try the overflow node */
		if (res == BEFS_BT_OVERFLOW)
			node_off = this_node->head.overflow;
			node_off = this_node->head.overflow;
		/* if no match, go to overflow node */
		if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
		if (befs_bt_read_node(sb, ds, this_node, node_off) != BEFS_OK) {
			befs_error(sb, "befs_btree_find() failed to read "
			befs_error(sb, "befs_btree_find() failed to read "
				   "node at %llu", node_off);
				   "node at %llu", node_off);
@@ -293,15 +291,15 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
		}
		}
	}
	}


	/* at the correct leaf node now */
	/* at a leaf node now, check if it is correct */

	res = befs_find_key(sb, this_node, key, value);
	res = befs_find_key(sb, this_node, key, value);


	brelse(this_node->bh);
	brelse(this_node->bh);
	kfree(this_node);
	kfree(this_node);


	if (res != BEFS_BT_MATCH) {
	if (res != BEFS_BT_MATCH) {
		befs_debug(sb, "<--- %s Key %s not found", __func__, key);
		befs_error(sb, "<--- %s Key %s not found", __func__, key);
		befs_debug(sb, "<--- %s ERROR", __func__);
		*value = 0;
		*value = 0;
		return BEFS_BT_NOT_FOUND;
		return BEFS_BT_NOT_FOUND;
	}
	}
@@ -324,16 +322,12 @@ befs_btree_find(struct super_block *sb, const befs_data_stream *ds,
 * @findkey: Keystring to search for
 * @findkey: Keystring to search for
 * @value: If key is found, the value stored with the key is put here
 * @value: If key is found, the value stored with the key is put here
 *
 *
 * finds exact match if one exists, and returns BEFS_BT_MATCH
 * Finds exact match if one exists, and returns BEFS_BT_MATCH.
 * If no exact match, finds first key in node that is greater
 * If there is no match and node's value array is too small for key, return
 * (alphabetically) than the search key and returns BEFS_BT_PARMATCH
 * BEFS_BT_OVERFLOW.
 * (for partial match, I guess). Can you think of something better to
 * If no match and node should countain this key, return BEFS_BT_NOT_FOUND.
 * call it?
 *
 * If no key was a match or greater than the search key, return
 * BEFS_BT_NOT_FOUND.
 *
 *
 * Use binary search instead of a linear.
 * Uses binary search instead of a linear.
 */
 */
static int
static int
befs_find_key(struct super_block *sb, struct befs_btree_node *node,
befs_find_key(struct super_block *sb, struct befs_btree_node *node,
@@ -348,18 +342,16 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,


	befs_debug(sb, "---> %s %s", __func__, findkey);
	befs_debug(sb, "---> %s %s", __func__, findkey);


	*value = 0;

	findkey_len = strlen(findkey);
	findkey_len = strlen(findkey);


	/* if node can not contain key, just skeep this node */
	/* if node can not contain key, just skip this node */
	last = node->head.all_key_count - 1;
	last = node->head.all_key_count - 1;
	thiskey = befs_bt_get_key(sb, node, last, &keylen);
	thiskey = befs_bt_get_key(sb, node, last, &keylen);


	eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len);
	eq = befs_compare_strings(thiskey, keylen, findkey, findkey_len);
	if (eq < 0) {
	if (eq < 0) {
		befs_debug(sb, "<--- %s %s not found", __func__, findkey);
		befs_debug(sb, "<--- node can't contain %s", findkey);
		return BEFS_BT_NOT_FOUND;
		return BEFS_BT_OVERFLOW;
	}
	}


	valarray = befs_bt_valarray(node);
	valarray = befs_bt_valarray(node);
@@ -387,12 +379,15 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,
		else
		else
			first = mid + 1;
			first = mid + 1;
	}
	}

	/* return an existing value so caller can arrive to a leaf node */
	if (eq < 0)
	if (eq < 0)
		*value = fs64_to_cpu(sb, valarray[mid + 1]);
		*value = fs64_to_cpu(sb, valarray[mid + 1]);
	else
	else
		*value = fs64_to_cpu(sb, valarray[mid]);
		*value = fs64_to_cpu(sb, valarray[mid]);
	befs_debug(sb, "<--- %s found %s at %d", __func__, thiskey, mid);
	befs_error(sb, "<--- %s %s not found", __func__, findkey);
	return BEFS_BT_PARMATCH;
	befs_debug(sb, "<--- %s ERROR", __func__);
	return BEFS_BT_NOT_FOUND;
}
}


/**
/**
@@ -405,7 +400,7 @@ befs_find_key(struct super_block *sb, struct befs_btree_node *node,
 * @keysize: Length of the returned key
 * @keysize: Length of the returned key
 * @value: Value stored with the returned key
 * @value: Value stored with the returned key
 *
 *
 * Heres how it works: Key_no is the index of the key/value pair to 
 * Here's how it works: Key_no is the index of the key/value pair to
 * return in keybuf/value.
 * return in keybuf/value.
 * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is 
 * Bufsize is the size of keybuf (BEFS_NAME_LEN+1 is a good size). Keysize is 
 * the number of characters in the key (just a convenience).
 * the number of characters in the key (just a convenience).
@@ -422,7 +417,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
{
{
	struct befs_btree_node *this_node;
	struct befs_btree_node *this_node;
	befs_btree_super bt_super;
	befs_btree_super bt_super;
	befs_off_t node_off = 0;
	befs_off_t node_off;
	int cur_key;
	int cur_key;
	fs64 *valarray;
	fs64 *valarray;
	char *keystart;
	char *keystart;
@@ -467,7 +462,7 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
	while (key_sum + this_node->head.all_key_count <= key_no) {
	while (key_sum + this_node->head.all_key_count <= key_no) {


		/* no more nodes to look in: key_no is too large */
		/* no more nodes to look in: key_no is too large */
		if (this_node->head.right == befs_bt_inval) {
		if (this_node->head.right == BEFS_BT_INVAL) {
			*keysize = 0;
			*keysize = 0;
			*value = 0;
			*value = 0;
			befs_debug(sb,
			befs_debug(sb,
@@ -541,7 +536,6 @@ befs_btree_read(struct super_block *sb, const befs_data_stream *ds,
 * @node_off: Pointer to offset of current node within datastream. Modified
 * @node_off: Pointer to offset of current node within datastream. Modified
 * 		by the function.
 * 		by the function.
 *
 *
 *
 * Helper function for btree traverse. Moves the current position to the 
 * Helper function for btree traverse. Moves the current position to the 
 * start of the first leaf node.
 * start of the first leaf node.
 *
 *
@@ -608,7 +602,7 @@ static int
befs_leafnode(struct befs_btree_node *node)
befs_leafnode(struct befs_btree_node *node)
{
{
	/* all interior nodes (and only interior nodes) have an overflow node */
	/* all interior nodes (and only interior nodes) have an overflow node */
	if (node->head.overflow == befs_bt_inval)
	if (node->head.overflow == BEFS_BT_INVAL)
		return 1;
		return 1;
	else
	else
		return 0;
		return 0;
@@ -715,7 +709,7 @@ befs_bt_get_key(struct super_block *sb, struct befs_btree_node *node,
 *
 *
 * Returns 0 if @key1 and @key2 are equal.
 * Returns 0 if @key1 and @key2 are equal.
 * Returns >0 if @key1 is greater.
 * Returns >0 if @key1 is greater.
 * Returns <0 if @key2 is greater..
 * Returns <0 if @key2 is greater.
 */
 */
static int
static int
befs_compare_strings(const void *key1, int keylen1,
befs_compare_strings(const void *key1, int keylen1,
+125 −128
Original line number Original line Diff line number Diff line
@@ -37,7 +37,7 @@ static int befs_find_brun_dblindirect(struct super_block *sb,
/**
/**
 * befs_read_datastream - get buffer_head containing data, starting from pos.
 * befs_read_datastream - get buffer_head containing data, starting from pos.
 * @sb: Filesystem superblock
 * @sb: Filesystem superblock
 * @ds: datastrem to find data with
 * @ds: datastream to find data with
 * @pos: start of data
 * @pos: start of data
 * @off: offset of data in buffer_head->b_data
 * @off: offset of data in buffer_head->b_data
 *
 *
@@ -75,7 +75,13 @@ befs_read_datastream(struct super_block *sb, const befs_data_stream *ds,
	return bh;
	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
 * Takes a file position and gives back a brun who's starting block
 * is block number fblock of the file.
 * is block number fblock of the file.
 * 
 * 
@@ -115,7 +121,7 @@ befs_fblock2brun(struct super_block *sb, const befs_data_stream *data,
/**
/**
 * befs_read_lsmylink - read long symlink from datastream.
 * befs_read_lsmylink - read long symlink from datastream.
 * @sb: Filesystem superblock 
 * @sb: Filesystem superblock 
 * @ds: Datastrem to read from
 * @ds: Datastream to read from
 * @buff: Buffer in which to place long symlink data
 * @buff: Buffer in which to place long symlink data
 * @len: Length of the long symlink in bytes
 * @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 */
	befs_off_t bytes_read = 0;	/* bytes readed */
	u16 plen;
	u16 plen;
	struct buffer_head *bh;
	struct buffer_head *bh;

	befs_debug(sb, "---> %s length: %llu", __func__, len);
	befs_debug(sb, "---> %s length: %llu", __func__, len);


	while (bytes_read < 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;
		metablocks += ds->indirect.len;


	/*
	/*
	   Double indir block, plus all the indirect blocks it mapps
	 * Double indir block, plus all the indirect blocks it maps.
	   In the double-indirect range, all block runs of data are
	 * In the double-indirect range, all block runs of data are
	   BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know 
	 * BEFS_DBLINDIR_BRUN_LEN blocks long. Therefore, we know
	   how many data block runs are in the double-indirect region,
	 * how many data block runs are in the double-indirect region,
	   and from that we know how many indirect blocks it takes to
	 * and from that we know how many indirect blocks it takes to
	   map them. We assume that the indirect blocks are also
	 * map them. We assume that the indirect blocks are also
	   BEFS_DBLINDIR_BRUN_LEN blocks long.
	 * BEFS_DBLINDIR_BRUN_LEN blocks long.
	 */
	 */
	if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) {
	if (ds->size > ds->max_indirect_range && ds->max_indirect_range != 0) {
		uint dbl_bytes;
		uint dbl_bytes;
@@ -212,35 +219,34 @@ befs_count_blocks(struct super_block *sb, const befs_data_stream *ds)
	return blocks;
	return blocks;
}
}


/*
/**
	Finds the block run that starts at file block number blockno
 * befs_find_brun_direct - find a direct block run in the datastream
	in the file represented by the datastream data, if that 
 * @sb: the superblock
	blockno is in the direct region of the datastream.
 * @data: the datastream
	
 * @blockno: the blocknumber to find
	sb: the superblock
 * @run: The found run is passed back through this pointer
	data: the datastream
 *
	blockno: the blocknumber to find
 * Finds the block run that starts at file block number blockno
	run: The found run is passed back through this pointer
 * 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.
 * 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
 * Algorithm:
	contains the blockno-th filesystem block. This is necessary
 * Linear search. Checks each element of array[] to see if it
	because the block runs map variable amounts of data. Simply
 * contains the blockno-th filesystem block. This is necessary
	keeps a count of the number of blocks searched so far (sum),
 * because the block runs map variable amounts of data. Simply
	incrementing this by the length of each block run as we come
 * keeps a count of the number of blocks searched so far (sum),
	across it. Adds sum to *count before returning (this is so
 * incrementing this by the length of each block run as we come
	you can search multiple arrays that are logicaly one array,
 * across it. Adds sum to *count before returning (this is so
	as in the indirect region code).
 * 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
 * When/if blockno is found, if blockno is inside of a block
	of the block run, so that blockno is the start and len is
 * run as stored on disk, we offset the start and length members
	still valid (the run ends in the same place).
 * 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
static int
befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data,
befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data,
@@ -249,21 +255,14 @@ befs_find_brun_direct(struct super_block *sb, const befs_data_stream *data,
	int i;
	int i;
	const befs_block_run *array = data->direct;
	const befs_block_run *array = data->direct;
	befs_blocknr_t sum;
	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);
	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;
	for (i = 0, sum = 0; i < BEFS_NUM_DIRECT_BLOCKS;
	     sum += array[i].len, i++) {
	     sum += array[i].len, i++) {
		if (blockno >= sum && blockno < sum + (array[i].len)) {
		if (blockno >= sum && blockno < sum + (array[i].len)) {
			int offset = blockno - sum;
			int offset = blockno - sum;

			run->allocation_group = array[i].allocation_group;
			run->allocation_group = array[i].allocation_group;
			run->start = array[i].start + offset;
			run->start = array[i].start + offset;
			run->len = array[i].len - offset;
			run->len = array[i].len - offset;
@@ -275,32 +274,33 @@ 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__);
	befs_debug(sb, "---> %s ERROR", __func__);
	return BEFS_ERR;
	return BEFS_ERR;
}
}


/*
/**
	Finds the block run that starts at file block number blockno
 * befs_find_brun_indirect - find a block run in the datastream
	in the file represented by the datastream data, if that 
 * @sb: the superblock
	blockno is in the indirect region of the datastream.
 * @data: the datastream
	
 * @blockno: the blocknumber to find
	sb: the superblock
 * @run: The found run is passed back through this pointer
	data: the datastream
 *
	blockno: the blocknumber to find
 * Finds the block run that starts at file block number blockno
	run: The found run is passed back through this pointer
 * 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.
 * 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
 * Algorithm:
	it in and search through it for	search_blk.
 * 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
 * XXX:
	region.
 * Really should check to make sure blockno is inside indirect
	
 * region.
	2001-11-15 Will Dyson
 */
 */
static int
static int
befs_find_brun_indirect(struct super_block *sb,
befs_find_brun_indirect(struct super_block *sb,
@@ -326,11 +326,12 @@ befs_find_brun_indirect(struct super_block *sb,


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


@@ -370,46 +371,45 @@ befs_find_brun_indirect(struct super_block *sb,
	return BEFS_ERR;
	return BEFS_ERR;
}
}


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


	befs_blocknr_t indir_start_blk =
	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;
	off_t dbl_indir_off = blockno - indir_start_blk;


@@ -471,7 +470,7 @@ befs_find_brun_dblindirect(struct super_block *sb,
	}
	}


	dbl_indir_block =
	dbl_indir_block =
	    befs_bread(sb, iaddr2blockno(sb, &data->double_indirect) +
	    sb_bread(sb, iaddr2blockno(sb, &data->double_indirect) +
					dbl_which_block);
					dbl_which_block);
	if (dbl_indir_block == NULL) {
	if (dbl_indir_block == NULL) {
		befs_error(sb, "%s couldn't read the "
		befs_error(sb, "%s couldn't read the "
@@ -479,7 +478,6 @@ befs_find_brun_dblindirect(struct super_block *sb,
			   (unsigned long)
			   (unsigned long)
			   iaddr2blockno(sb, &data->double_indirect) +
			   iaddr2blockno(sb, &data->double_indirect) +
			   dbl_which_block);
			   dbl_which_block);
		brelse(dbl_indir_block);
		return BEFS_ERR;
		return BEFS_ERR;
	}
	}


@@ -499,12 +497,11 @@ befs_find_brun_dblindirect(struct super_block *sb,
	}
	}


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


+1 −0
Original line number Original line Diff line number Diff line
@@ -169,6 +169,7 @@ befs_dump_super_block(const struct super_block *sb, befs_super_block * sup)


	befs_debug(sb, "  num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks));
	befs_debug(sb, "  num_blocks %llu", fs64_to_cpu(sb, sup->num_blocks));
	befs_debug(sb, "  used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks));
	befs_debug(sb, "  used_blocks %llu", fs64_to_cpu(sb, sup->used_blocks));
	befs_debug(sb, "  inode_size %u", fs32_to_cpu(sb, sup->inode_size));


	befs_debug(sb, "  magic2 %08x", fs32_to_cpu(sb, sup->magic2));
	befs_debug(sb, "  magic2 %08x", fs32_to_cpu(sb, sup->magic2));
	befs_debug(sb, "  blocks_per_ag %u",
	befs_debug(sb, "  blocks_per_ag %u",
+1 −25
Original line number Original line Diff line number Diff line
@@ -27,7 +27,7 @@ struct buffer_head *
befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
{
{
	struct buffer_head *bh;
	struct buffer_head *bh;
	befs_blocknr_t block = 0;
	befs_blocknr_t block;
	struct befs_sb_info *befs_sb = BEFS_SB(sb);
	struct befs_sb_info *befs_sb = BEFS_SB(sb);


	befs_debug(sb, "---> Enter %s "
	befs_debug(sb, "---> Enter %s "
@@ -59,27 +59,3 @@ befs_bread_iaddr(struct super_block *sb, befs_inode_addr iaddr)
	befs_debug(sb, "<--- %s ERROR", __func__);
	befs_debug(sb, "<--- %s ERROR", __func__);
	return NULL;
	return NULL;
}
}

struct buffer_head *
befs_bread(struct super_block *sb, befs_blocknr_t block)
{
	struct buffer_head *bh;

	befs_debug(sb, "---> Enter %s %lu", __func__, (unsigned long)block);

	bh = sb_bread(sb, block);

	if (bh == NULL) {
		befs_error(sb, "Failed to read block %lu",
			   (unsigned long)block);
		goto error;
	}

	befs_debug(sb, "<--- %s", __func__);

	return bh;

      error:
	befs_debug(sb, "<--- %s ERROR", __func__);
	return NULL;
}
Loading