prints.c revision 8e186e454e871678c01b7eec4da5865111076095
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, int *skip)
161{
162	char *k = fmt;
163
164	*skip = 0;
165
166	while ((k = strchr(k, '%')) != NULL) {
167		if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
168		    k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
169			*what = k[1];
170			break;
171		}
172		(*skip)++;
173		k++;
174	}
175	return k;
176}
177
178/* debugging reiserfs we used to print out a lot of different
179   variables, like keys, item headers, buffer heads etc. Values of
180   most fields matter. So it took a long time just to write
181   appropriative printk. With this reiserfs_warning you can use format
182   specification for complex structures like you used to do with
183   printfs for integers, doubles and pointers. For instance, to print
184   out key structure you have to write just:
185   reiserfs_warning ("bad key %k", key);
186   instead of
187   printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid,
188           key->k_offset, key->k_uniqueness);
189*/
190
191static void prepare_error_buf(const char *fmt, va_list args)
192{
193	char *fmt1 = fmt_buf;
194	char *k;
195	char *p = error_buf;
196	int i, j, what, skip;
197
198	strcpy(fmt1, fmt);
199
200	while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) {
201		*k = 0;
202
203		p += vsprintf(p, fmt1, args);
204
205		for (i = 0; i < skip; i++)
206			j = va_arg(args, int);
207
208		switch (what) {
209		case 'k':
210			sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
211			break;
212		case 'K':
213			sprintf_cpu_key(p, va_arg(args, struct cpu_key *));
214			break;
215		case 'h':
216			sprintf_item_head(p, va_arg(args, struct item_head *));
217			break;
218		case 't':
219			sprintf_direntry(p,
220					 va_arg(args,
221						struct reiserfs_dir_entry *));
222			break;
223		case 'y':
224			sprintf_disk_child(p,
225					   va_arg(args, struct disk_child *));
226			break;
227		case 'z':
228			sprintf_block_head(p,
229					   va_arg(args, struct buffer_head *));
230			break;
231		case 'b':
232			sprintf_buffer_head(p,
233					    va_arg(args, struct buffer_head *));
234			break;
235		case 'a':
236			sprintf_de_head(p,
237					va_arg(args,
238					       struct reiserfs_de_head *));
239			break;
240		}
241
242		p += strlen(p);
243		fmt1 = k + 2;
244	}
245	vsprintf(p, fmt1, args);
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
267void 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 */
278void 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 */
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: %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#ifdef CONFIG_REISERFS_CHECK
353extern struct tree_balance *cur_tb;
354#endif
355
356void reiserfs_panic(struct super_block *sb, const char *fmt, ...)
357{
358	do_reiserfs_warning(fmt);
359
360	dump_stack();
361
362	panic(KERN_EMERG "REISERFS: panic (device %s): %s\n",
363	       reiserfs_bdevname(sb), error_buf);
364}
365
366void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
367{
368	do_reiserfs_warning(fmt);
369
370	if (reiserfs_error_panic(sb)) {
371		panic(KERN_CRIT "REISERFS: panic (device %s): %s\n",
372		      reiserfs_bdevname(sb), error_buf);
373	}
374
375	if (sb->s_flags & MS_RDONLY)
376		return;
377
378	printk(KERN_CRIT "REISERFS: abort (device %s): %s\n",
379	       reiserfs_bdevname(sb), error_buf);
380
381	sb->s_flags |= MS_RDONLY;
382	reiserfs_journal_abort(sb, errno);
383}
384
385/* this prints internal nodes (4 keys/items in line) (dc_number,
386   dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
387   dc_size)...*/
388static int print_internal(struct buffer_head *bh, int first, int last)
389{
390	struct reiserfs_key *key;
391	struct disk_child *dc;
392	int i;
393	int from, to;
394
395	if (!B_IS_KEYS_LEVEL(bh))
396		return 1;
397
398	check_internal(bh);
399
400	if (first == -1) {
401		from = 0;
402		to = B_NR_ITEMS(bh);
403	} else {
404		from = first;
405		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
406	}
407
408	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
409
410	dc = B_N_CHILD(bh, from);
411	reiserfs_printk("PTR %d: %y ", from, dc);
412
413	for (i = from, key = B_N_PDELIM_KEY(bh, from), dc++; i < to;
414	     i++, key++, dc++) {
415		reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
416		if (i && i % 4 == 0)
417			printk("\n");
418	}
419	printk("\n");
420	return 0;
421}
422
423static int print_leaf(struct buffer_head *bh, int print_mode, int first,
424		      int last)
425{
426	struct block_head *blkh;
427	struct item_head *ih;
428	int i, nr;
429	int from, to;
430
431	if (!B_IS_ITEMS_LEVEL(bh))
432		return 1;
433
434	check_leaf(bh);
435
436	blkh = B_BLK_HEAD(bh);
437	ih = B_N_PITEM_HEAD(bh, 0);
438	nr = blkh_nr_item(blkh);
439
440	printk
441	    ("\n===================================================================\n");
442	reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
443
444	if (!(print_mode & PRINT_LEAF_ITEMS)) {
445		reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
446				&(ih->ih_key), &((ih + nr - 1)->ih_key));
447		return 0;
448	}
449
450	if (first < 0 || first > nr - 1)
451		from = 0;
452	else
453		from = first;
454
455	if (last < 0 || last > nr)
456		to = nr;
457	else
458		to = last;
459
460	ih += from;
461	printk
462	    ("-------------------------------------------------------------------------------\n");
463	printk
464	    ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
465	for (i = from; i < to; i++, ih++) {
466		printk
467		    ("-------------------------------------------------------------------------------\n");
468		reiserfs_printk("|%2d| %h |\n", i, ih);
469		if (print_mode & PRINT_LEAF_ITEMS)
470			op_print_item(ih, B_I_PITEM(bh, ih));
471	}
472
473	printk
474	    ("===================================================================\n");
475
476	return 0;
477}
478
479char *reiserfs_hashname(int code)
480{
481	if (code == YURA_HASH)
482		return "rupasov";
483	if (code == TEA_HASH)
484		return "tea";
485	if (code == R5_HASH)
486		return "r5";
487
488	return "unknown";
489}
490
491/* return 1 if this is not super block */
492static int print_super_block(struct buffer_head *bh)
493{
494	struct reiserfs_super_block *rs =
495	    (struct reiserfs_super_block *)(bh->b_data);
496	int skipped, data_blocks;
497	char *version;
498	char b[BDEVNAME_SIZE];
499
500	if (is_reiserfs_3_5(rs)) {
501		version = "3.5";
502	} else if (is_reiserfs_3_6(rs)) {
503		version = "3.6";
504	} else if (is_reiserfs_jr(rs)) {
505		version = ((sb_version(rs) == REISERFS_VERSION_2) ?
506			   "3.6" : "3.5");
507	} else {
508		return 1;
509	}
510
511	printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b),
512	       (unsigned long long)bh->b_blocknr);
513	printk("Reiserfs version %s\n", version);
514	printk("Block count %u\n", sb_block_count(rs));
515	printk("Blocksize %d\n", sb_blocksize(rs));
516	printk("Free blocks %u\n", sb_free_blocks(rs));
517	// FIXME: this would be confusing if
518	// someone stores reiserfs super block in some data block ;)
519//    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
520	skipped = bh->b_blocknr;
521	data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
522	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
523	     1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
524	printk
525	    ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
526	     "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
527	     (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
528	      sb_reserved_for_journal(rs)), data_blocks);
529	printk("Root block %u\n", sb_root_block(rs));
530	printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
531	printk("Journal dev %d\n", sb_jp_journal_dev(rs));
532	printk("Journal orig size %d\n", sb_jp_journal_size(rs));
533	printk("FS state %d\n", sb_fs_state(rs));
534	printk("Hash function \"%s\"\n",
535	       reiserfs_hashname(sb_hash_function_code(rs)));
536
537	printk("Tree height %d\n", sb_tree_height(rs));
538	return 0;
539}
540
541static int print_desc_block(struct buffer_head *bh)
542{
543	struct reiserfs_journal_desc *desc;
544
545	if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
546		return 1;
547
548	desc = (struct reiserfs_journal_desc *)(bh->b_data);
549	printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
550	       (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
551	       get_desc_mount_id(desc), get_desc_trans_len(desc));
552
553	return 0;
554}
555
556void print_block(struct buffer_head *bh, ...)	//int print_mode, int first, int last)
557{
558	va_list args;
559	int mode, first, last;
560
561	va_start(args, bh);
562
563	if (!bh) {
564		printk("print_block: buffer is NULL\n");
565		return;
566	}
567
568	mode = va_arg(args, int);
569	first = va_arg(args, int);
570	last = va_arg(args, int);
571	if (print_leaf(bh, mode, first, last))
572		if (print_internal(bh, first, last))
573			if (print_super_block(bh))
574				if (print_desc_block(bh))
575					printk
576					    ("Block %llu contains unformatted data\n",
577					     (unsigned long long)bh->b_blocknr);
578}
579
580static char print_tb_buf[2048];
581
582/* this stores initial state of tree balance in the print_tb_buf */
583void store_print_tb(struct tree_balance *tb)
584{
585	int h = 0;
586	int i;
587	struct buffer_head *tbSh, *tbFh;
588
589	if (!tb)
590		return;
591
592	sprintf(print_tb_buf, "\n"
593		"BALANCING %d\n"
594		"MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
595		"=====================================================================\n"
596		"* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
597		REISERFS_SB(tb->tb_sb)->s_do_balance,
598		tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
599		tb->tb_path->pos_in_item);
600
601	for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
602		if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
603		    tb->tb_path->path_length
604		    && PATH_H_PATH_OFFSET(tb->tb_path,
605					  h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
606			tbSh = PATH_H_PBUFFER(tb->tb_path, h);
607			tbFh = PATH_H_PPARENT(tb->tb_path, h);
608		} else {
609			tbSh = NULL;
610			tbFh = NULL;
611		}
612		sprintf(print_tb_buf + strlen(print_tb_buf),
613			"* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
614			h,
615			(tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
616			(tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
617			(tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
618			(tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
619			(tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
620			(tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
621			(tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
622			(tb->FL[h]) ? (long long)(tb->FL[h]->
623						  b_blocknr) : (-1LL),
624			(tb->FR[h]) ? (long long)(tb->FR[h]->
625						  b_blocknr) : (-1LL),
626			(tb->CFL[h]) ? (long long)(tb->CFL[h]->
627						   b_blocknr) : (-1LL),
628			(tb->CFR[h]) ? (long long)(tb->CFR[h]->
629						   b_blocknr) : (-1LL));
630	}
631
632	sprintf(print_tb_buf + strlen(print_tb_buf),
633		"=====================================================================\n"
634		"* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
635		"* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
636		tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
637		tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
638		tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
639		tb->rkey[0]);
640
641	/* this prints balance parameters for non-leaf levels */
642	h = 0;
643	do {
644		h++;
645		sprintf(print_tb_buf + strlen(print_tb_buf),
646			"* %d * %4d * %2d *    * %2d *    * %2d *\n",
647			h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
648			tb->blknum[h]);
649	} while (tb->insert_size[h]);
650
651	sprintf(print_tb_buf + strlen(print_tb_buf),
652		"=====================================================================\n"
653		"FEB list: ");
654
655	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
656	h = 0;
657	for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
658		sprintf(print_tb_buf + strlen(print_tb_buf),
659			"%p (%llu %d)%s", tb->FEB[i],
660			tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
661			b_blocknr : 0ULL,
662			tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
663			(i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
664
665	sprintf(print_tb_buf + strlen(print_tb_buf),
666		"======================== the end ====================================\n");
667}
668
669void print_cur_tb(char *mes)
670{
671	printk("%s\n%s", mes, print_tb_buf);
672}
673
674static void check_leaf_block_head(struct buffer_head *bh)
675{
676	struct block_head *blkh;
677	int nr;
678
679	blkh = B_BLK_HEAD(bh);
680	nr = blkh_nr_item(blkh);
681	if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
682		reiserfs_panic(NULL,
683			       "vs-6010: check_leaf_block_head: invalid item number %z",
684			       bh);
685	if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
686		reiserfs_panic(NULL,
687			       "vs-6020: check_leaf_block_head: invalid free space %z",
688			       bh);
689
690}
691
692static void check_internal_block_head(struct buffer_head *bh)
693{
694	struct block_head *blkh;
695
696	blkh = B_BLK_HEAD(bh);
697	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
698		reiserfs_panic(NULL,
699			       "vs-6025: check_internal_block_head: invalid level %z",
700			       bh);
701
702	if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
703		reiserfs_panic(NULL,
704			       "vs-6030: check_internal_block_head: invalid item number %z",
705			       bh);
706
707	if (B_FREE_SPACE(bh) !=
708	    bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
709	    DC_SIZE * (B_NR_ITEMS(bh) + 1))
710		reiserfs_panic(NULL,
711			       "vs-6040: check_internal_block_head: invalid free space %z",
712			       bh);
713
714}
715
716void check_leaf(struct buffer_head *bh)
717{
718	int i;
719	struct item_head *ih;
720
721	if (!bh)
722		return;
723	check_leaf_block_head(bh);
724	for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
725		op_check_item(ih, B_I_PITEM(bh, ih));
726}
727
728void check_internal(struct buffer_head *bh)
729{
730	if (!bh)
731		return;
732	check_internal_block_head(bh);
733}
734
735void print_statistics(struct super_block *s)
736{
737
738	/*
739	   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
740	   bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
741	   REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
742	   REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
743	   REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
744	 */
745
746}
747