summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Mason <mason@suse.com>2002-05-20 21:43:46 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-05-20 21:43:46 -0700
commitea882f08613a6efa9929b3d6a7e7bfcbec22cf92 (patch)
tree1032ea42e66e8fa019aab3549e84cf896ce0e3f8
parent70e08a38b2ded7518678bb1f2a89862b0fa5cc1f (diff)
[PATCH] reiserfs 64 bit bug in get_virtual_node_size
This patch fixes a problem with reiserfs on 64 bit machines. Our struct virtual_item is a different size there, and some calculations that assume otherwise lead to this panic create_virtual_node: vs-8030: create_virtual_node: virtual node space consumed
-rw-r--r--fs/reiserfs/fix_node.c20
-rw-r--r--fs/reiserfs/item_ops.c7
-rw-r--r--include/linux/reiserfs_fs.h7
3 files changed, 19 insertions, 15 deletions
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 802eefb3825d..86ac5cb83dd1 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -2011,16 +2011,20 @@ void reiserfs_kfree (const void * vp, size_t size, struct super_block * s)
static int get_virtual_node_size (struct super_block * sb, struct buffer_head * bh)
{
- // int size = sizeof (struct virtual_item); /* for new item in case of insert */
- // int i, nr_items;
- // struct item_head * ih;
+ int max_num_of_items;
+ int max_num_of_entries;
+ unsigned long blocksize = sb->s_blocksize;
- // this is enough for _ALL_ currently possible cases. In 4 k block
- // one may put < 170 empty items. Each virtual item eats 12
- // byte. The biggest direntry item may have < 256 entries. Each
- // entry would eat 2 byte of virtual node space
- return sb->s_blocksize;
+#define MIN_NAME_LEN 1
+ max_num_of_items = (blocksize - BLKH_SIZE) / (IH_SIZE + MIN_ITEM_LEN);
+ max_num_of_entries = (blocksize - BLKH_SIZE - IH_SIZE) /
+ (DEH_SIZE + MIN_NAME_LEN);
+
+ return sizeof(struct virtual_node) +
+ max(max_num_of_items * sizeof (struct virtual_item),
+ sizeof (struct virtual_item) + sizeof(struct direntry_uarea) +
+ (max_num_of_entries - 1) * sizeof (__u16));
}
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
index 7cf647e6f9b1..ac5c94b1500e 100644
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -466,13 +466,6 @@ static void direntry_check_item (struct item_head * ih, char * item)
#define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
-struct direntry_uarea {
- int flags;
- __u16 entry_count;
- __u16 entry_sizes[1];
-} __attribute__ ((__packed__)) ;
-
-
/*
* function returns old entry number in directory item in real node
* using new entry number in virtual item in virtual node */
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 173279f6ff0a..abe55b91a328 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -1342,6 +1342,13 @@ struct virtual_node
struct virtual_item * vn_vi; /* array of items (including a new one, excluding item to be deleted) */
};
+/* used by directory items when creating virtual nodes */
+struct direntry_uarea {
+ int flags;
+ __u16 entry_count;
+ __u16 entry_sizes[1];
+} __attribute__ ((__packed__)) ;
+
/***************************************************************************/
/* TREE BALANCE */