diff options
| author | Chris Mason <mason@suse.com> | 2002-05-20 21:43:46 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-05-20 21:43:46 -0700 |
| commit | ea882f08613a6efa9929b3d6a7e7bfcbec22cf92 (patch) | |
| tree | 1032ea42e66e8fa019aab3549e84cf896ce0e3f8 | |
| parent | 70e08a38b2ded7518678bb1f2a89862b0fa5cc1f (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.c | 20 | ||||
| -rw-r--r-- | fs/reiserfs/item_ops.c | 7 | ||||
| -rw-r--r-- | include/linux/reiserfs_fs.h | 7 |
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 */ |
