patch-2_6_7-vs1_9_1_12
[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
19 static char * reiserfs_cpu_offset (struct cpu_key * key)
20 {
21   if (cpu_key_k_type(key) == TYPE_DIRENTRY)
22     sprintf (off_buf, "%Lu(%Lu)", 
23              (unsigned long long)GET_HASH_VALUE (cpu_key_k_offset (key)),
24              (unsigned long long)GET_GENERATION_NUMBER (cpu_key_k_offset (key)));
25   else
26     sprintf (off_buf, "0x%Lx", (unsigned long long)cpu_key_k_offset (key));
27   return off_buf;
28 }
29
30
31 static char * le_offset (struct 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)GET_HASH_VALUE (le_key_k_offset (version, key)),
39              (unsigned long long)GET_GENERATION_NUMBER (le_key_k_offset (version, key)));
40   else
41     sprintf (off_buf, "0x%Lx", (unsigned long long)le_key_k_offset (version, key));
42   return off_buf;
43 }
44
45
46 static char * cpu_type (struct cpu_key * key)
47 {
48     if (cpu_key_k_type (key) == TYPE_STAT_DATA)
49         return "SD";
50     if (cpu_key_k_type (key) == TYPE_DIRENTRY)
51         return "DIR";
52     if (cpu_key_k_type (key) == TYPE_DIRECT)
53         return "DIRECT";
54     if (cpu_key_k_type (key) == TYPE_INDIRECT)
55         return "IND";
56     return "UNKNOWN";
57 }
58
59
60 static char * le_type (struct key * key)
61 {
62     int version;
63     
64     version = le_key_version (key);
65
66     if (le_key_k_type (version, key) == TYPE_STAT_DATA)
67         return "SD";
68     if (le_key_k_type (version, key) == TYPE_DIRENTRY)
69         return "DIR";
70     if (le_key_k_type (version, key) == TYPE_DIRECT)
71         return "DIRECT";
72     if (le_key_k_type (version, key) == TYPE_INDIRECT)
73         return "IND";
74     return "UNKNOWN";
75 }
76
77
78 /* %k */
79 static void sprintf_le_key (char * buf, struct 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), le_type (key));
84   else
85     sprintf (buf, "[NULL]");
86 }
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, "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", deh_offset(deh), deh_dir_id(deh),
104                  deh_objectid(deh), deh_location(deh), deh_state(deh) );
105     else
106         sprintf( buf, "[NULL]" );
107
108 }
109
110 static void sprintf_item_head (char * buf, struct item_head * ih)
111 {
112     if (ih) {
113         strcpy (buf, (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
114         sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
115         sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
116                  "free_space(entry_count) %d",
117                  ih_item_len(ih), ih_location(ih), ih_free_space (ih));
118     } else
119         sprintf (buf, "[NULL]");
120 }
121
122
123 static void sprintf_direntry (char * buf, struct reiserfs_dir_entry * de)
124 {
125   char name[20];
126
127   memcpy (name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
128   name [de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
129   sprintf (buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
130 }
131
132
133 static void sprintf_block_head (char * buf, struct buffer_head * bh)
134 {
135   sprintf (buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
136            B_LEVEL (bh), B_NR_ITEMS (bh), B_FREE_SPACE (bh));
137 }
138
139
140 static void sprintf_buffer_head (char * buf, struct buffer_head * bh) 
141 {
142   char b[BDEVNAME_SIZE];
143
144   sprintf (buf, "dev %s, size %d, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
145            bdevname (bh->b_bdev, b), bh->b_size,
146            (unsigned long long)bh->b_blocknr,
147            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
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), dc_size(dc));
158 }
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   {
169     if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
170               k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' ) {
171       *what = k[1];
172       break;
173     }
174     (*skip) ++;
175     k ++;
176   }
177   return k;
178 }
179
180
181 /* debugging reiserfs we used to print out a lot of different
182    variables, like keys, item headers, buffer heads etc. Values of
183    most fields matter. So it took a long time just to write
184    appropriative printk. With this reiserfs_warning you can use format
185    specification for complex structures like you used to do with
186    printfs for integers, doubles and pointers. For instance, to print
187    out key structure you have to write just: 
188    reiserfs_warning ("bad key %k", key); 
189    instead of 
190    printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid, 
191            key->k_offset, key->k_uniqueness); 
192 */
193
194
195 static void
196 prepare_error_buf( const char *fmt, va_list args )
197 {
198     char * fmt1 = fmt_buf;
199     char * k;
200     char * p = error_buf;
201     int i, j, what, skip;
202
203     strcpy (fmt1, fmt);
204
205     while( (k = is_there_reiserfs_struct( fmt1, &what, &skip )) != NULL )
206     {
207         *k = 0;
208
209         p += vsprintf (p, fmt1, args);
210
211         for (i = 0; i < skip; i ++)
212             j = va_arg (args, int);
213
214         switch (what) {
215         case 'k':
216             sprintf_le_key (p, va_arg(args, struct key *));
217             break;
218         case 'K':
219             sprintf_cpu_key (p, va_arg(args, struct cpu_key *));
220             break;
221         case 'h':
222             sprintf_item_head (p, va_arg(args, struct item_head *));
223             break;
224         case 't':
225             sprintf_direntry (p, va_arg(args, struct reiserfs_dir_entry *));
226             break;
227         case 'y':
228             sprintf_disk_child (p, va_arg(args, struct disk_child *));
229             break;
230         case 'z':
231             sprintf_block_head (p, va_arg(args, struct buffer_head *));
232             break;
233         case 'b':
234             sprintf_buffer_head (p, va_arg(args, struct buffer_head *));
235             break;
236         case 'a':
237             sprintf_de_head (p, va_arg(args, struct reiserfs_de_head *));
238             break;
239         }
240
241         p += strlen (p);
242         fmt1 = k + 2;
243     }
244     vsprintf (p, fmt1, args);
245
246 }
247
248
249 /* in addition to usual conversion specifiers this accepts reiserfs
250    specific conversion specifiers: 
251    %k to print little endian key, 
252    %K to print cpu key, 
253    %h to print item_head,
254    %t to print directory entry 
255    %z to print block head (arg must be struct buffer_head *
256    %b to print buffer_head
257 */
258
259 #define do_reiserfs_warning(fmt)\
260 {\
261     va_list args;\
262     va_start( args, fmt );\
263     prepare_error_buf( fmt, args );\
264     va_end( args );\
265 }
266
267 void reiserfs_warning (struct super_block *sb, const char * fmt, ...)
268 {
269   do_reiserfs_warning(fmt);
270   if (sb)
271       printk (KERN_WARNING "ReiserFS: %s: warning: %s\n",
272              reiserfs_bdevname (sb), error_buf);
273   else
274       printk (KERN_WARNING "ReiserFS: warning: %s\n", 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: %s: %s",
283              reiserfs_bdevname (sb), 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 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: %s: %s\n",
301              reiserfs_bdevname (s), error_buf);
302   else
303       printk (KERN_DEBUG "ReiserFS: %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
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
370 void print_virtual_node (struct virtual_node * vn)
371 {
372     int i;
373     struct virtual_item * vi;
374
375     printk ("VIRTUAL NODE CONTAINS %d items, has size %d,%s,%s, ITEM_POS=%d POS_IN_ITEM=%d MODE=\'%c\'\n",
376             vn->vn_nr_item, vn->vn_size,
377             (vn->vn_vi[0].vi_type & VI_TYPE_LEFT_MERGEABLE )? "left mergeable" : "", 
378             (vn->vn_vi[vn->vn_nr_item - 1].vi_type & VI_TYPE_RIGHT_MERGEABLE) ? "right mergeable" : "",
379             vn->vn_affected_item_num, vn->vn_pos_in_item, vn->vn_mode);
380     
381     vi = vn->vn_vi;
382     for (i = 0; i < vn->vn_nr_item; i ++, vi ++)
383         op_print_vi (vi);
384         
385 }
386
387
388 void print_path (struct tree_balance * tb, struct path * path)
389 {
390     int h = 0;
391     struct buffer_head * bh;
392     
393     if (tb) {
394         while (tb->insert_size[h]) {
395             bh = PATH_H_PBUFFER (path, h);
396             printk ("block %llu (level=%d), position %d\n", bh ? (unsigned long long)bh->b_blocknr : 0LL,
397                     bh ? B_LEVEL (bh) : 0, PATH_H_POSITION (path, h));
398             h ++;
399         }
400   } else {
401       int offset = path->path_length;
402       struct buffer_head * bh;
403       printk ("Offset    Bh     (b_blocknr, b_count) Position Nr_item\n");
404       while ( offset > ILLEGAL_PATH_ELEMENT_OFFSET ) {
405           bh = PATH_OFFSET_PBUFFER (path, offset);
406           printk ("%6d %10p (%9llu, %7d) %8d %7d\n", offset, 
407                   bh, bh ? (unsigned long long)bh->b_blocknr : 0LL, bh ? atomic_read (&(bh->b_count)) : 0,
408                   PATH_OFFSET_POSITION (path, offset), bh ? B_NR_ITEMS (bh) : -1);
409           
410           offset --;
411       }
412   }
413
414 }
415
416
417 /* this prints internal nodes (4 keys/items in line) (dc_number,
418    dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
419    dc_size)...*/
420 static int print_internal (struct buffer_head * bh, int first, int last)
421 {
422     struct key * key;
423     struct disk_child * dc;
424     int i;
425     int from, to;
426     
427     if (!B_IS_KEYS_LEVEL (bh))
428         return 1;
429
430     check_internal (bh);
431     
432     if (first == -1) {
433         from = 0;
434         to = B_NR_ITEMS (bh);
435     } else {
436         from = first;
437         to = last < B_NR_ITEMS (bh) ? last : B_NR_ITEMS (bh);
438     }
439
440     reiserfs_printk ("INTERNAL NODE (%ld) contains %z\n",  bh->b_blocknr, bh);
441     
442     dc = B_N_CHILD (bh, from);
443     reiserfs_printk ("PTR %d: %y ", from, dc);
444     
445     for (i = from, key = B_N_PDELIM_KEY (bh, from), dc ++; i < to; i ++, key ++, dc ++) {
446         reiserfs_printk ("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
447         if (i && i % 4 == 0)
448             printk ("\n");
449     }
450     printk ("\n");
451     return 0;
452 }
453
454
455
456
457
458 static int print_leaf (struct buffer_head * bh, int print_mode, int first, int last)
459 {
460     struct block_head * blkh;
461     struct item_head * ih;
462     int i, nr;
463     int from, to;
464
465     if (!B_IS_ITEMS_LEVEL (bh))
466         return 1;
467
468     check_leaf (bh);
469
470     blkh = B_BLK_HEAD (bh);
471     ih = B_N_PITEM_HEAD (bh,0);
472     nr = blkh_nr_item(blkh);
473
474     printk ("\n===================================================================\n");
475     reiserfs_printk ("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
476
477     if (!(print_mode & PRINT_LEAF_ITEMS)) {
478         reiserfs_printk ("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
479                           &(ih->ih_key), &((ih + nr - 1)->ih_key));
480         return 0;
481     }
482
483     if (first < 0 || first > nr - 1) 
484         from = 0;
485     else 
486         from = first;
487
488     if (last < 0 || last > nr )
489         to = nr;
490     else
491         to = last;
492
493     ih += from;
494     printk ("-------------------------------------------------------------------------------\n");
495     printk ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
496     for (i = from; i < to; i++, ih ++) {
497         printk ("-------------------------------------------------------------------------------\n");
498         reiserfs_printk ("|%2d| %h |\n", i, ih);
499         if (print_mode & PRINT_LEAF_ITEMS)
500             op_print_item (ih, B_I_PITEM (bh, ih));
501     }
502
503     printk ("===================================================================\n");
504
505     return 0;
506 }
507
508 char * reiserfs_hashname(int code)
509 {
510     if ( code == YURA_HASH)
511         return "rupasov";
512     if ( code == TEA_HASH)
513         return "tea";
514     if ( code == R5_HASH)
515         return "r5";
516
517     return "unknown";
518 }
519
520 /* return 1 if this is not super block */
521 static int print_super_block (struct buffer_head * bh)
522 {
523     struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data);
524     int skipped, data_blocks;
525     char *version;
526     char b[BDEVNAME_SIZE];
527
528     if (is_reiserfs_3_5(rs)) {
529         version = "3.5";
530     } else if (is_reiserfs_3_6(rs)) {
531         version = "3.6";
532     } else if (is_reiserfs_jr(rs)) {
533       version = ((sb_version(rs) == REISERFS_VERSION_2) ?
534                  "3.6" : "3.5");  
535     } else {
536         return 1;
537     }
538
539     printk ("%s\'s super block is in block %llu\n", bdevname (bh->b_bdev, b),
540             (unsigned long long)bh->b_blocknr);
541     printk ("Reiserfs version %s\n", version );
542     printk ("Block count %u\n", sb_block_count(rs));
543     printk ("Blocksize %d\n", sb_blocksize(rs));
544     printk ("Free blocks %u\n", sb_free_blocks(rs));
545     // FIXME: this would be confusing if
546     // someone stores reiserfs super block in some data block ;)
547 //    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
548     skipped = bh->b_blocknr;
549     data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
550             (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) + 1 : sb_reserved_for_journal(rs)) -      
551             sb_free_blocks(rs);
552     printk ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
553             "1 super block, %d data blocks\n", 
554             skipped, sb_bmap_nr(rs), (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
555                                       sb_reserved_for_journal(rs)) , data_blocks);
556     printk ("Root block %u\n", sb_root_block(rs));
557     printk ("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
558     printk ("Journal dev %d\n", sb_jp_journal_dev(rs));
559     printk ("Journal orig size %d\n", sb_jp_journal_size(rs));
560     printk ("FS state %d\n", sb_fs_state(rs));
561     printk ("Hash function \"%s\"\n",
562             reiserfs_hashname(sb_hash_function_code(rs)));
563     
564     printk ("Tree height %d\n", sb_tree_height(rs));
565     return 0;
566 }
567
568 static int print_desc_block (struct buffer_head * bh)
569 {
570     struct reiserfs_journal_desc * desc;
571
572     if (memcmp(get_journal_desc_magic (bh), JOURNAL_DESC_MAGIC, 8))
573         return 1;
574
575     desc = (struct reiserfs_journal_desc *)(bh->b_data);
576     printk ("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
577             (unsigned long long)bh->b_blocknr, get_desc_trans_id (desc), get_desc_mount_id (desc),
578             get_desc_trans_len (desc));
579
580     return 0;
581 }
582
583
584 void print_block (struct buffer_head * bh, ...)//int print_mode, int first, int last)
585 {
586     va_list args;
587     int mode, first, last;
588
589     va_start (args, bh);
590
591     if ( ! bh ) {
592         printk("print_block: buffer is NULL\n");
593         return;
594     }
595
596     mode = va_arg (args, int);
597     first = va_arg (args, int);
598     last = va_arg (args, int);
599     if (print_leaf (bh, mode, first, last))
600         if (print_internal (bh, first, last))
601             if (print_super_block (bh))
602                 if (print_desc_block (bh))
603                     printk ("Block %llu contains unformatted data\n", (unsigned long long)bh->b_blocknr);
604 }
605
606
607
608 char print_tb_buf[2048];
609
610 /* this stores initial state of tree balance in the print_tb_buf */
611 void store_print_tb (struct tree_balance * tb)
612 {
613     int h = 0;
614     int i;
615     struct buffer_head * tbSh, * tbFh;
616
617     if (!tb)
618         return;
619
620     sprintf (print_tb_buf, "\n"
621              "BALANCING %d\n"
622              "MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n" 
623              "=====================================================================\n"
624              "* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
625              REISERFS_SB(tb->tb_sb)->s_do_balance,
626              tb->tb_mode, PATH_LAST_POSITION (tb->tb_path), tb->tb_path->pos_in_item);
627   
628     for (h = 0; h < sizeof(tb->insert_size) / sizeof (tb->insert_size[0]); h ++) {
629         if (PATH_H_PATH_OFFSET (tb->tb_path, h) <= tb->tb_path->path_length && 
630             PATH_H_PATH_OFFSET (tb->tb_path, h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
631             tbSh = PATH_H_PBUFFER (tb->tb_path, h);
632             tbFh = PATH_H_PPARENT (tb->tb_path, h);
633         } else {
634             tbSh = 0;
635             tbFh = 0;
636         }
637         sprintf (print_tb_buf + strlen (print_tb_buf),
638                  "* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
639                  h, 
640                  (tbSh) ? (long long)(tbSh->b_blocknr):(-1LL),
641                  (tbSh) ? atomic_read (&(tbSh->b_count)) : -1,
642                  (tb->L[h]) ? (long long)(tb->L[h]->b_blocknr):(-1LL),
643                  (tb->L[h]) ? atomic_read (&(tb->L[h]->b_count)) : -1,
644                  (tb->R[h]) ? (long long)(tb->R[h]->b_blocknr):(-1LL),
645                  (tb->R[h]) ? atomic_read (&(tb->R[h]->b_count)) : -1,
646                  (tbFh) ? (long long)(tbFh->b_blocknr):(-1LL),
647                  (tb->FL[h]) ? (long long)(tb->FL[h]->b_blocknr):(-1LL),
648                  (tb->FR[h]) ? (long long)(tb->FR[h]->b_blocknr):(-1LL),
649                  (tb->CFL[h]) ? (long long)(tb->CFL[h]->b_blocknr):(-1LL),
650                  (tb->CFR[h]) ? (long long)(tb->CFR[h]->b_blocknr):(-1LL));
651     }
652
653     sprintf (print_tb_buf + strlen (print_tb_buf), 
654              "=====================================================================\n"
655              "* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
656              "* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
657              tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],tb->rbytes, tb->blknum[0], 
658              tb->s0num, tb->s1num,tb->s1bytes,  tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0], tb->rkey[0]);
659
660     /* this prints balance parameters for non-leaf levels */
661     h = 0;
662     do {
663         h++;
664         sprintf (print_tb_buf + strlen (print_tb_buf),
665                  "* %d * %4d * %2d *    * %2d *    * %2d *\n",
666                 h, tb->insert_size[h], tb->lnum[h], tb->rnum[h], tb->blknum[h]);
667     } while (tb->insert_size[h]);
668
669     sprintf (print_tb_buf + strlen (print_tb_buf), 
670              "=====================================================================\n"
671              "FEB list: ");
672
673     /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
674     h = 0;
675     for (i = 0; i < sizeof (tb->FEB) / sizeof (tb->FEB[0]); i ++)
676         sprintf (print_tb_buf + strlen (print_tb_buf),
677                  "%p (%llu %d)%s", tb->FEB[i], tb->FEB[i] ? (unsigned long long)tb->FEB[i]->b_blocknr : 0ULL,
678                  tb->FEB[i] ? atomic_read (&(tb->FEB[i]->b_count)) : 0, 
679                  (i == sizeof (tb->FEB) / sizeof (tb->FEB[0]) - 1) ? "\n" : ", ");
680
681     sprintf (print_tb_buf + strlen (print_tb_buf), 
682              "======================== the end ====================================\n");
683 }
684
685 void print_cur_tb (char * mes)
686 {
687     printk ("%s\n%s", mes, print_tb_buf);
688 }
689
690 static void check_leaf_block_head (struct buffer_head * bh)
691 {
692   struct block_head * blkh;
693   int nr;
694
695   blkh = B_BLK_HEAD (bh);
696   nr = blkh_nr_item(blkh);
697   if ( nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
698     reiserfs_panic (0, "vs-6010: check_leaf_block_head: invalid item number %z", bh);
699   if ( blkh_free_space(blkh) > 
700       bh->b_size - BLKH_SIZE - IH_SIZE * nr )
701     reiserfs_panic (0, "vs-6020: check_leaf_block_head: invalid free space %z", bh);
702     
703 }
704
705 static void check_internal_block_head (struct buffer_head * bh)
706 {
707     struct block_head * blkh;
708     
709     blkh = B_BLK_HEAD (bh);
710     if (!(B_LEVEL (bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL (bh) <= MAX_HEIGHT))
711         reiserfs_panic (0, "vs-6025: check_internal_block_head: invalid level %z", bh);
712
713     if (B_NR_ITEMS (bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
714         reiserfs_panic (0, "vs-6030: check_internal_block_head: invalid item number %z", bh);
715
716     if (B_FREE_SPACE (bh) != 
717         bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS (bh) - DC_SIZE * (B_NR_ITEMS (bh) + 1))
718         reiserfs_panic (0, "vs-6040: check_internal_block_head: invalid free space %z", bh);
719
720 }
721
722
723 void check_leaf (struct buffer_head * bh)
724 {
725     int i;
726     struct item_head * ih;
727
728     if (!bh)
729         return;
730     check_leaf_block_head (bh);
731     for (i = 0, ih = B_N_PITEM_HEAD (bh, 0); i < B_NR_ITEMS (bh); i ++, ih ++)
732         op_check_item (ih, B_I_PITEM (bh, ih));
733 }
734
735
736 void check_internal (struct buffer_head * bh)
737 {
738   if (!bh)
739     return;
740   check_internal_block_head (bh);
741 }
742
743
744 void print_statistics (struct super_block * s)
745 {
746
747   /*
748   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
749 bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
750           REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
751           REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
752           REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
753   */
754
755 }