diff -Nru linux/fs/reiserfs/fix_node.c linux.old/fs/reiserfs/fix_node.c
--- linux/fs/reiserfs/fix_node.c	Fri Apr 20 11:43:58 2001
+++ linux.old/fs/reiserfs/fix_node.c	Fri Apr 20 11:43:58 2001
@@ -2087,6 +2087,7 @@
     unsigned long		n_son_number;
     struct super_block  *	p_s_sb = p_s_tb->tb_sb;
     struct buffer_head  * p_s_bh;
+    int was_read;
 
 
     if ( p_s_tb->lnum[n_h] ) {
@@ -2100,7 +2101,7 @@
 
 	n_child_position = ( p_s_bh == p_s_tb->FL[n_h] ) ? p_s_tb->lkey[n_h] : B_NR_ITEMS (p_s_tb->FL[n_h]);
 	n_son_number = B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position);
-	p_s_bh = reiserfs_bread(p_s_sb->s_dev, n_son_number, p_s_sb->s_blocksize);
+	p_s_bh = reiserfs_read_node (p_s_sb, n_son_number, &was_read);
 	if (!p_s_bh)
 	    return IO_ERROR;
 	if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
@@ -2108,6 +2109,15 @@
 	    return REPEAT_SEARCH;
 	}
 	
+	if (
+#ifndef CONFIG_REISERFS_CHECK
+	was_read &&
+#endif
+	reiserfs_check_node(p_s_bh, n_h + 1)) {
+	    brelse (p_s_bh);
+	    return IO_ERROR;
+	}
+
 #ifdef CONFIG_REISERFS_CHECK
 	if ( ! B_IS_IN_TREE(p_s_tb->FL[n_h]) || n_child_position > B_NR_ITEMS(p_s_tb->FL[n_h]) ||
 	     B_N_CHILD_NUM(p_s_tb->FL[n_h], n_child_position) != p_s_bh->b_blocknr )
@@ -2134,13 +2144,23 @@
 
 	n_child_position = ( p_s_bh == p_s_tb->FR[n_h] ) ? p_s_tb->rkey[n_h] + 1 : 0;
 	n_son_number = B_N_CHILD_NUM(p_s_tb->FR[n_h], n_child_position);
-	p_s_bh = reiserfs_bread(p_s_sb->s_dev, n_son_number, p_s_sb->s_blocksize);
+	p_s_bh = reiserfs_read_node(p_s_sb, n_son_number, &was_read);
 	if (!p_s_bh)
 	    return IO_ERROR;
 	if ( FILESYSTEM_CHANGED_TB (p_s_tb) ) {
 	    decrement_bcount(p_s_bh);
 	    return REPEAT_SEARCH;
 	}
+
+	if (
+#ifndef CONFIG_REISERFS_CHECK
+	was_read &&
+#endif
+	reiserfs_check_node(p_s_bh, n_h + 1)) {
+	    brelse (p_s_bh);
+	    return IO_ERROR;
+	}
+
 	decrement_bcount(p_s_tb->R[n_h]);
 	p_s_tb->R[n_h] = p_s_bh;
 
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 @@
     }
 }
 
-static void sd_check_item (struct item_head * ih, char * item)
+static int sd_check_item (struct item_head * ih, char * item)
 {
-    // FIXME: type something here!
+    if (ih_version(ih) == ITEM_VERSION_1) {
+	return (ih_item_len(ih) == SD_V1_SIZE);
+    }
+    return (ih_item_len(ih) == SD_SIZE);
 }
 
 
@@ -178,9 +183,9 @@
 }
 
 
-static void direct_check_item (struct item_head * ih, char * item)
+static int direct_check_item (struct item_head * ih, char * item)
 {
-    // FIXME: type something here!
+    return check_key_version(ih, &(ih)->ih_key);
 }
 
 
@@ -329,9 +334,9 @@
     printk ("]\n");
 }
 
-static void indirect_check_item (struct item_head * ih, char * item)
+static int indirect_check_item (struct item_head * ih, char * item)
 {
-    // FIXME: type something here!
+    return check_key_version(ih, &(ih)->ih_key);
 }
 
 
@@ -464,7 +469,7 @@
 }
 
 
-static void direntry_check_item (struct item_head * ih, char * item)
+static int direntry_check_item (struct item_head * ih, char * item)
 {
     int i;
     struct reiserfs_de_head * deh;
@@ -474,6 +479,13 @@
     for (i = 0; i < I_ENTRY_COUNT (ih); i ++, deh ++) {
 	;
     }
+    if (ih_version(ih) != ITEM_VERSION_1 ||
+	le_key_version(&ih->ih_key)) {
+	reiserfs_warning ("direntry_check_item: item or item key version "
+			  "is not suitable here.\n");
+	return 0;
+    }
+    return 1;
 }
 
 
diff -Nru linux/fs/reiserfs/stree.c linux.old/fs/reiserfs/stree.c
--- linux/fs/reiserfs/stree.c	Fri Apr 20 11:43:58 2001
+++ linux.old/fs/reiserfs/stree.c	Fri Apr 20 11:43:58 2001
@@ -568,6 +568,12 @@
 	    reiserfs_warning ("is_leaf: item location seems wrong (second one): %h\n", ih);
 	    return 0;
 	}
+
+	if (!op_check_item(ih, B_I_PITEM(bh,ih))) {
+	    reiserfs_warning ("is_leaf: item (%h) has not passed internal check\n", ih);
+	    return 0;
+	}
+
 	prev_location = ih_location (ih);
     }
 
@@ -608,20 +614,26 @@
     return 1;
 }
 
-
-// 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);
 
-    return is_internal (bh->b_data, bh->b_size, bh);
+ error:	
+    mark_buffer_uptodate(bh, 0);
+    reiserfs_warning("zam-5100: " __FUNCTION__ ": "
+		     "reiserfs format violation in block %lu\n", bh->b_blocknr);
+    return IO_ERROR;
 }
 
 
@@ -646,6 +658,28 @@
 
 #endif
 
+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);
 
     int (*create_vi) (struct virtual_node * vn, struct virtual_item * vi, 
 		      int is_affected, int insert_size);
@@ -1714,6 +1714,8 @@
 int comp_items (struct item_head  * p_s_ih, struct path * p_s_path);
 struct key * get_rkey (struct path * p_s_chk_path, struct super_block  * p_s_sb);
 inline int bin_search (void * p_v_key, void * p_v_base, int p_n_num, int p_n_width, int * p_n_pos);
+struct buffer_head * reiserfs_read_node (struct super_block*, int, int*);
+int reiserfs_check_node (struct buffer_head*, int);
 int search_by_key (struct super_block *, struct cpu_key *, struct path *, int);
 #define search_item(s,key,path) search_by_key (s, key, path, DISK_LEAF_NODE_LEVEL)
 int search_for_position_by_key (struct super_block * p_s_sb, struct cpu_key * p_s_cpu_key, struct path * p_s_search_path);

