b87b23717c23115fb90be71a79501832ad7c4c32
[safe/jmp/linux-2.6] / 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
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         strcpy(fmt1, fmt);
196
197         while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
198                 *k = 0;
199
200                 p += vsprintf(p, fmt1, args);
201
202                 switch (what) {
203                 case 'k':
204                         sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
205                         break;
206                 case 'K':
207                         sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
208                         break;
209                 case 'h':
210                         sprintf_item_head(p, va_arg(args, struct item_head *));
211                         break;
212                 case 't':
213                         sprintf_direntry(p,
214                                          va_arg(args,
215                                                 struct reiserfs_dir_entry *));
216                         break;
217                 case 'y':
218                         sprintf_disk_child(p,
219                                            va_arg(args, struct disk_child *));
220                         break;
221                 case 'z':
222                         sprintf_block_head(p,
223                                            va_arg(args, struct buffer_head *));
224                         break;
225                 case 'b':
226                         sprintf_buffer_head(p,
227                                             va_arg(args, struct buffer_head *));
228                         break;
229                 case 'a':
230                         sprintf_de_head(p,
231                                         va_arg(args,
232                                                struct reiserfs_de_head *));
233                         break;
234                 }
235
236                 p += strlen(p);
237                 fmt1 = k + 2;
238         }
239         vsprintf(p, fmt1, args);
240
241 }
242
243 /* in addition to usual conversion specifiers this accepts reiserfs
244    specific conversion specifiers: 
245    %k to print little endian key, 
246    %K to print cpu key, 
247    %h to print item_head,
248    %t to print directory entry 
249    %z to print block head (arg must be struct buffer_head *
250    %b to print buffer_head
251 */
252
253 #define do_reiserfs_warning(fmt)\
254 {\
255     va_list args;\
256     va_start( args, fmt );\
257     prepare_error_buf( fmt, args );\
258     va_end( args );\
259 }
260
261 void __reiserfs_warning(struct super_block *sb, const char *id,
262                          const char *function, const char *fmt, ...)
263 {
264         do_reiserfs_warning(fmt);
265         if (sb)
266                 printk(KERN_WARNING "REISERFS warning (device %s): %s%s%s: "
267                        "%s\n", sb->s_id, id ? id : "", id ? " " : "",
268                        function, error_buf);
269         else
270                 printk(KERN_WARNING "REISERFS warning: %s%s%s: %s\n",
271                        id ? id : "", id ? " " : "", function, error_buf);
272 }
273
274 /* No newline.. reiserfs_info calls can be followed by printk's */
275 void reiserfs_info(struct super_block *sb, const char *fmt, ...)
276 {
277         do_reiserfs_warning(fmt);
278         if (sb)
279                 printk(KERN_NOTICE "REISERFS (device %s): %s",
280                        sb->s_id, error_buf);
281         else
282                 printk(KERN_NOTICE "REISERFS %s:", error_buf);
283 }
284
285 /* No newline.. reiserfs_printk calls can be followed by printk's */
286 static void reiserfs_printk(const char *fmt, ...)
287 {
288         do_reiserfs_warning(fmt);
289         printk(error_buf);
290 }
291
292 void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
293 {
294 #ifdef CONFIG_REISERFS_CHECK
295         do_reiserfs_warning(fmt);
296         if (s)
297                 printk(KERN_DEBUG "REISERFS debug (device %s): %s\n",
298                        s->s_id, error_buf);
299         else
300                 printk(KERN_DEBUG "REISERFS debug: %s\n", error_buf);
301 #endif
302 }
303
304 /* The format:
305
306            maintainer-errorid: [function-name:] message
307
308     where errorid is unique to the maintainer and function-name is
309     optional, is recommended, so that anyone can easily find the bug
310     with a simple grep for the short to type string
311     maintainer-errorid.  Don't bother with reusing errorids, there are
312     lots of numbers out there.
313
314     Example: 
315     
316     reiserfs_panic(
317         p_sb, "reiser-29: reiserfs_new_blocknrs: "
318         "one of search_start or rn(%d) is equal to MAX_B_NUM,"
319         "which means that we are optimizing location based on the bogus location of a temp buffer (%p).", 
320         rn, bh
321     );
322
323     Regular panic()s sometimes clear the screen before the message can
324     be read, thus the need for the while loop.  
325
326     Numbering scheme for panic used by Vladimir and Anatoly( Hans completely ignores this scheme, and considers it
327     pointless complexity):
328
329     panics in reiserfs_fs.h have numbers from 1000 to 1999
330     super.c                                     2000 to 2999
331     preserve.c (unused)                     3000 to 3999
332     bitmap.c                                4000 to 4999
333     stree.c                                     5000 to 5999
334     prints.c                                6000 to 6999
335     namei.c                     7000 to 7999
336     fix_nodes.c                 8000 to 8999
337     dir.c                       9000 to 9999
338         lbalance.c                                      10000 to 10999
339         ibalance.c              11000 to 11999 not ready
340         do_balan.c              12000 to 12999
341         inode.c                 13000 to 13999
342         file.c                  14000 to 14999
343     objectid.c                       15000 - 15999
344     buffer.c                         16000 - 16999
345     symlink.c                        17000 - 17999
346
347    .  */
348
349 #ifdef CONFIG_REISERFS_CHECK
350 extern struct tree_balance *cur_tb;
351 #endif
352
353 void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
354 {
355         do_reiserfs_warning(fmt);
356
357         dump_stack();
358
359         panic(KERN_EMERG "REISERFS: panic (device %s): %s\n",
360                reiserfs_bdevname(sb), error_buf);
361 }
362
363 void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
364 {
365         do_reiserfs_warning(fmt);
366
367         if (reiserfs_error_panic(sb)) {
368                 panic(KERN_CRIT "REISERFS panic (device %s): %s\n", sb->s_id,
369                       error_buf);
370         }
371
372         if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
373                 return;
374
375         printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
376                error_buf);
377
378         sb->s_flags |= MS_RDONLY;
379         reiserfs_journal_abort(sb, errno);
380 }
381
382 /* this prints internal nodes (4 keys/items in line) (dc_number,
383    dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
384    dc_size)...*/
385 static int print_internal(struct buffer_head *bh, int first, int last)
386 {
387         struct reiserfs_key *key;
388         struct disk_child *dc;
389         int i;
390         int from, to;
391
392         if (!B_IS_KEYS_LEVEL(bh))
393                 return 1;
394
395         check_internal(bh);
396
397         if (first == -1) {
398                 from = 0;
399                 to = B_NR_ITEMS(bh);
400         } else {
401                 from = first;
402                 to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
403         }
404
405         reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
406
407         dc = B_N_CHILD(bh, from);
408         reiserfs_printk("PTR %d: %y ", from, dc);
409
410         for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
411              i++, key++, dc++) {
412                 reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
413                 if (i && i % 4 == 0)
414                         printk("\n");
415         }
416         printk("\n");
417         return 0;
418 }
419
420 static int print_leaf(struct buffer_head *bh, int print_mode, int first,
421                       int last)
422 {
423         struct block_head *blkh;
424         struct item_head *ih;
425         int i, nr;
426         int from, to;
427
428         if (!B_IS_ITEMS_LEVEL(bh))
429                 return 1;
430
431         check_leaf(bh);
432
433         blkh = B_BLK_HEAD(bh);
434         ih = B_N_PITEM_HEAD(bh, 0);
435         nr = blkh_nr_item(blkh);
436
437         printk
438             ("\n===================================================================\n");
439         reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
440
441         if (!(print_mode & PRINT_LEAF_ITEMS)) {
442                 reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
443                                 &(ih->ih_key), &((ih + nr - 1)->ih_key));
444                 return 0;
445         }
446
447         if (first < 0 || first > nr - 1)
448                 from = 0;
449         else
450                 from = first;
451
452         if (last < 0 || last > nr)
453                 to = nr;
454         else
455                 to = last;
456
457         ih += from;
458         printk
459             ("-------------------------------------------------------------------------------\n");
460         printk
461             ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
462         for (i = from; i < to; i++, ih++) {
463                 printk
464                     ("-------------------------------------------------------------------------------\n");
465                 reiserfs_printk("|%2d| %h |\n", i, ih);
466                 if (print_mode & PRINT_LEAF_ITEMS)
467                         op_print_item(ih, B_I_PITEM(bh, ih));
468         }
469
470         printk
471             ("===================================================================\n");
472
473         return 0;
474 }
475
476 char *reiserfs_hashname(int code)
477 {
478         if (code == YURA_HASH)
479                 return "rupasov";
480         if (code == TEA_HASH)
481                 return "tea";
482         if (code == R5_HASH)
483                 return "r5";
484
485         return "unknown";
486 }
487
488 /* return 1 if this is not super block */
489 static int print_super_block(struct buffer_head *bh)
490 {
491         struct reiserfs_super_block *rs =
492             (struct reiserfs_super_block *)(bh->b_data);
493         int skipped, data_blocks;
494         char *version;
495         char b[BDEVNAME_SIZE];
496
497         if (is_reiserfs_3_5(rs)) {
498                 version = "3.5";
499         } else if (is_reiserfs_3_6(rs)) {
500                 version = "3.6";
501         } else if (is_reiserfs_jr(rs)) {
502                 version = ((sb_version(rs) == REISERFS_VERSION_2) ?
503                            "3.6" : "3.5");
504         } else {
505                 return 1;
506         }
507
508         printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
509                (unsigned long long)bh->b_blocknr);
510         printk("Reiserfs version %s\n", version);
511         printk("Block count %u\n", sb_block_count(rs));
512         printk("Blocksize %d\n", sb_blocksize(rs));
513         printk("Free blocks %u\n", sb_free_blocks(rs));
514         // FIXME: this would be confusing if
515         // someone stores reiserfs super block in some data block ;)
516 //    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
517         skipped = bh->b_blocknr;
518         data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
519             (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
520              1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
521         printk
522             ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
523              "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
524              (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
525               sb_reserved_for_journal(rs)), data_blocks);
526         printk("Root block %u\n", sb_root_block(rs));
527         printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
528         printk("Journal dev %d\n", sb_jp_journal_dev(rs));
529         printk("Journal orig size %d\n", sb_jp_journal_size(rs));
530         printk("FS state %d\n", sb_fs_state(rs));
531         printk("Hash function \"%s\"\n",
532                reiserfs_hashname(sb_hash_function_code(rs)));
533
534         printk("Tree height %d\n", sb_tree_height(rs));
535         return 0;
536 }
537
538 static int print_desc_block(struct buffer_head *bh)
539 {
540         struct reiserfs_journal_desc *desc;
541
542         if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
543                 return 1;
544
545         desc = (struct reiserfs_journal_desc *)(bh->b_data);
546         printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
547                (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
548                get_desc_mount_id(desc), get_desc_trans_len(desc));
549
550         return 0;
551 }
552
553 void print_block(struct buffer_head *bh, ...)   //int print_mode, int first, int last)
554 {
555         va_list args;
556         int mode, first, last;
557
558         va_start(args, bh);
559
560         if (!bh) {
561                 printk("print_block: buffer is NULL\n");
562                 return;
563         }
564
565         mode = va_arg(args, int);
566         first = va_arg(args, int);
567         last = va_arg(args, int);
568         if (print_leaf(bh, mode, first, last))
569                 if (print_internal(bh, first, last))
570                         if (print_super_block(bh))
571                                 if (print_desc_block(bh))
572                                         printk
573                                             ("Block %llu contains unformatted data\n",
574                                              (unsigned long long)bh->b_blocknr);
575
576         va_end(args);
577 }
578
579 static char print_tb_buf[2048];
580
581 /* this stores initial state of tree balance in the print_tb_buf */
582 void store_print_tb(struct tree_balance *tb)
583 {
584         int h = 0;
585         int i;
586         struct buffer_head *tbSh, *tbFh;
587
588         if (!tb)
589                 return;
590
591         sprintf(print_tb_buf, "\n"
592                 "BALANCING %d\n"
593                 "MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
594                 "=====================================================================\n"
595                 "* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
596                 REISERFS_SB(tb->tb_sb)->s_do_balance,
597                 tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
598                 tb->tb_path->pos_in_item);
599
600         for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
601                 if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
602                     tb->tb_path->path_length
603                     && PATH_H_PATH_OFFSET(tb->tb_path,
604                                           h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
605                         tbSh = PATH_H_PBUFFER(tb->tb_path, h);
606                         tbFh = PATH_H_PPARENT(tb->tb_path, h);
607                 } else {
608                         tbSh = NULL;
609                         tbFh = NULL;
610                 }
611                 sprintf(print_tb_buf + strlen(print_tb_buf),
612                         "* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
613                         h,
614                         (tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
615                         (tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
616                         (tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
617                         (tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
618                         (tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
619                         (tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
620                         (tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
621                         (tb->FL[h]) ? (long long)(tb->FL[h]->
622                                                   b_blocknr) : (-1LL),
623                         (tb->FR[h]) ? (long long)(tb->FR[h]->
624                                                   b_blocknr) : (-1LL),
625                         (tb->CFL[h]) ? (long long)(tb->CFL[h]->
626                                                    b_blocknr) : (-1LL),
627                         (tb->CFR[h]) ? (long long)(tb->CFR[h]->
628                                                    b_blocknr) : (-1LL));
629         }
630
631         sprintf(print_tb_buf + strlen(print_tb_buf),
632                 "=====================================================================\n"
633                 "* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
634                 "* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
635                 tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
636                 tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
637                 tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
638                 tb->rkey[0]);
639
640         /* this prints balance parameters for non-leaf levels */
641         h = 0;
642         do {
643                 h++;
644                 sprintf(print_tb_buf + strlen(print_tb_buf),
645                         "* %d * %4d * %2d *    * %2d *    * %2d *\n",
646                         h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
647                         tb->blknum[h]);
648         } while (tb->insert_size[h]);
649
650         sprintf(print_tb_buf + strlen(print_tb_buf),
651                 "=====================================================================\n"
652                 "FEB list: ");
653
654         /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
655         h = 0;
656         for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
657                 sprintf(print_tb_buf + strlen(print_tb_buf),
658                         "%p (%llu %d)%s", tb->FEB[i],
659                         tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
660                         b_blocknr : 0ULL,
661                         tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
662                         (i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
663
664         sprintf(print_tb_buf + strlen(print_tb_buf),
665                 "======================== the end ====================================\n");
666 }
667
668 void print_cur_tb(char *mes)
669 {
670         printk("%s\n%s", mes, print_tb_buf);
671 }
672
673 static void check_leaf_block_head(struct buffer_head *bh)
674 {
675         struct block_head *blkh;
676         int nr;
677
678         blkh = B_BLK_HEAD(bh);
679         nr = blkh_nr_item(blkh);
680         if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
681                 reiserfs_panic(NULL,
682                                "vs-6010: check_leaf_block_head: invalid item number %z",
683                                bh);
684         if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
685                 reiserfs_panic(NULL,
686                                "vs-6020: check_leaf_block_head: invalid free space %z",
687                                bh);
688
689 }
690
691 static void check_internal_block_head(struct buffer_head *bh)
692 {
693         struct block_head *blkh;
694
695         blkh = B_BLK_HEAD(bh);
696         if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
697                 reiserfs_panic(NULL,
698                                "vs-6025: check_internal_block_head: invalid level %z",
699                                bh);
700
701         if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
702                 reiserfs_panic(NULL,
703                                "vs-6030: check_internal_block_head: invalid item number %z",
704                                bh);
705
706         if (B_FREE_SPACE(bh) !=
707             bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
708             DC_SIZE * (B_NR_ITEMS(bh) + 1))
709                 reiserfs_panic(NULL,
710                                "vs-6040: check_internal_block_head: invalid free space %z",
711                                bh);
712
713 }
714
715 void check_leaf(struct buffer_head *bh)
716 {
717         int i;
718         struct item_head *ih;
719
720         if (!bh)
721                 return;
722         check_leaf_block_head(bh);
723         for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
724                 op_check_item(ih, B_I_PITEM(bh, ih));
725 }
726
727 void check_internal(struct buffer_head *bh)
728 {
729         if (!bh)
730                 return;
731         check_internal_block_head(bh);
732 }
733
734 void print_statistics(struct super_block *s)
735 {
736
737         /*
738            printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
739            bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
740            REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
741            REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
742            REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
743          */
744
745 }