reiserfs: rearrange journal abort
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / reiserfs / prints.c
1 /*
2  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3  */
4
5 #include <linux/time.h>
6 #include <linux/fs.h>
7 #include <linux/reiserfs_fs.h>
8 #include <linux/string.h>
9 #include <linux/buffer_head.h>
10
11 #include <stdarg.h>
12
13 static char error_buf[1024];
14 static char fmt_buf[1024];
15 static char off_buf[80];
16
17 static char *reiserfs_cpu_offset(struct cpu_key *key)
18 {
19         if (cpu_key_k_type(key) == TYPE_DIRENTRY)
20                 sprintf(off_buf, "%Lu(%Lu)",
21                         (unsigned long long)
22                         GET_HASH_VALUE(cpu_key_k_offset(key)),
23                         (unsigned long long)
24                         GET_GENERATION_NUMBER(cpu_key_k_offset(key)));
25         else
26                 sprintf(off_buf, "0x%Lx",
27                         (unsigned long long)cpu_key_k_offset(key));
28         return off_buf;
29 }
30
31 static char *le_offset(struct reiserfs_key *key)
32 {
33         int version;
34
35         version = le_key_version(key);
36         if (le_key_k_type(version, key) == TYPE_DIRENTRY)
37                 sprintf(off_buf, "%Lu(%Lu)",
38                         (unsigned long long)
39                         GET_HASH_VALUE(le_key_k_offset(version, key)),
40                         (unsigned long long)
41                         GET_GENERATION_NUMBER(le_key_k_offset(version, key)));
42         else
43                 sprintf(off_buf, "0x%Lx",
44                         (unsigned long long)le_key_k_offset(version, key));
45         return off_buf;
46 }
47
48 static char *cpu_type(struct cpu_key *key)
49 {
50         if (cpu_key_k_type(key) == TYPE_STAT_DATA)
51                 return "SD";
52         if (cpu_key_k_type(key) == TYPE_DIRENTRY)
53                 return "DIR";
54         if (cpu_key_k_type(key) == TYPE_DIRECT)
55                 return "DIRECT";
56         if (cpu_key_k_type(key) == TYPE_INDIRECT)
57                 return "IND";
58         return "UNKNOWN";
59 }
60
61 static char *le_type(struct reiserfs_key *key)
62 {
63         int version;
64
65         version = le_key_version(key);
66
67         if (le_key_k_type(version, key) == TYPE_STAT_DATA)
68                 return "SD";
69         if (le_key_k_type(version, key) == TYPE_DIRENTRY)
70                 return "DIR";
71         if (le_key_k_type(version, key) == TYPE_DIRECT)
72                 return "DIRECT";
73         if (le_key_k_type(version, key) == TYPE_INDIRECT)
74                 return "IND";
75         return "UNKNOWN";
76 }
77
78 /* %k */
79 static void sprintf_le_key(char *buf, struct reiserfs_key *key)
80 {
81         if (key)
82                 sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id),
83                         le32_to_cpu(key->k_objectid), le_offset(key),
84                         le_type(key));
85         else
86                 sprintf(buf, "[NULL]");
87 }
88
89 /* %K */
90 static void sprintf_cpu_key(char *buf, struct cpu_key *key)
91 {
92         if (key)
93                 sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id,
94                         key->on_disk_key.k_objectid, reiserfs_cpu_offset(key),
95                         cpu_type(key));
96         else
97                 sprintf(buf, "[NULL]");
98 }
99
100 static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh)
101 {
102         if (deh)
103                 sprintf(buf,
104                         "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
105                         deh_offset(deh), deh_dir_id(deh), deh_objectid(deh),
106                         deh_location(deh), deh_state(deh));
107         else
108                 sprintf(buf, "[NULL]");
109
110 }
111
112 static void sprintf_item_head(char *buf, struct item_head *ih)
113 {
114         if (ih) {
115                 strcpy(buf,
116                        (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
117                 sprintf_le_key(buf + strlen(buf), &(ih->ih_key));
118                 sprintf(buf + strlen(buf), ", item_len %d, item_location %d, "
119                         "free_space(entry_count) %d",
120                         ih_item_len(ih), ih_location(ih), ih_free_space(ih));
121         } else
122                 sprintf(buf, "[NULL]");
123 }
124
125 static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de)
126 {
127         char name[20];
128
129         memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
130         name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
131         sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
132 }
133
134 static void sprintf_block_head(char *buf, struct buffer_head *bh)
135 {
136         sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
137                 B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
138 }
139
140 static void sprintf_buffer_head(char *buf, struct buffer_head *bh)
141 {
142         char b[BDEVNAME_SIZE];
143
144         sprintf(buf,
145                 "dev %s, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
146                 bdevname(bh->b_bdev, b), bh->b_size,
147                 (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)),
148                 bh->b_state, bh->b_page,
149                 buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
150                 buffer_dirty(bh) ? "DIRTY" : "CLEAN",
151                 buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
152 }
153
154 static void sprintf_disk_child(char *buf, struct disk_child *dc)
155 {
156         sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc),
157                 dc_size(dc));
158 }
159
160 static char *is_there_reiserfs_struct(char *fmt, int *what)
161 {
162         char *k = fmt;
163
164         while ((k = strchr(k, '%')) != NULL) {
165                 if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
166                     k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
167                         *what = k[1];
168                         break;
169                 }
170                 k++;
171         }
172         return k;
173 }
174
175 /* debugging reiserfs we used to print out a lot of different
176    variables, like keys, item headers, buffer heads etc. Values of
177    most fields matter. So it took a long time just to write
178    appropriative printk. With this reiserfs_warning you can use format
179    specification for complex structures like you used to do with
180    printfs for integers, doubles and pointers. For instance, to print
181    out key structure you have to write just: 
182    reiserfs_warning ("bad key %k", key); 
183    instead of 
184    printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid, 
185            key->k_offset, key->k_uniqueness); 
186 */
187 static DEFINE_SPINLOCK(error_lock);
188 static void prepare_error_buf(const char *fmt, va_list args)
189 {
190         char *fmt1 = fmt_buf;
191         char *k;
192         char *p = error_buf;
193         int what;
194
195         spin_lock(&error_lock);
196
197         strcpy(fmt1, fmt);
198
199         while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
200                 *k = 0;
201
202                 p += vsprintf(p, fmt1, args);
203
204                 switch (what) {
205                 case 'k':
206                         sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
207                         break;
208                 case 'K':
209                         sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
210                         break;
211                 case 'h':
212                         sprintf_item_head(p, va_arg(args, struct item_head *));
213                         break;
214                 case 't':
215                         sprintf_direntry(p,
216                                          va_arg(args,
217                                                 struct reiserfs_dir_entry *));
218                         break;
219                 case 'y':
220                         sprintf_disk_child(p,
221                                            va_arg(args, struct disk_child *));
222                         break;
223                 case 'z':
224                         sprintf_block_head(p,
225                                            va_arg(args, struct buffer_head *));
226                         break;
227                 case 'b':
228                         sprintf_buffer_head(p,
229                                             va_arg(args, struct buffer_head *));
230                         break;
231                 case 'a':
232                         sprintf_de_head(p,
233                                         va_arg(args,
234                                                struct reiserfs_de_head *));
235                         break;
236                 }
237
238                 p += strlen(p);
239                 fmt1 = k + 2;
240         }
241         vsprintf(p, fmt1, args);
242         spin_unlock(&error_lock);
243
244 }
245
246 /* in addition to usual conversion specifiers this accepts reiserfs
247    specific conversion specifiers: 
248    %k to print little endian key, 
249    %K to print cpu key, 
250    %h to print item_head,
251    %t to print directory entry 
252    %z to print block head (arg must be struct buffer_head *
253    %b to print buffer_head
254 */
255
256 #define do_reiserfs_warning(fmt)\
257 {\
258     va_list args;\
259     va_start( args, fmt );\
260     prepare_error_buf( fmt, args );\
261     va_end( args );\
262 }
263
264 void __reiserfs_warning(struct super_block *sb, const char *id,
265                          const char *function, const char *fmt, ...)
266 {
267         do_reiserfs_warning(fmt);
268         if (sb)
269                 printk(KERN_WARNING "REISERFS warning (device %s): %s%s%s: "
270                        "%s\n", sb->s_id, id ? id : "", id ? " " : "",
271                        function, error_buf);
272         else
273                 printk(KERN_WARNING "REISERFS warning: %s%s%s: %s\n",
274                        id ? id : "", id ? " " : "", function, error_buf);
275 }
276
277 /* No newline.. reiserfs_info calls can be followed by printk's */
278 void reiserfs_info(struct super_block *sb, const char *fmt, ...)
279 {
280         do_reiserfs_warning(fmt);
281         if (sb)
282                 printk(KERN_NOTICE "REISERFS (device %s): %s",
283                        sb->s_id, error_buf);
284         else
285                 printk(KERN_NOTICE "REISERFS %s:", error_buf);
286 }
287
288 /* No newline.. reiserfs_printk calls can be followed by printk's */
289 static void reiserfs_printk(const char *fmt, ...)
290 {
291         do_reiserfs_warning(fmt);
292         printk(error_buf);
293 }
294
295 void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
296 {
297 #ifdef CONFIG_REISERFS_CHECK
298         do_reiserfs_warning(fmt);
299         if (s)
300                 printk(KERN_DEBUG "REISERFS debug (device %s): %s\n",
301                        s->s_id, error_buf);
302         else
303                 printk(KERN_DEBUG "REISERFS debug: %s\n", error_buf);
304 #endif
305 }
306
307 /* The format:
308
309            maintainer-errorid: [function-name:] message
310
311     where errorid is unique to the maintainer and function-name is
312     optional, is recommended, so that anyone can easily find the bug
313     with a simple grep for the short to type string
314     maintainer-errorid.  Don't bother with reusing errorids, there are
315     lots of numbers out there.
316
317     Example: 
318     
319     reiserfs_panic(
320         p_sb, "reiser-29: reiserfs_new_blocknrs: "
321         "one of search_start or rn(%d) is equal to MAX_B_NUM,"
322         "which means that we are optimizing location based on the bogus location of a temp buffer (%p).", 
323         rn, bh
324     );
325
326     Regular panic()s sometimes clear the screen before the message can
327     be read, thus the need for the while loop.  
328
329     Numbering scheme for panic used by Vladimir and Anatoly( Hans completely ignores this scheme, and considers it
330     pointless complexity):
331
332     panics in reiserfs_fs.h have numbers from 1000 to 1999
333     super.c                                     2000 to 2999
334     preserve.c (unused)                     3000 to 3999
335     bitmap.c                                4000 to 4999
336     stree.c                                     5000 to 5999
337     prints.c                                6000 to 6999
338     namei.c                     7000 to 7999
339     fix_nodes.c                 8000 to 8999
340     dir.c                       9000 to 9999
341         lbalance.c                                      10000 to 10999
342         ibalance.c              11000 to 11999 not ready
343         do_balan.c              12000 to 12999
344         inode.c                 13000 to 13999
345         file.c                  14000 to 14999
346     objectid.c                       15000 - 15999
347     buffer.c                         16000 - 16999
348     symlink.c                        17000 - 17999
349
350    .  */
351
352 #ifdef CONFIG_REISERFS_CHECK
353 extern struct tree_balance *cur_tb;
354 #endif
355
356 void __reiserfs_panic(struct super_block *sb, const char *id,
357                       const char *function, const char *fmt, ...)
358 {
359         do_reiserfs_warning(fmt);
360
361 #ifdef CONFIG_REISERFS_CHECK
362         dump_stack();
363 #endif
364         if (sb)
365                 panic(KERN_WARNING "REISERFS panic (device %s): %s%s%s: %s\n",
366                       sb->s_id, id ? id : "", id ? " " : "",
367                       function, error_buf);
368         else
369                 panic(KERN_WARNING "REISERFS panic: %s%s%s: %s\n",
370                       id ? id : "", id ? " " : "", function, error_buf);
371 }
372
373 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
374 {
375         do_reiserfs_warning(fmt);
376
377         if (reiserfs_error_panic(sb)) {
378                 panic(KERN_CRIT "REISERFS panic (device %s): %s\n", sb->s_id,
379                       error_buf);
380         }
381
382         if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
383                 return;
384
385         printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
386                error_buf);
387
388         sb->s_flags |= MS_RDONLY;
389         reiserfs_abort_journal(sb, errno);
390 }
391
392 /* this prints internal nodes (4 keys/items in line) (dc_number,
393    dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
394    dc_size)...*/
395 static int print_internal(struct buffer_head *bh, int first, int last)
396 {
397         struct reiserfs_key *key;
398         struct disk_child *dc;
399         int i;
400         int from, to;
401
402         if (!B_IS_KEYS_LEVEL(bh))
403                 return 1;
404
405         check_internal(bh);
406
407         if (first == -1) {
408                 from = 0;
409                 to = B_NR_ITEMS(bh);
410         } else {
411                 from = first;
412                 to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
413         }
414
415         reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
416
417         dc = B_N_CHILD(bh, from);
418         reiserfs_printk("PTR %d: %y ", from, dc);
419
420         for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
421              i++, key++, dc++) {
422                 reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
423                 if (i && i % 4 == 0)
424                         printk("\n");
425         }
426         printk("\n");
427         return 0;
428 }
429
430 static int print_leaf(struct buffer_head *bh, int print_mode, int first,
431                       int last)
432 {
433         struct block_head *blkh;
434         struct item_head *ih;
435         int i, nr;
436         int from, to;
437
438         if (!B_IS_ITEMS_LEVEL(bh))
439                 return 1;
440
441         check_leaf(bh);
442
443         blkh = B_BLK_HEAD(bh);
444         ih = B_N_PITEM_HEAD(bh, 0);
445         nr = blkh_nr_item(blkh);
446
447         printk
448             ("\n===================================================================\n");
449         reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
450
451         if (!(print_mode & PRINT_LEAF_ITEMS)) {
452                 reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
453                                 &(ih->ih_key), &((ih + nr - 1)->ih_key));
454                 return 0;
455         }
456
457         if (first < 0 || first > nr - 1)
458                 from = 0;
459         else
460                 from = first;
461
462         if (last < 0 || last > nr)
463                 to = nr;
464         else
465                 to = last;
466
467         ih += from;
468         printk
469             ("-------------------------------------------------------------------------------\n");
470         printk
471             ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
472         for (i = from; i < to; i++, ih++) {
473                 printk
474                     ("-------------------------------------------------------------------------------\n");
475                 reiserfs_printk("|%2d| %h |\n", i, ih);
476                 if (print_mode & PRINT_LEAF_ITEMS)
477                         op_print_item(ih, B_I_PITEM(bh, ih));
478         }
479
480         printk
481             ("===================================================================\n");
482
483         return 0;
484 }
485
486 char *reiserfs_hashname(int code)
487 {
488         if (code == YURA_HASH)
489                 return "rupasov";
490         if (code == TEA_HASH)
491                 return "tea";
492         if (code == R5_HASH)
493                 return "r5";
494
495         return "unknown";
496 }
497
498 /* return 1 if this is not super block */
499 static int print_super_block(struct buffer_head *bh)
500 {
501         struct reiserfs_super_block *rs =
502             (struct reiserfs_super_block *)(bh->b_data);
503         int skipped, data_blocks;
504         char *version;
505         char b[BDEVNAME_SIZE];
506
507         if (is_reiserfs_3_5(rs)) {
508                 version = "3.5";
509         } else if (is_reiserfs_3_6(rs)) {
510                 version = "3.6";
511         } else if (is_reiserfs_jr(rs)) {
512                 version = ((sb_version(rs) == REISERFS_VERSION_2) ?
513                            "3.6" : "3.5");
514         } else {
515                 return 1;
516         }
517
518         printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
519                (unsigned long long)bh->b_blocknr);
520         printk("Reiserfs version %s\n", version);
521         printk("Block count %u\n", sb_block_count(rs));
522         printk("Blocksize %d\n", sb_blocksize(rs));
523         printk("Free blocks %u\n", sb_free_blocks(rs));
524         // FIXME: this would be confusing if
525         // someone stores reiserfs super block in some data block ;)
526 //    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
527         skipped = bh->b_blocknr;
528         data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
529             (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
530              1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
531         printk
532             ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
533              "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
534              (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
535               sb_reserved_for_journal(rs)), data_blocks);
536         printk("Root block %u\n", sb_root_block(rs));
537         printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
538         printk("Journal dev %d\n", sb_jp_journal_dev(rs));
539         printk("Journal orig size %d\n", sb_jp_journal_size(rs));
540         printk("FS state %d\n", sb_fs_state(rs));
541         printk("Hash function \"%s\"\n",
542                reiserfs_hashname(sb_hash_function_code(rs)));
543
544         printk("Tree height %d\n", sb_tree_height(rs));
545         return 0;
546 }
547
548 static int print_desc_block(struct buffer_head *bh)
549 {
550         struct reiserfs_journal_desc *desc;
551
552         if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
553                 return 1;
554
555         desc = (struct reiserfs_journal_desc *)(bh->b_data);
556         printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
557                (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
558                get_desc_mount_id(desc), get_desc_trans_len(desc));
559
560         return 0;
561 }
562
563 void print_block(struct buffer_head *bh, ...)   //int print_mode, int first, int last)
564 {
565         va_list args;
566         int mode, first, last;
567
568         va_start(args, bh);
569
570         if (!bh) {
571                 printk("print_block: buffer is NULL\n");
572                 return;
573         }
574
575         mode = va_arg(args, int);
576         first = va_arg(args, int);
577         last = va_arg(args, int);
578         if (print_leaf(bh, mode, first, last))
579                 if (print_internal(bh, first, last))
580                         if (print_super_block(bh))
581                                 if (print_desc_block(bh))
582                                         printk
583                                             ("Block %llu contains unformatted data\n",
584                                              (unsigned long long)bh->b_blocknr);
585
586         va_end(args);
587 }
588
589 static char print_tb_buf[2048];
590
591 /* this stores initial state of tree balance in the print_tb_buf */
592 void store_print_tb(struct tree_balance *tb)
593 {
594         int h = 0;
595         int i;
596         struct buffer_head *tbSh, *tbFh;
597
598         if (!tb)
599                 return;
600
601         sprintf(print_tb_buf, "\n"
602                 "BALANCING %d\n"
603                 "MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
604                 "=====================================================================\n"
605                 "* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
606                 REISERFS_SB(tb->tb_sb)->s_do_balance,
607                 tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
608                 tb->tb_path->pos_in_item);
609
610         for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
611                 if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
612                     tb->tb_path->path_length
613                     && PATH_H_PATH_OFFSET(tb->tb_path,
614                                           h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
615                         tbSh = PATH_H_PBUFFER(tb->tb_path, h);
616                         tbFh = PATH_H_PPARENT(tb->tb_path, h);
617                 } else {
618                         tbSh = NULL;
619                         tbFh = NULL;
620                 }
621                 sprintf(print_tb_buf + strlen(print_tb_buf),
622                         "* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
623                         h,
624                         (tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
625                         (tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
626                         (tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
627                         (tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
628                         (tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
629                         (tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
630                         (tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
631                         (tb->FL[h]) ? (long long)(tb->FL[h]->
632                                                   b_blocknr) : (-1LL),
633                         (tb->FR[h]) ? (long long)(tb->FR[h]->
634                                                   b_blocknr) : (-1LL),
635                         (tb->CFL[h]) ? (long long)(tb->CFL[h]->
636                                                    b_blocknr) : (-1LL),
637                         (tb->CFR[h]) ? (long long)(tb->CFR[h]->
638                                                    b_blocknr) : (-1LL));
639         }
640
641         sprintf(print_tb_buf + strlen(print_tb_buf),
642                 "=====================================================================\n"
643                 "* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
644                 "* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
645                 tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
646                 tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
647                 tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
648                 tb->rkey[0]);
649
650         /* this prints balance parameters for non-leaf levels */
651         h = 0;
652         do {
653                 h++;
654                 sprintf(print_tb_buf + strlen(print_tb_buf),
655                         "* %d * %4d * %2d *    * %2d *    * %2d *\n",
656                         h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
657                         tb->blknum[h]);
658         } while (tb->insert_size[h]);
659
660         sprintf(print_tb_buf + strlen(print_tb_buf),
661                 "=====================================================================\n"
662                 "FEB list: ");
663
664         /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
665         h = 0;
666         for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
667                 sprintf(print_tb_buf + strlen(print_tb_buf),
668                         "%p (%llu %d)%s", tb->FEB[i],
669                         tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
670                         b_blocknr : 0ULL,
671                         tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
672                         (i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
673
674         sprintf(print_tb_buf + strlen(print_tb_buf),
675                 "======================== the end ====================================\n");
676 }
677
678 void print_cur_tb(char *mes)
679 {
680         printk("%s\n%s", mes, print_tb_buf);
681 }
682
683 static void check_leaf_block_head(struct buffer_head *bh)
684 {
685         struct block_head *blkh;
686         int nr;
687
688         blkh = B_BLK_HEAD(bh);
689         nr = blkh_nr_item(blkh);
690         if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
691                 reiserfs_panic(NULL, "vs-6010", "invalid item number %z",
692                                bh);
693         if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
694                 reiserfs_panic(NULL, "vs-6020", "invalid free space %z",
695                                bh);
696
697 }
698
699 static void check_internal_block_head(struct buffer_head *bh)
700 {
701         struct block_head *blkh;
702
703         blkh = B_BLK_HEAD(bh);
704         if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
705                 reiserfs_panic(NULL, "vs-6025", "invalid level %z", bh);
706
707         if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
708                 reiserfs_panic(NULL, "vs-6030", "invalid item number %z", bh);
709
710         if (B_FREE_SPACE(bh) !=
711             bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
712             DC_SIZE * (B_NR_ITEMS(bh) + 1))
713                 reiserfs_panic(NULL, "vs-6040", "invalid free space %z", bh);
714
715 }
716
717 void check_leaf(struct buffer_head *bh)
718 {
719         int i;
720         struct item_head *ih;
721
722         if (!bh)
723                 return;
724         check_leaf_block_head(bh);
725         for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
726                 op_check_item(ih, B_I_PITEM(bh, ih));
727 }
728
729 void check_internal(struct buffer_head *bh)
730 {
731         if (!bh)
732                 return;
733         check_internal_block_head(bh);
734 }
735
736 void print_statistics(struct super_block *s)
737 {
738
739         /*
740            printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
741            bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
742            REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
743            REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
744            REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
745          */
746
747 }