0001
0002
0003
0004
0005 #include <linux/time.h>
0006 #include "reiserfs.h"
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
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
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
0114 static int direct_bytes_number(struct item_head *ih, int block_size)
0115 {
0116 return ih_item_len(ih);
0117 }
0118
0119
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
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
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
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
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
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
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
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
0312
0313
0314 static int indirect_part_size(struct virtual_item *vi, int first, int units)
0315 {
0316
0317 return units;
0318 }
0319
0320 static int indirect_unit_num(struct virtual_item *vi)
0321 {
0322
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
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
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
0428
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
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
0455
0456
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
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
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
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
0523
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
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
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
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
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
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
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
0677
0678
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
0744 };