prints.c revision a5437152eec2c9171f6ab06e63135c5333f0a929
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 warning (device %s): %s\n",
272		       sb->s_id, 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 (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 *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", sb->s_id,
372		      error_buf);
373	}
374
375	if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
376		return;
377
378	printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
379	       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	va_end(args);
580}
581
582static char print_tb_buf[2048];
583
584/* this stores initial state of tree balance in the print_tb_buf */
585void store_print_tb(struct tree_balance *tb)
586{
587	int h = 0;
588	int i;
589	struct buffer_head *tbSh, *tbFh;
590
591	if (!tb)
592		return;
593
594	sprintf(print_tb_buf, "\n"
595		"BALANCING %d\n"
596		"MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
597		"=====================================================================\n"
598		"* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
599		REISERFS_SB(tb->tb_sb)->s_do_balance,
600		tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
601		tb->tb_path->pos_in_item);
602
603	for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
604		if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
605		    tb->tb_path->path_length
606		    && PATH_H_PATH_OFFSET(tb->tb_path,
607					  h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
608			tbSh = PATH_H_PBUFFER(tb->tb_path, h);
609			tbFh = PATH_H_PPARENT(tb->tb_path, h);
610		} else {
611			tbSh = NULL;
612			tbFh = NULL;
613		}
614		sprintf(print_tb_buf + strlen(print_tb_buf),
615			"* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
616			h,
617			(tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
618			(tbSh) ? atomic_read(&(tbSh->b_count)) : -1,
619			(tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
620			(tb->L[h]) ? atomic_read(&(tb->L[h]->b_count)) : -1,
621			(tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
622			(tb->R[h]) ? atomic_read(&(tb->R[h]->b_count)) : -1,
623			(tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
624			(tb->FL[h]) ? (long long)(tb->FL[h]->
625						  b_blocknr) : (-1LL),
626			(tb->FR[h]) ? (long long)(tb->FR[h]->
627						  b_blocknr) : (-1LL),
628			(tb->CFL[h]) ? (long long)(tb->CFL[h]->
629						   b_blocknr) : (-1LL),
630			(tb->CFR[h]) ? (long long)(tb->CFR[h]->
631						   b_blocknr) : (-1LL));
632	}
633
634	sprintf(print_tb_buf + strlen(print_tb_buf),
635		"=====================================================================\n"
636		"* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
637		"* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
638		tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
639		tb->rbytes, tb->blknum[0], tb->s0num, tb->s1num, tb->s1bytes,
640		tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0],
641		tb->rkey[0]);
642
643	/* this prints balance parameters for non-leaf levels */
644	h = 0;
645	do {
646		h++;
647		sprintf(print_tb_buf + strlen(print_tb_buf),
648			"* %d * %4d * %2d *    * %2d *    * %2d *\n",
649			h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
650			tb->blknum[h]);
651	} while (tb->insert_size[h]);
652
653	sprintf(print_tb_buf + strlen(print_tb_buf),
654		"=====================================================================\n"
655		"FEB list: ");
656
657	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
658	h = 0;
659	for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
660		sprintf(print_tb_buf + strlen(print_tb_buf),
661			"%p (%llu %d)%s", tb->FEB[i],
662			tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
663			b_blocknr : 0ULL,
664			tb->FEB[i] ? atomic_read(&(tb->FEB[i]->b_count)) : 0,
665			(i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
666
667	sprintf(print_tb_buf + strlen(print_tb_buf),
668		"======================== the end ====================================\n");
669}
670
671void print_cur_tb(char *mes)
672{
673	printk("%s\n%s", mes, print_tb_buf);
674}
675
676static void check_leaf_block_head(struct buffer_head *bh)
677{
678	struct block_head *blkh;
679	int nr;
680
681	blkh = B_BLK_HEAD(bh);
682	nr = blkh_nr_item(blkh);
683	if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
684		reiserfs_panic(NULL,
685			       "vs-6010: check_leaf_block_head: invalid item number %z",
686			       bh);
687	if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
688		reiserfs_panic(NULL,
689			       "vs-6020: check_leaf_block_head: invalid free space %z",
690			       bh);
691
692}
693
694static void check_internal_block_head(struct buffer_head *bh)
695{
696	struct block_head *blkh;
697
698	blkh = B_BLK_HEAD(bh);
699	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
700		reiserfs_panic(NULL,
701			       "vs-6025: check_internal_block_head: invalid level %z",
702			       bh);
703
704	if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
705		reiserfs_panic(NULL,
706			       "vs-6030: check_internal_block_head: invalid item number %z",
707			       bh);
708
709	if (B_FREE_SPACE(bh) !=
710	    bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
711	    DC_SIZE * (B_NR_ITEMS(bh) + 1))
712		reiserfs_panic(NULL,
713			       "vs-6040: check_internal_block_head: invalid free space %z",
714			       bh);
715
716}
717
718void check_leaf(struct buffer_head *bh)
719{
720	int i;
721	struct item_head *ih;
722
723	if (!bh)
724		return;
725	check_leaf_block_head(bh);
726	for (i = 0, ih = B_N_PITEM_HEAD(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
727		op_check_item(ih, B_I_PITEM(bh, ih));
728}
729
730void check_internal(struct buffer_head *bh)
731{
732	if (!bh)
733		return;
734	check_internal_block_head(bh);
735}
736
737void print_statistics(struct super_block *s)
738{
739
740	/*
741	   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
742	   bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
743	   REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
744	   REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
745	   REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
746	 */
747
748}
749