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