2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
5 #include <linux/time.h>
9 * this contains item handlers for old item types: sd, direct,
14 * and where are the comments? how about saying where we can find an
15 * explanation of each item handler method? -Hans
18 /* stat data functions */
19 static int sd_bytes_number(struct item_head
*ih
, int block_size
)
24 static void sd_decrement_key(struct cpu_key
*key
)
26 key
->on_disk_key
.k_objectid
--;
27 set_cpu_key_k_type(key
, TYPE_ANY
);
28 set_cpu_key_k_offset(key
, (loff_t
)(~0ULL >> 1));
31 static int sd_is_left_mergeable(struct reiserfs_key
*key
, unsigned long bsize
)
36 static char *print_time(time_t t
)
38 static char timebuf
[256];
40 sprintf(timebuf
, "%ld", t
);
44 static void sd_print_item(struct item_head
*ih
, char *item
)
46 printk("\tmode | size | nlinks | first direct | mtime\n");
47 if (stat_data_v1(ih
)) {
48 struct stat_data_v1
*sd
= (struct stat_data_v1
*)item
;
50 printk("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd
),
51 sd_v1_size(sd
), sd_v1_nlink(sd
),
52 sd_v1_first_direct_byte(sd
),
53 print_time(sd_v1_mtime(sd
)));
55 struct stat_data
*sd
= (struct stat_data
*)item
;
57 printk("\t0%-6o | %6llu | %2u | %d | %s\n", sd_v2_mode(sd
),
58 (unsigned long long)sd_v2_size(sd
), sd_v2_nlink(sd
),
59 sd_v2_rdev(sd
), print_time(sd_v2_mtime(sd
)));
63 static void sd_check_item(struct item_head
*ih
, char *item
)
68 static int sd_create_vi(struct virtual_node
*vn
,
69 struct virtual_item
*vi
,
70 int is_affected
, int insert_size
)
72 vi
->vi_index
= TYPE_STAT_DATA
;
76 static int sd_check_left(struct virtual_item
*vi
, int free
,
77 int start_skip
, int end_skip
)
79 BUG_ON(start_skip
|| end_skip
);
83 static int sd_check_right(struct virtual_item
*vi
, int free
)
88 static int sd_part_size(struct virtual_item
*vi
, int first
, int count
)
94 static int sd_unit_num(struct virtual_item
*vi
)
96 return vi
->vi_item_len
- IH_SIZE
;
99 static void sd_print_vi(struct virtual_item
*vi
)
101 reiserfs_warning(NULL
, "reiserfs-16100",
102 "STATDATA, index %d, type 0x%x, %h",
103 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
106 static struct item_operations stat_data_ops
= {
107 .bytes_number
= sd_bytes_number
,
108 .decrement_key
= sd_decrement_key
,
109 .is_left_mergeable
= sd_is_left_mergeable
,
110 .print_item
= sd_print_item
,
111 .check_item
= sd_check_item
,
113 .create_vi
= sd_create_vi
,
114 .check_left
= sd_check_left
,
115 .check_right
= sd_check_right
,
116 .part_size
= sd_part_size
,
117 .unit_num
= sd_unit_num
,
118 .print_vi
= sd_print_vi
121 /* direct item functions */
122 static int direct_bytes_number(struct item_head
*ih
, int block_size
)
124 return ih_item_len(ih
);
127 /* FIXME: this should probably switch to indirect as well */
128 static void direct_decrement_key(struct cpu_key
*key
)
130 cpu_key_k_offset_dec(key
);
131 if (cpu_key_k_offset(key
) == 0)
132 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
135 static int direct_is_left_mergeable(struct reiserfs_key
*key
,
138 int version
= le_key_version(key
);
139 return ((le_key_k_offset(version
, key
) & (bsize
- 1)) != 1);
142 static void direct_print_item(struct item_head
*ih
, char *item
)
148 while (j
< ih_item_len(ih
))
149 printk("%c", item
[j
++]);
153 static void direct_check_item(struct item_head
*ih
, char *item
)
158 static int direct_create_vi(struct virtual_node
*vn
,
159 struct virtual_item
*vi
,
160 int is_affected
, int insert_size
)
162 vi
->vi_index
= TYPE_DIRECT
;
166 static int direct_check_left(struct virtual_item
*vi
, int free
,
167 int start_skip
, int end_skip
)
171 bytes
= free
- free
% 8;
175 static int direct_check_right(struct virtual_item
*vi
, int free
)
177 return direct_check_left(vi
, free
, 0, 0);
180 static int direct_part_size(struct virtual_item
*vi
, int first
, int count
)
185 static int direct_unit_num(struct virtual_item
*vi
)
187 return vi
->vi_item_len
- IH_SIZE
;
190 static void direct_print_vi(struct virtual_item
*vi
)
192 reiserfs_warning(NULL
, "reiserfs-16101",
193 "DIRECT, index %d, type 0x%x, %h",
194 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
197 static struct item_operations direct_ops
= {
198 .bytes_number
= direct_bytes_number
,
199 .decrement_key
= direct_decrement_key
,
200 .is_left_mergeable
= direct_is_left_mergeable
,
201 .print_item
= direct_print_item
,
202 .check_item
= direct_check_item
,
204 .create_vi
= direct_create_vi
,
205 .check_left
= direct_check_left
,
206 .check_right
= direct_check_right
,
207 .part_size
= direct_part_size
,
208 .unit_num
= direct_unit_num
,
209 .print_vi
= direct_print_vi
212 /* indirect item functions */
213 static int indirect_bytes_number(struct item_head
*ih
, int block_size
)
215 return ih_item_len(ih
) / UNFM_P_SIZE
* block_size
;
218 /* decrease offset, if it becomes 0, change type to stat data */
219 static void indirect_decrement_key(struct cpu_key
*key
)
221 cpu_key_k_offset_dec(key
);
222 if (cpu_key_k_offset(key
) == 0)
223 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
226 /* if it is not first item of the body, then it is mergeable */
227 static int indirect_is_left_mergeable(struct reiserfs_key
*key
,
230 int version
= le_key_version(key
);
231 return (le_key_k_offset(version
, key
) != 1);
234 /* printing of indirect item */
235 static void start_new_sequence(__u32
* start
, int *len
, __u32
new)
241 static int sequence_finished(__u32 start
, int *len
, __u32
new)
243 if (start
== INT_MAX
)
246 if (start
== 0 && new == 0) {
250 if (start
!= 0 && (start
+ *len
) == new) {
257 static void print_sequence(__u32 start
, int len
)
259 if (start
== INT_MAX
)
263 printk(" %d", start
);
265 printk(" %d(%d)", start
, len
);
268 static void indirect_print_item(struct item_head
*ih
, char *item
)
272 __u32 prev
= INT_MAX
;
275 unp
= (__le32
*) item
;
277 if (ih_item_len(ih
) % UNFM_P_SIZE
)
278 reiserfs_warning(NULL
, "reiserfs-16102", "invalid item len");
280 printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih
));
281 for (j
= 0; j
< I_UNFM_NUM(ih
); j
++) {
282 if (sequence_finished(prev
, &num
, get_block_num(unp
, j
))) {
283 print_sequence(prev
, num
);
284 start_new_sequence(&prev
, &num
, get_block_num(unp
, j
));
287 print_sequence(prev
, num
);
291 static void indirect_check_item(struct item_head
*ih
, char *item
)
296 static int indirect_create_vi(struct virtual_node
*vn
,
297 struct virtual_item
*vi
,
298 int is_affected
, int insert_size
)
300 vi
->vi_index
= TYPE_INDIRECT
;
304 static int indirect_check_left(struct virtual_item
*vi
, int free
,
305 int start_skip
, int end_skip
)
309 bytes
= free
- free
% UNFM_P_SIZE
;
313 static int indirect_check_right(struct virtual_item
*vi
, int free
)
315 return indirect_check_left(vi
, free
, 0, 0);
319 * return size in bytes of 'units' units. If first == 0 - calculate
320 * from the head (left), otherwise - from tail (right)
322 static int indirect_part_size(struct virtual_item
*vi
, int first
, int units
)
324 /* unit of indirect item is byte (yet) */
328 static int indirect_unit_num(struct virtual_item
*vi
)
330 /* unit of indirect item is byte (yet) */
331 return vi
->vi_item_len
- IH_SIZE
;
334 static void indirect_print_vi(struct virtual_item
*vi
)
336 reiserfs_warning(NULL
, "reiserfs-16103",
337 "INDIRECT, index %d, type 0x%x, %h",
338 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
341 static struct item_operations indirect_ops
= {
342 .bytes_number
= indirect_bytes_number
,
343 .decrement_key
= indirect_decrement_key
,
344 .is_left_mergeable
= indirect_is_left_mergeable
,
345 .print_item
= indirect_print_item
,
346 .check_item
= indirect_check_item
,
348 .create_vi
= indirect_create_vi
,
349 .check_left
= indirect_check_left
,
350 .check_right
= indirect_check_right
,
351 .part_size
= indirect_part_size
,
352 .unit_num
= indirect_unit_num
,
353 .print_vi
= indirect_print_vi
356 /* direntry functions */
357 static int direntry_bytes_number(struct item_head
*ih
, int block_size
)
359 reiserfs_warning(NULL
, "vs-16090",
360 "bytes number is asked for direntry");
364 static void direntry_decrement_key(struct cpu_key
*key
)
366 cpu_key_k_offset_dec(key
);
367 if (cpu_key_k_offset(key
) == 0)
368 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
371 static int direntry_is_left_mergeable(struct reiserfs_key
*key
,
374 if (le32_to_cpu(key
->u
.k_offset_v1
.k_offset
) == DOT_OFFSET
)
380 static void direntry_print_item(struct item_head
*ih
, char *item
)
384 struct reiserfs_de_head
*deh
;
386 static char namebuf
[80];
388 printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",
389 "Key of pointed object", "Hash", "Gen number", "Status");
391 deh
= (struct reiserfs_de_head
*)item
;
393 for (i
= 0; i
< ih_entry_count(ih
); i
++, deh
++) {
395 (i
? (deh_location(deh
- 1)) : ih_item_len(ih
)) -
397 name
= item
+ deh_location(deh
);
398 if (name
[namelen
- 1] == 0)
399 namelen
= strlen(name
);
401 if (namelen
> sizeof(namebuf
) - 3) {
402 strncpy(namebuf
+ 1, name
, sizeof(namebuf
) - 3);
403 namebuf
[sizeof(namebuf
) - 2] = '"';
404 namebuf
[sizeof(namebuf
) - 1] = 0;
406 memcpy(namebuf
+ 1, name
, namelen
);
407 namebuf
[namelen
+ 1] = '"';
408 namebuf
[namelen
+ 2] = 0;
411 printk("%d: %-15s%-15d%-15d%-15lld%-15lld(%s)\n",
413 deh_dir_id(deh
), deh_objectid(deh
),
414 GET_HASH_VALUE(deh_offset(deh
)),
415 GET_GENERATION_NUMBER((deh_offset(deh
))),
416 (de_hidden(deh
)) ? "HIDDEN" : "VISIBLE");
420 static void direntry_check_item(struct item_head
*ih
, char *item
)
423 struct reiserfs_de_head
*deh
;
426 deh
= (struct reiserfs_de_head
*)item
;
427 for (i
= 0; i
< ih_entry_count(ih
); i
++, deh
++) {
432 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
435 * function returns old entry number in directory item in real node
436 * using new entry number in virtual item in virtual node
438 static inline int old_entry_num(int is_affected
, int virtual_entry_num
,
439 int pos_in_item
, int mode
)
441 if (mode
== M_INSERT
|| mode
== M_DELETE
)
442 return virtual_entry_num
;
445 /* cut or paste is applied to another item */
446 return virtual_entry_num
;
448 if (virtual_entry_num
< pos_in_item
)
449 return virtual_entry_num
;
452 return virtual_entry_num
+ 1;
454 RFALSE(mode
!= M_PASTE
|| virtual_entry_num
== 0,
455 "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",
458 return virtual_entry_num
- 1;
462 * Create an array of sizes of directory entries for virtual
463 * item. Return space used by an item. FIXME: no control over
464 * consuming of space used by this item handler
466 static int direntry_create_vi(struct virtual_node
*vn
,
467 struct virtual_item
*vi
,
468 int is_affected
, int insert_size
)
470 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
472 int size
= sizeof(struct direntry_uarea
);
473 struct reiserfs_de_head
*deh
;
475 vi
->vi_index
= TYPE_DIRENTRY
;
477 BUG_ON(!(vi
->vi_ih
) || !vi
->vi_item
);
480 if (le_ih_k_offset(vi
->vi_ih
) == DOT_OFFSET
)
481 dir_u
->flags
|= DIRENTRY_VI_FIRST_DIRENTRY_ITEM
;
483 deh
= (struct reiserfs_de_head
*)(vi
->vi_item
);
485 /* virtual directory item have this amount of entry after */
486 dir_u
->entry_count
= ih_entry_count(vi
->vi_ih
) +
487 ((is_affected
) ? ((vn
->vn_mode
== M_CUT
) ? -1 :
488 (vn
->vn_mode
== M_PASTE
? 1 : 0)) : 0);
490 for (i
= 0; i
< dir_u
->entry_count
; i
++) {
491 j
= old_entry_num(is_affected
, i
, vn
->vn_pos_in_item
,
493 dir_u
->entry_sizes
[i
] =
494 (j
? deh_location(&deh
[j
- 1]) : ih_item_len(vi
->vi_ih
)) -
495 deh_location(&deh
[j
]) + DEH_SIZE
;
498 size
+= (dir_u
->entry_count
* sizeof(short));
500 /* set size of pasted entry */
501 if (is_affected
&& vn
->vn_mode
== M_PASTE
)
502 dir_u
->entry_sizes
[vn
->vn_pos_in_item
] = insert_size
;
504 #ifdef CONFIG_REISERFS_CHECK
505 /* compare total size of entries with item length */
510 for (k
= 0; k
< dir_u
->entry_count
; k
++)
511 l
+= dir_u
->entry_sizes
[k
];
513 if (l
+ IH_SIZE
!= vi
->vi_item_len
+
515 && (vn
->vn_mode
== M_PASTE
516 || vn
->vn_mode
== M_CUT
)) ? insert_size
: 0)) {
517 reiserfs_panic(NULL
, "vs-8025", "(mode==%c, "
518 "insert_size==%d), invalid length of "
520 vn
->vn_mode
, insert_size
);
530 * return number of entries which may fit into specified amount of
531 * free space, or -1 if free space is not enough even for 1 entry
533 static int direntry_check_left(struct virtual_item
*vi
, int free
,
534 int start_skip
, int end_skip
)
538 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
540 for (i
= start_skip
; i
< dir_u
->entry_count
- end_skip
; i
++) {
541 /* i-th entry doesn't fit into the remaining free space */
542 if (dir_u
->entry_sizes
[i
] > free
)
545 free
-= dir_u
->entry_sizes
[i
];
549 if (entries
== dir_u
->entry_count
) {
550 reiserfs_panic(NULL
, "item_ops-1",
551 "free space %d, entry_count %d", free
,
555 /* "." and ".." can not be separated from each other */
556 if (start_skip
== 0 && (dir_u
->flags
& DIRENTRY_VI_FIRST_DIRENTRY_ITEM
)
560 return entries
? : -1;
563 static int direntry_check_right(struct virtual_item
*vi
, int free
)
567 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
569 for (i
= dir_u
->entry_count
- 1; i
>= 0; i
--) {
570 /* i-th entry doesn't fit into the remaining free space */
571 if (dir_u
->entry_sizes
[i
] > free
)
574 free
-= dir_u
->entry_sizes
[i
];
577 BUG_ON(entries
== dir_u
->entry_count
);
579 /* "." and ".." can not be separated from each other */
580 if ((dir_u
->flags
& DIRENTRY_VI_FIRST_DIRENTRY_ITEM
)
581 && entries
> dir_u
->entry_count
- 2)
582 entries
= dir_u
->entry_count
- 2;
584 return entries
? : -1;
587 /* sum of entry sizes between from-th and to-th entries including both edges */
588 static int direntry_part_size(struct virtual_item
*vi
, int first
, int count
)
592 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
598 from
= dir_u
->entry_count
- count
;
599 to
= from
+ count
- 1;
601 for (i
= from
; i
<= to
; i
++)
602 retval
+= dir_u
->entry_sizes
[i
];
607 static int direntry_unit_num(struct virtual_item
*vi
)
609 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
611 return dir_u
->entry_count
;
614 static void direntry_print_vi(struct virtual_item
*vi
)
617 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
619 reiserfs_warning(NULL
, "reiserfs-16104",
620 "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
621 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
, dir_u
->flags
);
622 printk("%d entries: ", dir_u
->entry_count
);
623 for (i
= 0; i
< dir_u
->entry_count
; i
++)
624 printk("%d ", dir_u
->entry_sizes
[i
]);
628 static struct item_operations direntry_ops
= {
629 .bytes_number
= direntry_bytes_number
,
630 .decrement_key
= direntry_decrement_key
,
631 .is_left_mergeable
= direntry_is_left_mergeable
,
632 .print_item
= direntry_print_item
,
633 .check_item
= direntry_check_item
,
635 .create_vi
= direntry_create_vi
,
636 .check_left
= direntry_check_left
,
637 .check_right
= direntry_check_right
,
638 .part_size
= direntry_part_size
,
639 .unit_num
= direntry_unit_num
,
640 .print_vi
= direntry_print_vi
643 /* Error catching functions to catch errors caused by incorrect item types. */
644 static int errcatch_bytes_number(struct item_head
*ih
, int block_size
)
646 reiserfs_warning(NULL
, "green-16001",
647 "Invalid item type observed, run fsck ASAP");
651 static void errcatch_decrement_key(struct cpu_key
*key
)
653 reiserfs_warning(NULL
, "green-16002",
654 "Invalid item type observed, run fsck ASAP");
657 static int errcatch_is_left_mergeable(struct reiserfs_key
*key
,
660 reiserfs_warning(NULL
, "green-16003",
661 "Invalid item type observed, run fsck ASAP");
665 static void errcatch_print_item(struct item_head
*ih
, char *item
)
667 reiserfs_warning(NULL
, "green-16004",
668 "Invalid item type observed, run fsck ASAP");
671 static void errcatch_check_item(struct item_head
*ih
, char *item
)
673 reiserfs_warning(NULL
, "green-16005",
674 "Invalid item type observed, run fsck ASAP");
677 static int errcatch_create_vi(struct virtual_node
*vn
,
678 struct virtual_item
*vi
,
679 int is_affected
, int insert_size
)
681 reiserfs_warning(NULL
, "green-16006",
682 "Invalid item type observed, run fsck ASAP");
684 * We might return -1 here as well, but it won't help as
685 * create_virtual_node() from where this operation is called
686 * from is of return type void.
691 static int errcatch_check_left(struct virtual_item
*vi
, int free
,
692 int start_skip
, int end_skip
)
694 reiserfs_warning(NULL
, "green-16007",
695 "Invalid item type observed, run fsck ASAP");
699 static int errcatch_check_right(struct virtual_item
*vi
, int free
)
701 reiserfs_warning(NULL
, "green-16008",
702 "Invalid item type observed, run fsck ASAP");
706 static int errcatch_part_size(struct virtual_item
*vi
, int first
, int count
)
708 reiserfs_warning(NULL
, "green-16009",
709 "Invalid item type observed, run fsck ASAP");
713 static int errcatch_unit_num(struct virtual_item
*vi
)
715 reiserfs_warning(NULL
, "green-16010",
716 "Invalid item type observed, run fsck ASAP");
720 static void errcatch_print_vi(struct virtual_item
*vi
)
722 reiserfs_warning(NULL
, "green-16011",
723 "Invalid item type observed, run fsck ASAP");
726 static struct item_operations errcatch_ops
= {
727 errcatch_bytes_number
,
728 errcatch_decrement_key
,
729 errcatch_is_left_mergeable
,
735 errcatch_check_right
,
741 #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
742 #error Item types must use disk-format assigned values.
745 struct item_operations
*item_ops
[TYPE_ANY
+ 1] = {
750 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
751 &errcatch_ops
/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */