Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
0003  */
0004 
0005 #include <linux/time.h>
0006 #include "reiserfs.h"
0007 
0008 /*
0009  * this contains item handlers for old item types: sd, direct,
0010  * indirect, directory
0011  */
0012 
0013 /*
0014  * and where are the comments? how about saying where we can find an
0015  * explanation of each item handler method? -Hans
0016  */
0017 
0018 /* stat data functions */
0019 static int sd_bytes_number(struct item_head *ih, int block_size)
0020 {
0021     return 0;
0022 }
0023 
0024 static void sd_decrement_key(struct cpu_key *key)
0025 {
0026     key->on_disk_key.k_objectid--;
0027     set_cpu_key_k_type(key, TYPE_ANY);
0028     set_cpu_key_k_offset(key, (loff_t)(~0ULL >> 1));
0029 }
0030 
0031 static int sd_is_left_mergeable(struct reiserfs_key *key, unsigned long bsize)
0032 {
0033     return 0;
0034 }
0035 
0036 static void sd_print_item(struct item_head *ih, char *item)
0037 {
0038     printk("\tmode | size | nlinks | first direct | mtime\n");
0039     if (stat_data_v1(ih)) {
0040         struct stat_data_v1 *sd = (struct stat_data_v1 *)item;
0041 
0042         printk("\t0%-6o | %6u | %2u | %d | %u\n", sd_v1_mode(sd),
0043                sd_v1_size(sd), sd_v1_nlink(sd),
0044                sd_v1_first_direct_byte(sd),
0045                sd_v1_mtime(sd));
0046     } else {
0047         struct stat_data *sd = (struct stat_data *)item;
0048 
0049         printk("\t0%-6o | %6llu | %2u | %d | %u\n", sd_v2_mode(sd),
0050                (unsigned long long)sd_v2_size(sd), sd_v2_nlink(sd),
0051                sd_v2_rdev(sd), sd_v2_mtime(sd));
0052     }
0053 }
0054 
0055 static void sd_check_item(struct item_head *ih, char *item)
0056 {
0057     /* unused */
0058 }
0059 
0060 static int sd_create_vi(struct virtual_node *vn,
0061             struct virtual_item *vi,
0062             int is_affected, int insert_size)
0063 {
0064     vi->vi_index = TYPE_STAT_DATA;
0065     return 0;
0066 }
0067 
0068 static int sd_check_left(struct virtual_item *vi, int free,
0069              int start_skip, int end_skip)
0070 {
0071     BUG_ON(start_skip || end_skip);
0072     return -1;
0073 }
0074 
0075 static int sd_check_right(struct virtual_item *vi, int free)
0076 {
0077     return -1;
0078 }
0079 
0080 static int sd_part_size(struct virtual_item *vi, int first, int count)
0081 {
0082     BUG_ON(count);
0083     return 0;
0084 }
0085 
0086 static int sd_unit_num(struct virtual_item *vi)
0087 {
0088     return vi->vi_item_len - IH_SIZE;
0089 }
0090 
0091 static void sd_print_vi(struct virtual_item *vi)
0092 {
0093     reiserfs_warning(NULL, "reiserfs-16100",
0094              "STATDATA, index %d, type 0x%x, %h",
0095              vi->vi_index, vi->vi_type, vi->vi_ih);
0096 }
0097 
0098 static struct item_operations stat_data_ops = {
0099     .bytes_number = sd_bytes_number,
0100     .decrement_key = sd_decrement_key,
0101     .is_left_mergeable = sd_is_left_mergeable,
0102     .print_item = sd_print_item,
0103     .check_item = sd_check_item,
0104 
0105     .create_vi = sd_create_vi,
0106     .check_left = sd_check_left,
0107     .check_right = sd_check_right,
0108     .part_size = sd_part_size,
0109     .unit_num = sd_unit_num,
0110     .print_vi = sd_print_vi
0111 };
0112 
0113 /* direct item functions */
0114 static int direct_bytes_number(struct item_head *ih, int block_size)
0115 {
0116     return ih_item_len(ih);
0117 }
0118 
0119 /* FIXME: this should probably switch to indirect as well */
0120 static void direct_decrement_key(struct cpu_key *key)
0121 {
0122     cpu_key_k_offset_dec(key);
0123     if (cpu_key_k_offset(key) == 0)
0124         set_cpu_key_k_type(key, TYPE_STAT_DATA);
0125 }
0126 
0127 static int direct_is_left_mergeable(struct reiserfs_key *key,
0128                     unsigned long bsize)
0129 {
0130     int version = le_key_version(key);
0131     return ((le_key_k_offset(version, key) & (bsize - 1)) != 1);
0132 }
0133 
0134 static void direct_print_item(struct item_head *ih, char *item)
0135 {
0136     int j = 0;
0137 
0138 /*    return; */
0139     printk("\"");
0140     while (j < ih_item_len(ih))
0141         printk("%c", item[j++]);
0142     printk("\"\n");
0143 }
0144 
0145 static void direct_check_item(struct item_head *ih, char *item)
0146 {
0147     /* unused */
0148 }
0149 
0150 static int direct_create_vi(struct virtual_node *vn,
0151                 struct virtual_item *vi,
0152                 int is_affected, int insert_size)
0153 {
0154     vi->vi_index = TYPE_DIRECT;
0155     return 0;
0156 }
0157 
0158 static int direct_check_left(struct virtual_item *vi, int free,
0159                  int start_skip, int end_skip)
0160 {
0161     int bytes;
0162 
0163     bytes = free - free % 8;
0164     return bytes ? : -1;
0165 }
0166 
0167 static int direct_check_right(struct virtual_item *vi, int free)
0168 {
0169     return direct_check_left(vi, free, 0, 0);
0170 }
0171 
0172 static int direct_part_size(struct virtual_item *vi, int first, int count)
0173 {
0174     return count;
0175 }
0176 
0177 static int direct_unit_num(struct virtual_item *vi)
0178 {
0179     return vi->vi_item_len - IH_SIZE;
0180 }
0181 
0182 static void direct_print_vi(struct virtual_item *vi)
0183 {
0184     reiserfs_warning(NULL, "reiserfs-16101",
0185              "DIRECT, index %d, type 0x%x, %h",
0186              vi->vi_index, vi->vi_type, vi->vi_ih);
0187 }
0188 
0189 static struct item_operations direct_ops = {
0190     .bytes_number = direct_bytes_number,
0191     .decrement_key = direct_decrement_key,
0192     .is_left_mergeable = direct_is_left_mergeable,
0193     .print_item = direct_print_item,
0194     .check_item = direct_check_item,
0195 
0196     .create_vi = direct_create_vi,
0197     .check_left = direct_check_left,
0198     .check_right = direct_check_right,
0199     .part_size = direct_part_size,
0200     .unit_num = direct_unit_num,
0201     .print_vi = direct_print_vi
0202 };
0203 
0204 /* indirect item functions */
0205 static int indirect_bytes_number(struct item_head *ih, int block_size)
0206 {
0207     return ih_item_len(ih) / UNFM_P_SIZE * block_size;
0208 }
0209 
0210 /* decrease offset, if it becomes 0, change type to stat data */
0211 static void indirect_decrement_key(struct cpu_key *key)
0212 {
0213     cpu_key_k_offset_dec(key);
0214     if (cpu_key_k_offset(key) == 0)
0215         set_cpu_key_k_type(key, TYPE_STAT_DATA);
0216 }
0217 
0218 /* if it is not first item of the body, then it is mergeable */
0219 static int indirect_is_left_mergeable(struct reiserfs_key *key,
0220                       unsigned long bsize)
0221 {
0222     int version = le_key_version(key);
0223     return (le_key_k_offset(version, key) != 1);
0224 }
0225 
0226 /* printing of indirect item */
0227 static void start_new_sequence(__u32 * start, int *len, __u32 new)
0228 {
0229     *start = new;
0230     *len = 1;
0231 }
0232 
0233 static int sequence_finished(__u32 start, int *len, __u32 new)
0234 {
0235     if (start == INT_MAX)
0236         return 1;
0237 
0238     if (start == 0 && new == 0) {
0239         (*len)++;
0240         return 0;
0241     }
0242     if (start != 0 && (start + *len) == new) {
0243         (*len)++;
0244         return 0;
0245     }
0246     return 1;
0247 }
0248 
0249 static void print_sequence(__u32 start, int len)
0250 {
0251     if (start == INT_MAX)
0252         return;
0253 
0254     if (len == 1)
0255         printk(" %d", start);
0256     else
0257         printk(" %d(%d)", start, len);
0258 }
0259 
0260 static void indirect_print_item(struct item_head *ih, char *item)
0261 {
0262     int j;
0263     __le32 *unp;
0264     __u32 prev = INT_MAX;
0265     int num = 0;
0266 
0267     unp = (__le32 *) item;
0268 
0269     if (ih_item_len(ih) % UNFM_P_SIZE)
0270         reiserfs_warning(NULL, "reiserfs-16102", "invalid item len");
0271 
0272     printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih));
0273     for (j = 0; j < I_UNFM_NUM(ih); j++) {
0274         if (sequence_finished(prev, &num, get_block_num(unp, j))) {
0275             print_sequence(prev, num);
0276             start_new_sequence(&prev, &num, get_block_num(unp, j));
0277         }
0278     }
0279     print_sequence(prev, num);
0280     printk("]\n");
0281 }
0282 
0283 static void indirect_check_item(struct item_head *ih, char *item)
0284 {
0285     /* unused */
0286 }
0287 
0288 static int indirect_create_vi(struct virtual_node *vn,
0289                   struct virtual_item *vi,
0290                   int is_affected, int insert_size)
0291 {
0292     vi->vi_index = TYPE_INDIRECT;
0293     return 0;
0294 }
0295 
0296 static int indirect_check_left(struct virtual_item *vi, int free,
0297                    int start_skip, int end_skip)
0298 {
0299     int bytes;
0300 
0301     bytes = free - free % UNFM_P_SIZE;
0302     return bytes ? : -1;
0303 }
0304 
0305 static int indirect_check_right(struct virtual_item *vi, int free)
0306 {
0307     return indirect_check_left(vi, free, 0, 0);
0308 }
0309 
0310 /*
0311  * return size in bytes of 'units' units. If first == 0 - calculate
0312  * from the head (left), otherwise - from tail (right)
0313  */
0314 static int indirect_part_size(struct virtual_item *vi, int first, int units)
0315 {
0316     /* unit of indirect item is byte (yet) */
0317     return units;
0318 }
0319 
0320 static int indirect_unit_num(struct virtual_item *vi)
0321 {
0322     /* unit of indirect item is byte (yet) */
0323     return vi->vi_item_len - IH_SIZE;
0324 }
0325 
0326 static void indirect_print_vi(struct virtual_item *vi)
0327 {
0328     reiserfs_warning(NULL, "reiserfs-16103",
0329              "INDIRECT, index %d, type 0x%x, %h",
0330              vi->vi_index, vi->vi_type, vi->vi_ih);
0331 }
0332 
0333 static struct item_operations indirect_ops = {
0334     .bytes_number = indirect_bytes_number,
0335     .decrement_key = indirect_decrement_key,
0336     .is_left_mergeable = indirect_is_left_mergeable,
0337     .print_item = indirect_print_item,
0338     .check_item = indirect_check_item,
0339 
0340     .create_vi = indirect_create_vi,
0341     .check_left = indirect_check_left,
0342     .check_right = indirect_check_right,
0343     .part_size = indirect_part_size,
0344     .unit_num = indirect_unit_num,
0345     .print_vi = indirect_print_vi
0346 };
0347 
0348 /* direntry functions */
0349 static int direntry_bytes_number(struct item_head *ih, int block_size)
0350 {
0351     reiserfs_warning(NULL, "vs-16090",
0352              "bytes number is asked for direntry");
0353     return 0;
0354 }
0355 
0356 static void direntry_decrement_key(struct cpu_key *key)
0357 {
0358     cpu_key_k_offset_dec(key);
0359     if (cpu_key_k_offset(key) == 0)
0360         set_cpu_key_k_type(key, TYPE_STAT_DATA);
0361 }
0362 
0363 static int direntry_is_left_mergeable(struct reiserfs_key *key,
0364                       unsigned long bsize)
0365 {
0366     if (le32_to_cpu(key->u.k_offset_v1.k_offset) == DOT_OFFSET)
0367         return 0;
0368     return 1;
0369 
0370 }
0371 
0372 static void direntry_print_item(struct item_head *ih, char *item)
0373 {
0374     int i;
0375     int namelen;
0376     struct reiserfs_de_head *deh;
0377     char *name;
0378     static char namebuf[80];
0379 
0380     printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",
0381            "Key of pointed object", "Hash", "Gen number", "Status");
0382 
0383     deh = (struct reiserfs_de_head *)item;
0384 
0385     for (i = 0; i < ih_entry_count(ih); i++, deh++) {
0386         namelen =
0387             (i ? (deh_location(deh - 1)) : ih_item_len(ih)) -
0388             deh_location(deh);
0389         name = item + deh_location(deh);
0390         if (name[namelen - 1] == 0)
0391             namelen = strlen(name);
0392         namebuf[0] = '"';
0393         if (namelen > sizeof(namebuf) - 3) {
0394             strncpy(namebuf + 1, name, sizeof(namebuf) - 3);
0395             namebuf[sizeof(namebuf) - 2] = '"';
0396             namebuf[sizeof(namebuf) - 1] = 0;
0397         } else {
0398             memcpy(namebuf + 1, name, namelen);
0399             namebuf[namelen + 1] = '"';
0400             namebuf[namelen + 2] = 0;
0401         }
0402 
0403         printk("%d:  %-15s%-15d%-15d%-15lld%-15lld(%s)\n",
0404                i, namebuf,
0405                deh_dir_id(deh), deh_objectid(deh),
0406                GET_HASH_VALUE(deh_offset(deh)),
0407                GET_GENERATION_NUMBER((deh_offset(deh))),
0408                (de_hidden(deh)) ? "HIDDEN" : "VISIBLE");
0409     }
0410 }
0411 
0412 static void direntry_check_item(struct item_head *ih, char *item)
0413 {
0414     int i;
0415     struct reiserfs_de_head *deh;
0416 
0417     /* unused */
0418     deh = (struct reiserfs_de_head *)item;
0419     for (i = 0; i < ih_entry_count(ih); i++, deh++) {
0420         ;
0421     }
0422 }
0423 
0424 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
0425 
0426 /*
0427  * function returns old entry number in directory item in real node
0428  * using new entry number in virtual item in virtual node
0429  */
0430 static inline int old_entry_num(int is_affected, int virtual_entry_num,
0431                 int pos_in_item, int mode)
0432 {
0433     if (mode == M_INSERT || mode == M_DELETE)
0434         return virtual_entry_num;
0435 
0436     if (!is_affected)
0437         /* cut or paste is applied to another item */
0438         return virtual_entry_num;
0439 
0440     if (virtual_entry_num < pos_in_item)
0441         return virtual_entry_num;
0442 
0443     if (mode == M_CUT)
0444         return virtual_entry_num + 1;
0445 
0446     RFALSE(mode != M_PASTE || virtual_entry_num == 0,
0447            "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",
0448            mode);
0449 
0450     return virtual_entry_num - 1;
0451 }
0452 
0453 /*
0454  * Create an array of sizes of directory entries for virtual
0455  * item. Return space used by an item. FIXME: no control over
0456  * consuming of space used by this item handler
0457  */
0458 static int direntry_create_vi(struct virtual_node *vn,
0459                   struct virtual_item *vi,
0460                   int is_affected, int insert_size)
0461 {
0462     struct direntry_uarea *dir_u = vi->vi_uarea;
0463     int i, j;
0464     int size = sizeof(struct direntry_uarea);
0465     struct reiserfs_de_head *deh;
0466 
0467     vi->vi_index = TYPE_DIRENTRY;
0468 
0469     BUG_ON(!(vi->vi_ih) || !vi->vi_item);
0470 
0471     dir_u->flags = 0;
0472     if (le_ih_k_offset(vi->vi_ih) == DOT_OFFSET)
0473         dir_u->flags |= DIRENTRY_VI_FIRST_DIRENTRY_ITEM;
0474 
0475     deh = (struct reiserfs_de_head *)(vi->vi_item);
0476 
0477     /* virtual directory item have this amount of entry after */
0478     dir_u->entry_count = ih_entry_count(vi->vi_ih) +
0479         ((is_affected) ? ((vn->vn_mode == M_CUT) ? -1 :
0480                   (vn->vn_mode == M_PASTE ? 1 : 0)) : 0);
0481 
0482     for (i = 0; i < dir_u->entry_count; i++) {
0483         j = old_entry_num(is_affected, i, vn->vn_pos_in_item,
0484                   vn->vn_mode);
0485         dir_u->entry_sizes[i] =
0486             (j ? deh_location(&deh[j - 1]) : ih_item_len(vi->vi_ih)) -
0487             deh_location(&deh[j]) + DEH_SIZE;
0488     }
0489 
0490     size += (dir_u->entry_count * sizeof(short));
0491 
0492     /* set size of pasted entry */
0493     if (is_affected && vn->vn_mode == M_PASTE)
0494         dir_u->entry_sizes[vn->vn_pos_in_item] = insert_size;
0495 
0496 #ifdef CONFIG_REISERFS_CHECK
0497     /* compare total size of entries with item length */
0498     {
0499         int k, l;
0500 
0501         l = 0;
0502         for (k = 0; k < dir_u->entry_count; k++)
0503             l += dir_u->entry_sizes[k];
0504 
0505         if (l + IH_SIZE != vi->vi_item_len +
0506             ((is_affected
0507               && (vn->vn_mode == M_PASTE
0508               || vn->vn_mode == M_CUT)) ? insert_size : 0)) {
0509             reiserfs_panic(NULL, "vs-8025", "(mode==%c, "
0510                        "insert_size==%d), invalid length of "
0511                        "directory item",
0512                        vn->vn_mode, insert_size);
0513         }
0514     }
0515 #endif
0516 
0517     return size;
0518 
0519 }
0520 
0521 /*
0522  * return number of entries which may fit into specified amount of
0523  * free space, or -1 if free space is not enough even for 1 entry
0524  */
0525 static int direntry_check_left(struct virtual_item *vi, int free,
0526                    int start_skip, int end_skip)
0527 {
0528     int i;
0529     int entries = 0;
0530     struct direntry_uarea *dir_u = vi->vi_uarea;
0531 
0532     for (i = start_skip; i < dir_u->entry_count - end_skip; i++) {
0533         /* i-th entry doesn't fit into the remaining free space */
0534         if (dir_u->entry_sizes[i] > free)
0535             break;
0536 
0537         free -= dir_u->entry_sizes[i];
0538         entries++;
0539     }
0540 
0541     if (entries == dir_u->entry_count) {
0542         reiserfs_panic(NULL, "item_ops-1",
0543                    "free space %d, entry_count %d", free,
0544                    dir_u->entry_count);
0545     }
0546 
0547     /* "." and ".." can not be separated from each other */
0548     if (start_skip == 0 && (dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
0549         && entries < 2)
0550         entries = 0;
0551 
0552     return entries ? : -1;
0553 }
0554 
0555 static int direntry_check_right(struct virtual_item *vi, int free)
0556 {
0557     int i;
0558     int entries = 0;
0559     struct direntry_uarea *dir_u = vi->vi_uarea;
0560 
0561     for (i = dir_u->entry_count - 1; i >= 0; i--) {
0562         /* i-th entry doesn't fit into the remaining free space */
0563         if (dir_u->entry_sizes[i] > free)
0564             break;
0565 
0566         free -= dir_u->entry_sizes[i];
0567         entries++;
0568     }
0569     BUG_ON(entries == dir_u->entry_count);
0570 
0571     /* "." and ".." can not be separated from each other */
0572     if ((dir_u->flags & DIRENTRY_VI_FIRST_DIRENTRY_ITEM)
0573         && entries > dir_u->entry_count - 2)
0574         entries = dir_u->entry_count - 2;
0575 
0576     return entries ? : -1;
0577 }
0578 
0579 /* sum of entry sizes between from-th and to-th entries including both edges */
0580 static int direntry_part_size(struct virtual_item *vi, int first, int count)
0581 {
0582     int i, retval;
0583     int from, to;
0584     struct direntry_uarea *dir_u = vi->vi_uarea;
0585 
0586     retval = 0;
0587     if (first == 0)
0588         from = 0;
0589     else
0590         from = dir_u->entry_count - count;
0591     to = from + count - 1;
0592 
0593     for (i = from; i <= to; i++)
0594         retval += dir_u->entry_sizes[i];
0595 
0596     return retval;
0597 }
0598 
0599 static int direntry_unit_num(struct virtual_item *vi)
0600 {
0601     struct direntry_uarea *dir_u = vi->vi_uarea;
0602 
0603     return dir_u->entry_count;
0604 }
0605 
0606 static void direntry_print_vi(struct virtual_item *vi)
0607 {
0608     int i;
0609     struct direntry_uarea *dir_u = vi->vi_uarea;
0610 
0611     reiserfs_warning(NULL, "reiserfs-16104",
0612              "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
0613              vi->vi_index, vi->vi_type, vi->vi_ih, dir_u->flags);
0614     printk("%d entries: ", dir_u->entry_count);
0615     for (i = 0; i < dir_u->entry_count; i++)
0616         printk("%d ", dir_u->entry_sizes[i]);
0617     printk("\n");
0618 }
0619 
0620 static struct item_operations direntry_ops = {
0621     .bytes_number = direntry_bytes_number,
0622     .decrement_key = direntry_decrement_key,
0623     .is_left_mergeable = direntry_is_left_mergeable,
0624     .print_item = direntry_print_item,
0625     .check_item = direntry_check_item,
0626 
0627     .create_vi = direntry_create_vi,
0628     .check_left = direntry_check_left,
0629     .check_right = direntry_check_right,
0630     .part_size = direntry_part_size,
0631     .unit_num = direntry_unit_num,
0632     .print_vi = direntry_print_vi
0633 };
0634 
0635 /* Error catching functions to catch errors caused by incorrect item types. */
0636 static int errcatch_bytes_number(struct item_head *ih, int block_size)
0637 {
0638     reiserfs_warning(NULL, "green-16001",
0639              "Invalid item type observed, run fsck ASAP");
0640     return 0;
0641 }
0642 
0643 static void errcatch_decrement_key(struct cpu_key *key)
0644 {
0645     reiserfs_warning(NULL, "green-16002",
0646              "Invalid item type observed, run fsck ASAP");
0647 }
0648 
0649 static int errcatch_is_left_mergeable(struct reiserfs_key *key,
0650                       unsigned long bsize)
0651 {
0652     reiserfs_warning(NULL, "green-16003",
0653              "Invalid item type observed, run fsck ASAP");
0654     return 0;
0655 }
0656 
0657 static void errcatch_print_item(struct item_head *ih, char *item)
0658 {
0659     reiserfs_warning(NULL, "green-16004",
0660              "Invalid item type observed, run fsck ASAP");
0661 }
0662 
0663 static void errcatch_check_item(struct item_head *ih, char *item)
0664 {
0665     reiserfs_warning(NULL, "green-16005",
0666              "Invalid item type observed, run fsck ASAP");
0667 }
0668 
0669 static int errcatch_create_vi(struct virtual_node *vn,
0670                   struct virtual_item *vi,
0671                   int is_affected, int insert_size)
0672 {
0673     reiserfs_warning(NULL, "green-16006",
0674              "Invalid item type observed, run fsck ASAP");
0675     /*
0676      * We might return -1 here as well, but it won't help as
0677      * create_virtual_node() from where this operation is called
0678      * from is of return type void.
0679      */
0680     return 0;
0681 }
0682 
0683 static int errcatch_check_left(struct virtual_item *vi, int free,
0684                    int start_skip, int end_skip)
0685 {
0686     reiserfs_warning(NULL, "green-16007",
0687              "Invalid item type observed, run fsck ASAP");
0688     return -1;
0689 }
0690 
0691 static int errcatch_check_right(struct virtual_item *vi, int free)
0692 {
0693     reiserfs_warning(NULL, "green-16008",
0694              "Invalid item type observed, run fsck ASAP");
0695     return -1;
0696 }
0697 
0698 static int errcatch_part_size(struct virtual_item *vi, int first, int count)
0699 {
0700     reiserfs_warning(NULL, "green-16009",
0701              "Invalid item type observed, run fsck ASAP");
0702     return 0;
0703 }
0704 
0705 static int errcatch_unit_num(struct virtual_item *vi)
0706 {
0707     reiserfs_warning(NULL, "green-16010",
0708              "Invalid item type observed, run fsck ASAP");
0709     return 0;
0710 }
0711 
0712 static void errcatch_print_vi(struct virtual_item *vi)
0713 {
0714     reiserfs_warning(NULL, "green-16011",
0715              "Invalid item type observed, run fsck ASAP");
0716 }
0717 
0718 static struct item_operations errcatch_ops = {
0719     .bytes_number = errcatch_bytes_number,
0720     .decrement_key = errcatch_decrement_key,
0721     .is_left_mergeable = errcatch_is_left_mergeable,
0722     .print_item = errcatch_print_item,
0723     .check_item = errcatch_check_item,
0724 
0725     .create_vi = errcatch_create_vi,
0726     .check_left = errcatch_check_left,
0727     .check_right = errcatch_check_right,
0728     .part_size = errcatch_part_size,
0729     .unit_num = errcatch_unit_num,
0730     .print_vi = errcatch_print_vi
0731 };
0732 
0733 #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
0734 #error Item types must use disk-format assigned values.
0735 #endif
0736 
0737 struct item_operations *item_ops[TYPE_ANY + 1] = {
0738     &stat_data_ops,
0739     &indirect_ops,
0740     &direct_ops,
0741     &direntry_ops,
0742     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
0743     &errcatch_ops       /* This is to catch errors with invalid type (15th entry for TYPE_ANY) */
0744 };