2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
5 #include <linux/time.h>
6 #include <linux/reiserfs_fs.h>
8 // this contains item handlers for old item types: sd, direct,
11 /* and where are the comments? how about saying where we can find an
12 explanation of each item handler method? -Hans */
14 //////////////////////////////////////////////////////////////////////////////
15 // stat data functions
17 static int sd_bytes_number(struct item_head
*ih
, int block_size
)
22 static void sd_decrement_key(struct cpu_key
*key
)
24 key
->on_disk_key
.k_objectid
--;
25 set_cpu_key_k_type(key
, TYPE_ANY
);
26 set_cpu_key_k_offset(key
, (loff_t
)(~0ULL >> 1));
29 static int sd_is_left_mergeable(struct reiserfs_key
*key
, unsigned long bsize
)
34 static char *print_time(time_t t
)
36 static char timebuf
[256];
38 sprintf(timebuf
, "%ld", t
);
42 static void sd_print_item(struct item_head
*ih
, char *item
)
44 printk("\tmode | size | nlinks | first direct | mtime\n");
45 if (stat_data_v1(ih
)) {
46 struct stat_data_v1
*sd
= (struct stat_data_v1
*)item
;
48 printk("\t0%-6o | %6u | %2u | %d | %s\n", sd_v1_mode(sd
),
49 sd_v1_size(sd
), sd_v1_nlink(sd
),
50 sd_v1_first_direct_byte(sd
),
51 print_time(sd_v1_mtime(sd
)));
53 struct stat_data
*sd
= (struct stat_data
*)item
;
55 printk("\t0%-6o | %6Lu | %2u | %d | %s\n", sd_v2_mode(sd
),
56 (unsigned long long)sd_v2_size(sd
), sd_v2_nlink(sd
),
57 sd_v2_rdev(sd
), print_time(sd_v2_mtime(sd
)));
61 static void sd_check_item(struct item_head
*ih
, char *item
)
63 // FIXME: type something here!
66 static int sd_create_vi(struct virtual_node
*vn
,
67 struct virtual_item
*vi
,
68 int is_affected
, int insert_size
)
70 vi
->vi_index
= TYPE_STAT_DATA
;
71 //vi->vi_type |= VI_TYPE_STAT_DATA;// not needed?
75 static int sd_check_left(struct virtual_item
*vi
, int free
,
76 int start_skip
, int end_skip
)
78 BUG_ON(start_skip
|| end_skip
);
82 static int sd_check_right(struct virtual_item
*vi
, int free
)
87 static int sd_part_size(struct virtual_item
*vi
, int first
, int count
)
93 static int sd_unit_num(struct virtual_item
*vi
)
95 return vi
->vi_item_len
- IH_SIZE
;
98 static void sd_print_vi(struct virtual_item
*vi
)
100 reiserfs_warning(NULL
, "reiserfs-16100",
101 "STATDATA, index %d, type 0x%x, %h",
102 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
105 static struct item_operations stat_data_ops
= {
106 .bytes_number
= sd_bytes_number
,
107 .decrement_key
= sd_decrement_key
,
108 .is_left_mergeable
= sd_is_left_mergeable
,
109 .print_item
= sd_print_item
,
110 .check_item
= sd_check_item
,
112 .create_vi
= sd_create_vi
,
113 .check_left
= sd_check_left
,
114 .check_right
= sd_check_right
,
115 .part_size
= sd_part_size
,
116 .unit_num
= sd_unit_num
,
117 .print_vi
= sd_print_vi
120 //////////////////////////////////////////////////////////////////////////////
121 // direct item functions
123 static int direct_bytes_number(struct item_head
*ih
, int block_size
)
125 return ih_item_len(ih
);
128 // FIXME: this should probably switch to indirect as well
129 static void direct_decrement_key(struct cpu_key
*key
)
131 cpu_key_k_offset_dec(key
);
132 if (cpu_key_k_offset(key
) == 0)
133 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
136 static int direct_is_left_mergeable(struct reiserfs_key
*key
,
139 int version
= le_key_version(key
);
140 return ((le_key_k_offset(version
, key
) & (bsize
- 1)) != 1);
143 static void direct_print_item(struct item_head
*ih
, char *item
)
149 while (j
< ih_item_len(ih
))
150 printk("%c", item
[j
++]);
154 static void direct_check_item(struct item_head
*ih
, char *item
)
156 // FIXME: type something here!
159 static int direct_create_vi(struct virtual_node
*vn
,
160 struct virtual_item
*vi
,
161 int is_affected
, int insert_size
)
163 vi
->vi_index
= TYPE_DIRECT
;
164 //vi->vi_type |= VI_TYPE_DIRECT;
168 static int direct_check_left(struct virtual_item
*vi
, int free
,
169 int start_skip
, int end_skip
)
173 bytes
= free
- free
% 8;
177 static int direct_check_right(struct virtual_item
*vi
, int free
)
179 return direct_check_left(vi
, free
, 0, 0);
182 static int direct_part_size(struct virtual_item
*vi
, int first
, int count
)
187 static int direct_unit_num(struct virtual_item
*vi
)
189 return vi
->vi_item_len
- IH_SIZE
;
192 static void direct_print_vi(struct virtual_item
*vi
)
194 reiserfs_warning(NULL
, "reiserfs-16101",
195 "DIRECT, index %d, type 0x%x, %h",
196 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
199 static struct item_operations direct_ops
= {
200 .bytes_number
= direct_bytes_number
,
201 .decrement_key
= direct_decrement_key
,
202 .is_left_mergeable
= direct_is_left_mergeable
,
203 .print_item
= direct_print_item
,
204 .check_item
= direct_check_item
,
206 .create_vi
= direct_create_vi
,
207 .check_left
= direct_check_left
,
208 .check_right
= direct_check_right
,
209 .part_size
= direct_part_size
,
210 .unit_num
= direct_unit_num
,
211 .print_vi
= direct_print_vi
214 //////////////////////////////////////////////////////////////////////////////
215 // indirect item functions
218 static int indirect_bytes_number(struct item_head
*ih
, int block_size
)
220 return ih_item_len(ih
) / UNFM_P_SIZE
* block_size
; //- get_ih_free_space (ih);
223 // decrease offset, if it becomes 0, change type to stat data
224 static void indirect_decrement_key(struct cpu_key
*key
)
226 cpu_key_k_offset_dec(key
);
227 if (cpu_key_k_offset(key
) == 0)
228 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
231 // if it is not first item of the body, then it is mergeable
232 static int indirect_is_left_mergeable(struct reiserfs_key
*key
,
235 int version
= le_key_version(key
);
236 return (le_key_k_offset(version
, key
) != 1);
239 // printing of indirect item
240 static void start_new_sequence(__u32
* start
, int *len
, __u32
new)
246 static int sequence_finished(__u32 start
, int *len
, __u32
new)
248 if (start
== INT_MAX
)
251 if (start
== 0 && new == 0) {
255 if (start
!= 0 && (start
+ *len
) == new) {
262 static void print_sequence(__u32 start
, int len
)
264 if (start
== INT_MAX
)
268 printk(" %d", start
);
270 printk(" %d(%d)", start
, len
);
273 static void indirect_print_item(struct item_head
*ih
, char *item
)
277 __u32 prev
= INT_MAX
;
280 unp
= (__le32
*) item
;
282 if (ih_item_len(ih
) % UNFM_P_SIZE
)
283 reiserfs_warning(NULL
, "reiserfs-16102", "invalid item len");
285 printk("%d pointers\n[ ", (int)I_UNFM_NUM(ih
));
286 for (j
= 0; j
< I_UNFM_NUM(ih
); j
++) {
287 if (sequence_finished(prev
, &num
, get_block_num(unp
, j
))) {
288 print_sequence(prev
, num
);
289 start_new_sequence(&prev
, &num
, get_block_num(unp
, j
));
292 print_sequence(prev
, num
);
296 static void indirect_check_item(struct item_head
*ih
, char *item
)
298 // FIXME: type something here!
301 static int indirect_create_vi(struct virtual_node
*vn
,
302 struct virtual_item
*vi
,
303 int is_affected
, int insert_size
)
305 vi
->vi_index
= TYPE_INDIRECT
;
306 //vi->vi_type |= VI_TYPE_INDIRECT;
310 static int indirect_check_left(struct virtual_item
*vi
, int free
,
311 int start_skip
, int end_skip
)
315 bytes
= free
- free
% UNFM_P_SIZE
;
319 static int indirect_check_right(struct virtual_item
*vi
, int free
)
321 return indirect_check_left(vi
, free
, 0, 0);
324 // return size in bytes of 'units' units. If first == 0 - calculate from the head (left), otherwise - from tail (right)
325 static int indirect_part_size(struct virtual_item
*vi
, int first
, int units
)
327 // unit of indirect item is byte (yet)
331 static int indirect_unit_num(struct virtual_item
*vi
)
333 // unit of indirect item is byte (yet)
334 return vi
->vi_item_len
- IH_SIZE
;
337 static void indirect_print_vi(struct virtual_item
*vi
)
339 reiserfs_warning(NULL
, "reiserfs-16103",
340 "INDIRECT, index %d, type 0x%x, %h",
341 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
);
344 static struct item_operations indirect_ops
= {
345 .bytes_number
= indirect_bytes_number
,
346 .decrement_key
= indirect_decrement_key
,
347 .is_left_mergeable
= indirect_is_left_mergeable
,
348 .print_item
= indirect_print_item
,
349 .check_item
= indirect_check_item
,
351 .create_vi
= indirect_create_vi
,
352 .check_left
= indirect_check_left
,
353 .check_right
= indirect_check_right
,
354 .part_size
= indirect_part_size
,
355 .unit_num
= indirect_unit_num
,
356 .print_vi
= indirect_print_vi
359 //////////////////////////////////////////////////////////////////////////////
360 // direntry functions
363 static int direntry_bytes_number(struct item_head
*ih
, int block_size
)
365 reiserfs_warning(NULL
, "vs-16090",
366 "bytes number is asked for direntry");
370 static void direntry_decrement_key(struct cpu_key
*key
)
372 cpu_key_k_offset_dec(key
);
373 if (cpu_key_k_offset(key
) == 0)
374 set_cpu_key_k_type(key
, TYPE_STAT_DATA
);
377 static int direntry_is_left_mergeable(struct reiserfs_key
*key
,
380 if (le32_to_cpu(key
->u
.k_offset_v1
.k_offset
) == DOT_OFFSET
)
386 static void direntry_print_item(struct item_head
*ih
, char *item
)
390 struct reiserfs_de_head
*deh
;
392 static char namebuf
[80];
394 printk("\n # %-15s%-30s%-15s%-15s%-15s\n", "Name",
395 "Key of pointed object", "Hash", "Gen number", "Status");
397 deh
= (struct reiserfs_de_head
*)item
;
399 for (i
= 0; i
< I_ENTRY_COUNT(ih
); i
++, deh
++) {
401 (i
? (deh_location(deh
- 1)) : ih_item_len(ih
)) -
403 name
= item
+ deh_location(deh
);
404 if (name
[namelen
- 1] == 0)
405 namelen
= strlen(name
);
407 if (namelen
> sizeof(namebuf
) - 3) {
408 strncpy(namebuf
+ 1, name
, sizeof(namebuf
) - 3);
409 namebuf
[sizeof(namebuf
) - 2] = '"';
410 namebuf
[sizeof(namebuf
) - 1] = 0;
412 memcpy(namebuf
+ 1, name
, namelen
);
413 namebuf
[namelen
+ 1] = '"';
414 namebuf
[namelen
+ 2] = 0;
417 printk("%d: %-15s%-15d%-15d%-15Ld%-15Ld(%s)\n",
419 deh_dir_id(deh
), deh_objectid(deh
),
420 GET_HASH_VALUE(deh_offset(deh
)),
421 GET_GENERATION_NUMBER((deh_offset(deh
))),
422 (de_hidden(deh
)) ? "HIDDEN" : "VISIBLE");
426 static void direntry_check_item(struct item_head
*ih
, char *item
)
429 struct reiserfs_de_head
*deh
;
431 // FIXME: type something here!
432 deh
= (struct reiserfs_de_head
*)item
;
433 for (i
= 0; i
< I_ENTRY_COUNT(ih
); i
++, deh
++) {
438 #define DIRENTRY_VI_FIRST_DIRENTRY_ITEM 1
441 * function returns old entry number in directory item in real node
442 * using new entry number in virtual item in virtual node */
443 static inline int old_entry_num(int is_affected
, int virtual_entry_num
,
444 int pos_in_item
, int mode
)
446 if (mode
== M_INSERT
|| mode
== M_DELETE
)
447 return virtual_entry_num
;
450 /* cut or paste is applied to another item */
451 return virtual_entry_num
;
453 if (virtual_entry_num
< pos_in_item
)
454 return virtual_entry_num
;
457 return virtual_entry_num
+ 1;
459 RFALSE(mode
!= M_PASTE
|| virtual_entry_num
== 0,
460 "vs-8015: old_entry_num: mode must be M_PASTE (mode = \'%c\'",
463 return virtual_entry_num
- 1;
466 /* Create an array of sizes of directory entries for virtual
467 item. Return space used by an item. FIXME: no control over
468 consuming of space used by this item handler */
469 static int direntry_create_vi(struct virtual_node
*vn
,
470 struct virtual_item
*vi
,
471 int is_affected
, int insert_size
)
473 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
475 int size
= sizeof(struct direntry_uarea
);
476 struct reiserfs_de_head
*deh
;
478 vi
->vi_index
= TYPE_DIRENTRY
;
480 BUG_ON(!(vi
->vi_ih
) || !vi
->vi_item
);
483 if (le_ih_k_offset(vi
->vi_ih
) == DOT_OFFSET
)
484 dir_u
->flags
|= DIRENTRY_VI_FIRST_DIRENTRY_ITEM
;
486 deh
= (struct reiserfs_de_head
*)(vi
->vi_item
);
488 /* virtual directory item have this amount of entry after */
489 dir_u
->entry_count
= ih_entry_count(vi
->vi_ih
) +
490 ((is_affected
) ? ((vn
->vn_mode
== M_CUT
) ? -1 :
491 (vn
->vn_mode
== M_PASTE
? 1 : 0)) : 0);
493 for (i
= 0; i
< dir_u
->entry_count
; i
++) {
494 j
= old_entry_num(is_affected
, i
, vn
->vn_pos_in_item
,
496 dir_u
->entry_sizes
[i
] =
497 (j
? deh_location(&(deh
[j
- 1])) : ih_item_len(vi
->vi_ih
)) -
498 deh_location(&(deh
[j
])) + DEH_SIZE
;
501 size
+= (dir_u
->entry_count
* sizeof(short));
503 /* set size of pasted entry */
504 if (is_affected
&& vn
->vn_mode
== M_PASTE
)
505 dir_u
->entry_sizes
[vn
->vn_pos_in_item
] = insert_size
;
507 #ifdef CONFIG_REISERFS_CHECK
508 /* compare total size of entries with item length */
513 for (k
= 0; k
< dir_u
->entry_count
; k
++)
514 l
+= dir_u
->entry_sizes
[k
];
516 if (l
+ IH_SIZE
!= vi
->vi_item_len
+
518 && (vn
->vn_mode
== M_PASTE
519 || vn
->vn_mode
== M_CUT
)) ? insert_size
: 0)) {
520 reiserfs_panic(NULL
, "vs-8025", "(mode==%c, "
521 "insert_size==%d), invalid length of "
523 vn
->vn_mode
, insert_size
);
533 // return number of entries which may fit into specified amount of
534 // free space, or -1 if free space is not enough even for 1 entry
536 static int direntry_check_left(struct virtual_item
*vi
, int free
,
537 int start_skip
, int end_skip
)
541 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
543 for (i
= start_skip
; i
< dir_u
->entry_count
- end_skip
; i
++) {
544 if (dir_u
->entry_sizes
[i
] > free
)
545 /* i-th entry doesn't fit into the remaining free space */
548 free
-= dir_u
->entry_sizes
[i
];
552 if (entries
== dir_u
->entry_count
) {
553 reiserfs_panic(NULL
, "item_ops-1",
554 "free space %d, entry_count %d", free
,
558 /* "." and ".." can not be separated from each other */
559 if (start_skip
== 0 && (dir_u
->flags
& DIRENTRY_VI_FIRST_DIRENTRY_ITEM
)
563 return entries
? : -1;
566 static int direntry_check_right(struct virtual_item
*vi
, int free
)
570 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
572 for (i
= dir_u
->entry_count
- 1; i
>= 0; i
--) {
573 if (dir_u
->entry_sizes
[i
] > free
)
574 /* i-th entry doesn't fit into the remaining free space */
577 free
-= dir_u
->entry_sizes
[i
];
580 BUG_ON(entries
== dir_u
->entry_count
);
582 /* "." and ".." can not be separated from each other */
583 if ((dir_u
->flags
& DIRENTRY_VI_FIRST_DIRENTRY_ITEM
)
584 && entries
> dir_u
->entry_count
- 2)
585 entries
= dir_u
->entry_count
- 2;
587 return entries
? : -1;
590 /* sum of entry sizes between from-th and to-th entries including both edges */
591 static int direntry_part_size(struct virtual_item
*vi
, int first
, int count
)
595 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
601 from
= dir_u
->entry_count
- count
;
602 to
= from
+ count
- 1;
604 for (i
= from
; i
<= to
; i
++)
605 retval
+= dir_u
->entry_sizes
[i
];
610 static int direntry_unit_num(struct virtual_item
*vi
)
612 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
614 return dir_u
->entry_count
;
617 static void direntry_print_vi(struct virtual_item
*vi
)
620 struct direntry_uarea
*dir_u
= vi
->vi_uarea
;
622 reiserfs_warning(NULL
, "reiserfs-16104",
623 "DIRENTRY, index %d, type 0x%x, %h, flags 0x%x",
624 vi
->vi_index
, vi
->vi_type
, vi
->vi_ih
, dir_u
->flags
);
625 printk("%d entries: ", dir_u
->entry_count
);
626 for (i
= 0; i
< dir_u
->entry_count
; i
++)
627 printk("%d ", dir_u
->entry_sizes
[i
]);
631 static struct item_operations direntry_ops
= {
632 .bytes_number
= direntry_bytes_number
,
633 .decrement_key
= direntry_decrement_key
,
634 .is_left_mergeable
= direntry_is_left_mergeable
,
635 .print_item
= direntry_print_item
,
636 .check_item
= direntry_check_item
,
638 .create_vi
= direntry_create_vi
,
639 .check_left
= direntry_check_left
,
640 .check_right
= direntry_check_right
,
641 .part_size
= direntry_part_size
,
642 .unit_num
= direntry_unit_num
,
643 .print_vi
= direntry_print_vi
646 //////////////////////////////////////////////////////////////////////////////
647 // Error catching functions to catch errors caused by incorrect item types.
649 static int errcatch_bytes_number(struct item_head
*ih
, int block_size
)
651 reiserfs_warning(NULL
, "green-16001",
652 "Invalid item type observed, run fsck ASAP");
656 static void errcatch_decrement_key(struct cpu_key
*key
)
658 reiserfs_warning(NULL
, "green-16002",
659 "Invalid item type observed, run fsck ASAP");
662 static int errcatch_is_left_mergeable(struct reiserfs_key
*key
,
665 reiserfs_warning(NULL
, "green-16003",
666 "Invalid item type observed, run fsck ASAP");
670 static void errcatch_print_item(struct item_head
*ih
, char *item
)
672 reiserfs_warning(NULL
, "green-16004",
673 "Invalid item type observed, run fsck ASAP");
676 static void errcatch_check_item(struct item_head
*ih
, char *item
)
678 reiserfs_warning(NULL
, "green-16005",
679 "Invalid item type observed, run fsck ASAP");
682 static int errcatch_create_vi(struct virtual_node
*vn
,
683 struct virtual_item
*vi
,
684 int is_affected
, int insert_size
)
686 reiserfs_warning(NULL
, "green-16006",
687 "Invalid item type observed, run fsck ASAP");
688 return 0; // We might return -1 here as well, but it won't help as create_virtual_node() from where
689 // this operation is called from is of return type void.
692 static int errcatch_check_left(struct virtual_item
*vi
, int free
,
693 int start_skip
, int end_skip
)
695 reiserfs_warning(NULL
, "green-16007",
696 "Invalid item type observed, run fsck ASAP");
700 static int errcatch_check_right(struct virtual_item
*vi
, int free
)
702 reiserfs_warning(NULL
, "green-16008",
703 "Invalid item type observed, run fsck ASAP");
707 static int errcatch_part_size(struct virtual_item
*vi
, int first
, int count
)
709 reiserfs_warning(NULL
, "green-16009",
710 "Invalid item type observed, run fsck ASAP");
714 static int errcatch_unit_num(struct virtual_item
*vi
)
716 reiserfs_warning(NULL
, "green-16010",
717 "Invalid item type observed, run fsck ASAP");
721 static void errcatch_print_vi(struct virtual_item
*vi
)
723 reiserfs_warning(NULL
, "green-16011",
724 "Invalid item type observed, run fsck ASAP");
727 static struct item_operations errcatch_ops
= {
728 errcatch_bytes_number
,
729 errcatch_decrement_key
,
730 errcatch_is_left_mergeable
,
736 errcatch_check_right
,
742 //////////////////////////////////////////////////////////////////////////////
745 #if ! (TYPE_STAT_DATA == 0 && TYPE_INDIRECT == 1 && TYPE_DIRECT == 2 && TYPE_DIRENTRY == 3)
746 #error Item types must use disk-format assigned values.
749 struct item_operations
*item_ops
[TYPE_ANY
+ 1] = {
754 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
755 &errcatch_ops
/* This is to catch errors with invalid type (15th entry for TYPE_ANY) */