prints.c revision 32e8b1062915d00d07d3b88a95174648e369b6a3
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
13static char error_buf[1024];
14static char fmt_buf[1024];
15static char off_buf[80];
16
17static 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
31static 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
48static 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
61static 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 */
79static 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 */
90static 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
100static 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
112static 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
125static 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
134static 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
140static 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
154static 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
160static 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*/
187static DEFINE_SPINLOCK(error_lock);
188static 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
264void __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 */
278void 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 */
289static void reiserfs_printk(const char *fmt, ...)
290{
291	do_reiserfs_warning(fmt);
292	printk(error_buf);
293}
294
295void 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
353extern struct tree_balance *cur_tb;
354#endif
355
356void __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
373void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
374{
375	do_reiserfs_warning(fmt);
376
377	if (reiserfs_error_panic(sb)) {
378		panic(KERN_CRIT "REISERFS panic (device %s): %s\n", sb->s_id,
379		      error_buf);
380	}
381
382	if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
383		return;
384
385	printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
386	       error_buf);
387
388	sb->s_flags |= MS_RDONLY;
389	reiserfs_abort_journal(sb, errno);
390}
391
392/* this prints internal nodes (4 keys/items in line) (dc_number,
393   dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
394   dc_size)...*/
395static int print_internal(struct buffer_head *bh, int first, int last)
396{
397	struct reiserfs_key *key;
398	struct disk_child *dc;
399	int i;
400	int from, to;
401
402	if (!B_IS_KEYS_LEVEL(bh))
403		return 1;
404
405	check_internal(bh);
406
407	if (first == -1) {
408		from = 0;
409		to = B_NR_ITEMS(bh);
410	} else {
411		from = first;
412		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
413	}
414
415	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
416
417	dc = B_N_CHILD(bh, from);
418	reiserfs_printk("PTR %d: %y ", from, dc);
419
420	for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
421	     i++, key++, dc++) {
422		reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
423		if (i && i % 4 == 0)
424			printk("\n");
425	}
426	printk("\n");
427	return 0;
428}
429
430static int print_leaf(struct buffer_head *bh, int print_mode, int first,
431		      int last)
432{
433	struct block_head *blkh;
434	struct item_head *ih;
435	int i, nr;
436	int from, to;
437
438	if (!B_IS_ITEMS_LEVEL(bh))
439		return 1;
440
441	check_leaf(bh);
442
443	blkh = B_BLK_HEAD(bh);
444	ih = B_N_PITEM_HEAD(bh, 0);
445	nr = blkh_nr_item(blkh);
446
447	printk
448	    ("\n===================================================================\n");
449	reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
450
451	if (!(print_mode & PRINT_LEAF_ITEMS)) {
452		reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
453				&(ih->ih_key), &((ih + nr - 1)->ih_key));
454		return 0;
455	}
456
457	if (first < 0 || first > nr - 1)
458		from = 0;
459	else
460		from = first;
461
462	if (last < 0 || last > nr)
463		to = nr;
464	else
465		to = last;
466
467	ih += from;
468	printk
469	    ("-------------------------------------------------------------------------------\n");
470	printk
471	    ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
472	for (i = from; i < to; i++, ih++) {
473		printk
474		    ("-------------------------------------------------------------------------------\n");
475		reiserfs_printk("|%2d| %h |\n", i, ih);
476		if (print_mode & PRINT_LEAF_ITEMS)
477			op_print_item(ih, B_I_PITEM(bh, ih));
478	}
479
480	printk
481	    ("===================================================================\n");
482
483	return 0;
484}
485
486char *reiserfs_hashname(int code)
487{
488	if (code == YURA_HASH)
489		return "rupasov";
490	if (code == TEA_HASH)
491		return "tea";
492	if (code == R5_HASH)
493		return "r5";
494
495	return "unknown";
496}
497
498/* return 1 if this is not super block */
499static int print_super_block(struct buffer_head *bh)
500{
501	struct reiserfs_super_block *rs =
502	    (struct reiserfs_super_block *)(bh->b_data);
503	int skipped, data_blocks;
504	char *version;
505	char b[BDEVNAME_SIZE];
506
507	if (is_reiserfs_3_5(rs)) {
508		version = "3.5";
509	} else if (is_reiserfs_3_6(rs)) {
510		version = "3.6";
511	} else if (is_reiserfs_jr(rs)) {
512		version = ((sb_version(rs) == REISERFS_VERSION_2) ?
513			   "3.6" : "3.5");
514	} else {
515		return 1;
516	}
517
518	printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
519	       (unsigned long long)bh->b_blocknr);
520	printk("Reiserfs version %s\n", version);
521	printk("Block count %u\n", sb_block_count(rs));
522	printk("Blocksize %d\n", sb_blocksize(rs));
523	printk("Free blocks %u\n", sb_free_blocks(rs));
524	// FIXME: this would be confusing if
525	// someone stores reiserfs super block in some data block ;)
526//    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
527	skipped = bh->b_blocknr;
528	data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
529	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
530	     1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
531	printk
532	    ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
533	     "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
534	     (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
535	      sb_reserved_for_journal(rs)), data_blocks);
536	printk("Root block %u\n", sb_root_block(rs));
537	printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
538	printk("Journal dev %d\n", sb_jp_journal_dev(rs));
539	printk("Journal orig size %d\n", sb_jp_journal_size(rs));
540	printk("FS state %d\n", sb_fs_state(rs));
541	printk("Hash function \"%s\"\n",
542	       reiserfs_hashname(sb_hash_function_code(rs)));
543
544	printk("Tree height %d\n", sb_tree_height(rs));
545	return 0;
546}
547
548static int print_desc_block(struct buffer_head *bh)
549{
550	struct reiserfs_journal_desc *desc;
551
552	if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
553		return 1;
554
555	desc = (struct reiserfs_journal_desc *)(bh->b_data);
556	printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
557	       (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
558	       get_desc_mount_id(desc), get_desc_trans_len(desc));
559
560	return 0;
561}
562
563void print_block(struct buffer_head *bh, ...)	//int print_mode, int first, int last)
564{
565	va_list args;
566	int mode, first, last;
567
568	va_start(args, bh);
569
570	if (!bh) {
571		printk("print_block: buffer is NULL\n");
572		return;
573	}
574
575	mode = va_arg(args, int);
576	first = va_arg(args, int);
577	last = va_arg(args, int);
578	if (print_leaf(bh, mode, first, last))
579		if (print_internal(bh, first, last))
580			if (print_super_block(bh))
581				if (print_desc_block(bh))
582					printk
583					    ("Block %llu contains unformatted data\n",
584					     (unsigned long long)bh->b_blocknr);
585
586	va_end(args);
587}
588
589static char print_tb_buf[2048];
590
591/* this stores initial state of tree balance in the print_tb_buf */
592void store_print_tb(struct tree_balance *tb)
593{
594	int h = 0;
595	int i;
596	struct buffer_head *tbSh, *tbFh;
597
598	if (!tb)
599		return;
600
601	sprintf(print_tb_buf, "\n"
602		"BALANCING %d\n"
603		"MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
604		"=====================================================================\n"
605		"* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
606		REISERFS_SB(tb->tb_sb)->s_do_balance,
607		tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
608		tb->tb_path->pos_in_item);
609
610	for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
611		if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
612		    tb->tb_path->path_length
613		    && PATH_H_PATH_OFFSET(tb->tb_path,
614					  h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
615			tbSh = PATH_H_PBUFFER(tb->tb_path, h);
616			tbFh = PATH_H_PPARENT(tb->tb_path, h);
617		} else {
618			tbSh = NULL;
619			tbFh = NULL;
620		}
621		sprintf(print_tb_buf + strlen(print_tb_buf),
622			"* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
623			h,
624			(tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
625			(tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
626			(tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
627			(tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
628			(tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
629			(tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
630			(tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
631			(tb->FL[h]) ? (long long)(tb->FL[h]->
632						  b_blocknr) : (-1LL),
633			(tb->FR[h]) ? (long long)(tb->FR[h]->
634						  b_blocknr) : (-1LL),
635			(tb->CFL[h]) ? (long long)(tb->CFL[h]->
636						   b_blocknr) : (-1LL),
637			(tb->CFR[h]) ? (long long)(tb->CFR[h]->
638						   b_blocknr) : (-1LL));
639	}
640
641	sprintf(print_tb_buf + strlen(print_tb_buf),
642		"=====================================================================\n"
643		"* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
644		"* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
645		tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
646		tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
647		tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
648		tb->rkey[0]);
649
650	/* this prints balance parameters for non-leaf levels */
651	h = 0;
652	do {
653		h++;
654		sprintf(print_tb_buf + strlen(print_tb_buf),
655			"* %d * %4d * %2d *    * %2d *    * %2d *\n",
656			h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
657			tb->blknum[h]);
658	} while (tb->insert_size[h]);
659
660	sprintf(print_tb_buf + strlen(print_tb_buf),
661		"=====================================================================\n"
662		"FEB list: ");
663
664	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
665	h = 0;
666	for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
667		sprintf(print_tb_buf + strlen(print_tb_buf),
668			"%p (%llu %d)%s", tb->FEB[i],
669			tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
670			b_blocknr : 0ULL,
671			tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
672			(i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
673
674	sprintf(print_tb_buf + strlen(print_tb_buf),
675		"======================== the end ====================================\n");
676}
677
678void print_cur_tb(char *mes)
679{
680	printk("%s\n%s", mes, print_tb_buf);
681}
682
683static void check_leaf_block_head(struct buffer_head *bh)
684{
685	struct block_head *blkh;
686	int nr;
687
688	blkh = B_BLK_HEAD(bh);
689	nr = blkh_nr_item(blkh);
690	if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
691		reiserfs_panic(NULL, "vs-6010", "invalid item number %z",
692			       bh);
693	if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
694		reiserfs_panic(NULL, "vs-6020", "invalid free space %z",
695			       bh);
696
697}
698
699static void check_internal_block_head(struct buffer_head *bh)
700{
701	struct block_head *blkh;
702
703	blkh = B_BLK_HEAD(bh);
704	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
705		reiserfs_panic(NULL, "vs-6025", "invalid level %z", bh);
706
707	if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
708		reiserfs_panic(NULL, "vs-6030", "invalid item number %z", 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, "vs-6040", "invalid free space %z", bh);
714
715}
716
717void check_leaf(struct buffer_head *bh)
718{
719	int i;
720	struct item_head *ih;
721
722	if (!bh)
723		return;
724	check_leaf_block_head(bh);
725	for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
726		op_check_item(ih, B_I_PITEM(bh, ih));
727}
728
729void check_internal(struct buffer_head *bh)
730{
731	if (!bh)
732		return;
733	check_internal_block_head(bh);
734}
735
736void print_statistics(struct super_block *s)
737{
738
739	/*
740	   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
741	   bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
742	   REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
743	   REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
744	   REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
745	 */
746
747}
748