cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

prints.c (21873B)


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