From e79e5fce3747f534ff67ce39fe067015d8a8d732 Mon Sep 17 00:00:00 2001 From: Hans Reiser Date: Mon, 11 Feb 2002 05:15:39 -0800 Subject: [PATCH] [PATCH] 05-corrupt_items_checks.diff Do not panic when encountered item of unknown type, just print a warning. --- fs/reiserfs/item_ops.c | 97 ++++++++++++++++++++++++++++++++++++- fs/reiserfs/stree.c | 4 ++ include/linux/reiserfs_fs.h | 23 +++++---- 3 files changed, 110 insertions(+), 14 deletions(-) diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c index 9881a2662a69..055c3527c153 100644 --- a/fs/reiserfs/item_ops.c +++ b/fs/reiserfs/item_ops.c @@ -684,6 +684,97 @@ struct item_operations direntry_ops = { }; +////////////////////////////////////////////////////////////////////////////// +// Error catching functions to catch errors caused by incorrect item types. +// +static int errcatch_bytes_number (struct item_head * ih, int block_size) +{ + reiserfs_warning ("green-16001: Invalid item type observed, run fsck ASAP\n"); + return 0; +} + +static void errcatch_decrement_key (struct cpu_key * key) +{ + reiserfs_warning ("green-16002: Invalid item type observed, run fsck ASAP\n"); +} + + +static int errcatch_is_left_mergeable (struct key * key, unsigned long bsize) +{ + reiserfs_warning ("green-16003: Invalid item type observed, run fsck ASAP\n"); + return 0; +} + + +static void errcatch_print_item (struct item_head * ih, char * item) +{ + reiserfs_warning ("green-16004: Invalid item type observed, run fsck ASAP\n"); +} + + +static void errcatch_check_item (struct item_head * ih, char * item) +{ + reiserfs_warning ("green-16005: Invalid item type observed, run fsck ASAP\n"); +} + +static int errcatch_create_vi (struct virtual_node * vn, + struct virtual_item * vi, + int is_affected, + int insert_size) +{ + reiserfs_warning ("green-16006: Invalid item type observed, run fsck ASAP\n"); + return 0; // We might return -1 here as well, but it won't help as create_virtual_node() from where + // this operation is called from is of return type void. +} + +static int errcatch_check_left (struct virtual_item * vi, int free, + int start_skip, int end_skip) +{ + reiserfs_warning ("green-16007: Invalid item type observed, run fsck ASAP\n"); + return -1; +} + + +static int errcatch_check_right (struct virtual_item * vi, int free) +{ + reiserfs_warning ("green-16008: Invalid item type observed, run fsck ASAP\n"); + return -1; +} + +static int errcatch_part_size (struct virtual_item * vi, int first, int count) +{ + reiserfs_warning ("green-16009: Invalid item type observed, run fsck ASAP\n"); + return 0; +} + +static int errcatch_unit_num (struct virtual_item * vi) +{ + reiserfs_warning ("green-16010: Invalid item type observed, run fsck ASAP\n"); + return 0; +} + +static void errcatch_print_vi (struct virtual_item * vi) +{ + reiserfs_warning ("green-16011: Invalid item type observed, run fsck ASAP\n"); +} + +struct item_operations errcatch_ops = { + errcatch_bytes_number, + errcatch_decrement_key, + errcatch_is_left_mergeable, + errcatch_print_item, + errcatch_check_item, + + errcatch_create_vi, + errcatch_check_left, + errcatch_check_right, + errcatch_part_size, + errcatch_unit_num, + errcatch_print_vi +}; + + + ////////////////////////////////////////////////////////////////////////////// // // @@ -691,11 +782,13 @@ struct item_operations direntry_ops = { do not compile #endif -struct item_operations * item_ops [4] = { +struct item_operations * item_ops [TYPE_ANY + 1] = { &stat_data_ops, &indirect_ops, &direct_ops, - &direntry_ops + &direntry_ops, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + &errcatch_ops /* This is to catch errors with invalid type (15th entry for TYPE_ANY) */ }; diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 5ab2d7e57305..43649b028aed 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c @@ -524,6 +524,10 @@ static int is_leaf (char * buf, int blocksize, struct buffer_head * bh) ih = (struct item_head *)(buf + BLKH_SIZE); prev_location = blocksize; for (i = 0; i < nr; i ++, ih ++) { + if ( le_ih_k_type(ih) == TYPE_ANY) { + reiserfs_warning ("is_leaf: wrong item type for item %h\n",ih); + return 0; + } if (ih_location (ih) >= blocksize || ih_location (ih) < IH_SIZE * nr) { reiserfs_warning ("is_leaf: item location seems wrong: %h\n", ih); return 0; diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 02f8cb393d74..11bb3dacf22c 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h @@ -337,7 +337,15 @@ static inline struct reiserfs_inode_info *REISERFS_I(struct inode *inode) #define REISERFS_VALID_FS 1 #define REISERFS_ERROR_FS 2 - +// +// there are 5 item types currently +// +#define TYPE_STAT_DATA 0 +#define TYPE_INDIRECT 1 +#define TYPE_DIRECT 2 +#define TYPE_DIRENTRY 3 +#define TYPE_MAXTYPE 3 +#define TYPE_ANY 15 // FIXME: comment is required /***************************************************************************/ /* KEY & ITEM HEAD */ @@ -373,7 +381,7 @@ static inline __u16 offset_v2_k_type( const struct offset_v2 *v2 ) { offset_v2_esafe_overlay tmp = *(const offset_v2_esafe_overlay *)v2; tmp.linear = le64_to_cpu( tmp.linear ); - return tmp.offset_v2.k_type; + return (tmp.offset_v2.k_type <= TYPE_MAXTYPE)?tmp.offset_v2.k_type:TYPE_ANY; } static inline void set_offset_v2_k_type( struct offset_v2 *v2, int type ) @@ -522,15 +530,6 @@ struct item_head #define get_block_num(p, i) le32_to_cpu(get_unaligned((p) + (i))) #define put_block_num(p, i, v) put_unaligned(cpu_to_le32(v), (p) + (i)) -// -// there are 5 item types currently -// -#define TYPE_STAT_DATA 0 -#define TYPE_INDIRECT 1 -#define TYPE_DIRECT 2 -#define TYPE_DIRENTRY 3 -#define TYPE_ANY 15 // FIXME: comment is required - // // in old version uniqueness field shows key type // @@ -1498,7 +1497,7 @@ struct item_operations { extern struct item_operations stat_data_ops, indirect_ops, direct_ops, direntry_ops; -extern struct item_operations * item_ops [4]; +extern struct item_operations * item_ops [TYPE_ANY + 1]; #define op_bytes_number(ih,bsize) item_ops[le_ih_k_type (ih)]->bytes_number (ih, bsize) #define op_is_left_mergeable(key,bsize) item_ops[le_key_k_type (le_key_version (key), key)]->is_left_mergeable (key, bsize) -- 2.39.5