diff -Nru linux/fs/reiserfs/item_ops.c linux.old/fs/reiserfs/item_ops.c
--- linux/fs/reiserfs/item_ops.c Fri Apr 20 11:43:58 2001
+++ linux.old/fs/reiserfs/item_ops.c Fri Apr 20 11:43:58 2001
@@ -20,6 +20,8 @@
/* and where are the comments? how about saying where we can find an
explanation of each item handler method? -Hans */
+#define check_key_version(ih, key) (ih_version(ih) == le_key_version(key))
+
//////////////////////////////////////////////////////////////////////////////
// stat data functions
//
@@ -74,9 +76,12 @@
}
}
-
-// make sure that bh contains formatted node of reiserfs tree of
-// 'level'-th level
-static int is_tree_node (struct buffer_head * bh, int level)
+int reiserfs_check_node (struct buffer_head *bh, int level)
{
if (B_LEVEL (bh) != level) {
- printk ("is_tree_node: node level %d does not match to the expected one %d\n",
+ printk (__FUNCTION__ ": node level %d does not match to the expected one %d\n",
B_LEVEL (bh), level);
+ goto error;
+ }
+
+ if (level == DISK_LEAF_NODE_LEVEL) {
+ if (is_leaf (bh->b_data, bh->b_size, bh))
+ return 0; /* OK */
+ } else if (is_internal (bh->b_data, bh->b_size, bh)) {
return 0;
}
- if (level == DISK_LEAF_NODE_LEVEL)
- return is_leaf (bh->b_data, bh->b_size, bh);
+struct buffer_head * reiserfs_read_node (struct super_block *sb,
+ int block,
+ int * was_read)
+{
+ struct buffer_head *bh;
+
+ bh = getblk(sb->s_dev, block, sb->s_blocksize);
+ if (buffer_uptodate(bh)) {
+ *was_read = 0;
+ return bh;
+ } else {
+ *was_read = 1;
+ ll_rw_block(READ, 1, &bh);
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
+ return bh;
+ }
+
+ brelse(bh);
+ return NULL;
+}
+
/**************************************************************************
* Algorithm SearchByKey *
* look for item in the Disk S+Tree by its key *
@@ -680,15 +714,14 @@
stop at leaf level - set to
DISK_LEAF_NODE_LEVEL */
) {
- kdev_t n_dev = p_s_sb->s_dev;
- int n_block_number = SB_ROOT_BLOCK (p_s_sb),
- expected_level = SB_TREE_HEIGHT (p_s_sb),
- n_block_size = p_s_sb->s_blocksize;
+ int n_block_number = SB_ROOT_BLOCK (p_s_sb);
+ int expected_level = SB_TREE_HEIGHT (p_s_sb);
struct buffer_head * p_s_bh;
struct path_element * p_s_last_element;
int n_node_level, n_retval;
int right_neighbor_of_leaf_node;
int fs_gen;
+ int was_read;
#ifdef CONFIG_REISERFS_CHECK
int n_repeat_counter = 0;
@@ -727,8 +760,10 @@
/* Read the next tree node, and set the last element in the path to
have a pointer to it. */
- if ( ! (p_s_bh = p_s_last_element->pe_buffer =
- reiserfs_bread(n_dev, n_block_number, n_block_size)) ) {
+ p_s_bh = p_s_last_element->pe_buffer =
+ reiserfs_read_node(p_s_sb, n_block_number, &was_read);
+
+ if (!p_s_bh) {
p_s_search_path->path_length --;
pathrelse(p_s_search_path);
return IO_ERROR;
@@ -764,7 +799,11 @@
// make sure, that the node contents look like a node of
// certain level
- if (!is_tree_node (p_s_bh, expected_level)) {
+ if (
+#ifndef CONFIG_REISERFS_CHECK
+ was_read &&
+#endif
+ reiserfs_check_node (p_s_bh, expected_level)) {
reiserfs_warning ("vs-5150: search_by_key: "
"invalid format found in block %d. Fsck?\n", p_s_bh->b_blocknr);
pathrelse (p_s_search_path);
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h Fri Apr 20 11:43:58 2001
+++ b/include/linux/reiserfs_fs.h Fri Apr 20 11:43:58 2001
@@ -1398,7 +1398,7 @@
void (*decrement_key) (struct cpu_key *);
int (*is_left_mergeable) (struct key * ih, unsigned long bsize);
void (*print_item) (struct item_head *, char * item);
- void (*check_item) (struct item_head *, char * item);
+ int (*check_item) (struct item_head *, char * item);