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