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