/*
 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 */

#include <linux/time.h>
#include <linux/fs.h>
#include "reiserfs.h"
#include <linux/string.h>
#include <linux/buffer_head.h>

#include <stdarg.h>

static char error_buf[1024];
static char fmt_buf[1024];
static char off_buf[80];

static char *reiserfs_cpu_offset(struct cpu_key *key)
{
	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
		sprintf(off_buf, "%llu(%llu)",
			(unsigned long long)
			GET_HASH_VALUE(cpu_key_k_offset(key)),
			(unsigned long long)
			GET_GENERATION_NUMBER(cpu_key_k_offset(key)));
	else
		sprintf(off_buf, "0x%Lx",
			(unsigned long long)cpu_key_k_offset(key));
	return off_buf;
}

static char *le_offset(struct reiserfs_key *key)
{
	int version;

	version = le_key_version(key);
	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
		sprintf(off_buf, "%llu(%llu)",
			(unsigned long long)
			GET_HASH_VALUE(le_key_k_offset(version, key)),
			(unsigned long long)
			GET_GENERATION_NUMBER(le_key_k_offset(version, key)));
	else
		sprintf(off_buf, "0x%Lx",
			(unsigned long long)le_key_k_offset(version, key));
	return off_buf;
}

static char *cpu_type(struct cpu_key *key)
{
	if (cpu_key_k_type(key) == TYPE_STAT_DATA)
		return "SD";
	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
		return "DIR";
	if (cpu_key_k_type(key) == TYPE_DIRECT)
		return "DIRECT";
	if (cpu_key_k_type(key) == TYPE_INDIRECT)
		return "IND";
	return "UNKNOWN";
}

static char *le_type(struct reiserfs_key *key)
{
	int version;

	version = le_key_version(key);

	if (le_key_k_type(version, key) == TYPE_STAT_DATA)
		return "SD";
	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
		return "DIR";
	if (le_key_k_type(version, key) == TYPE_DIRECT)
		return "DIRECT";
	if (le_key_k_type(version, key) == TYPE_INDIRECT)
		return "IND";
	return "UNKNOWN";
}

/* %k */
static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key)
{
	if (key)
		return scnprintf(buf, size, "[%d %d %s %s]",
				 le32_to_cpu(key->k_dir_id),
				 le32_to_cpu(key->k_objectid), le_offset(key),
				 le_type(key));
	else
		return scnprintf(buf, size, "[NULL]");
}

/* %K */
static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key)
{
	if (key)
		return scnprintf(buf, size, "[%d %d %s %s]",
				 key->on_disk_key.k_dir_id,
				 key->on_disk_key.k_objectid,
				 reiserfs_cpu_offset(key), cpu_type(key));
	else
		return scnprintf(buf, size, "[NULL]");
}

static int scnprintf_de_head(char *buf, size_t size,
			     struct reiserfs_de_head *deh)
{
	if (deh)
		return scnprintf(buf, size,
				 "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]",
				 deh_offset(deh), deh_dir_id(deh),
				 deh_objectid(deh), deh_location(deh),
				 deh_state(deh));
	else
		return scnprintf(buf, size, "[NULL]");

}

static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih)
{
	if (ih) {
		char *p = buf;
		char * const end = buf + size;

		p += scnprintf(p, end - p, "%s",
			       (ih_version(ih) == KEY_FORMAT_3_6) ?
			       "*3.6* " : "*3.5*");

		p += scnprintf_le_key(p, end - p, &ih->ih_key);

		p += scnprintf(p, end - p,
			       ", item_len %d, item_location %d, free_space(entry_count) %d",
			       ih_item_len(ih), ih_location(ih),
			       ih_free_space(ih));
		return p - buf;
	} else
		return scnprintf(buf, size, "[NULL]");
}

static int scnprintf_direntry(char *buf, size_t size,
			      struct reiserfs_dir_entry *de)
{
	char name[20];

	memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
	name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
	return scnprintf(buf, size, "\"%s\"==>[%d %d]",
			 name, de->de_dir_id, de->de_objectid);
}

static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh)
{
	return scnprintf(buf, size,
			 "level=%d, nr_items=%d, free_space=%d rdkey ",
			 B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
}

static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh)
{
	return scnprintf(buf, size,
			 "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
			 bh->b_bdev, bh->b_size,
			 (unsigned long long)bh->b_blocknr,
			 atomic_read(&(bh->b_count)),
			 bh->b_state, bh->b_page,
			 buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE",
			 buffer_dirty(bh) ? "DIRTY" : "CLEAN",
			 buffer_locked(bh) ? "LOCKED" : "UNLOCKED");
}

static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc)
{
	return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]",
			 dc_block_number(dc), dc_size(dc));
}

static char *is_there_reiserfs_struct(char *fmt, int *what)
{
	char *k = fmt;

	while ((k = strchr(k, '%')) != NULL) {
		if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
		    k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
			*what = k[1];
			break;
		}
		k++;
	}
	return k;
}

/*
 * debugging reiserfs we used to print out a lot of different
 * variables, like keys, item headers, buffer heads etc. Values of
 * most fields matter. So it took a long time just to write
 * appropriative printk. With this reiserfs_warning you can use format
 * specification for complex structures like you used to do with
 * printfs for integers, doubles and pointers. For instance, to print
 * out key structure you have to write just:
 * reiserfs_warning ("bad key %k", key);
 * instead of
 * printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid,
 *         key->k_offset, key->k_uniqueness);
 */
static DEFINE_SPINLOCK(error_lock);
static void prepare_error_buf(const char *fmt, va_list args)
{
	char *fmt1 = fmt_buf;
	char *k;
	char *p = error_buf;
	char * const end = &error_buf[sizeof(error_buf)];
	int what;

	spin_lock(&error_lock);

	if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) {
		strscpy(error_buf, "format string too long", end - error_buf);
		goto out_unlock;
	}

	while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
		*k = 0;

		p += vscnprintf(p, end - p, fmt1, args);

		switch (what) {
		case 'k':
			p += scnprintf_le_key(p, end - p,
					      va_arg(args, struct reiserfs_key *));
			break;
		case 'K':
			p += scnprintf_cpu_key(p, end - p,
					       va_arg(args, struct cpu_key *));
			break;
		case 'h':
			p += scnprintf_item_head(p, end - p,
						 va_arg(args, struct item_head *));
			break;
		case 't':
			p += scnprintf_direntry(p, end - p,
						va_arg(args, struct reiserfs_dir_entry *));
			break;
		case 'y':
			p += scnprintf_disk_child(p, end - p,
						  va_arg(args, struct disk_child *));
			break;
		case 'z':
			p += scnprintf_block_head(p, end - p,
						  va_arg(args, struct buffer_head *));
			break;
		case 'b':
			p += scnprintf_buffer_head(p, end - p,
						   va_arg(args, struct buffer_head *));
			break;
		case 'a':
			p += scnprintf_de_head(p, end - p,
					       va_arg(args, struct reiserfs_de_head *));
			break;
		}

		fmt1 = k + 2;
	}
	p += vscnprintf(p, end - p, fmt1, args);
out_unlock:
	spin_unlock(&error_lock);

}

/*
 * in addition to usual conversion specifiers this accepts reiserfs
 * specific conversion specifiers:
 * %k to print little endian key,
 * %K to print cpu key,
 * %h to print item_head,
 * %t to print directory entry
 * %z to print block head (arg must be struct buffer_head *
 * %b to print buffer_head
 */

#define do_reiserfs_warning(fmt)\
{\
    va_list args;\
    va_start( args, fmt );\
    prepare_error_buf( fmt, args );\
    va_end( args );\
}

void __reiserfs_warning(struct super_block *sb, const char *id,
			 const char *function, const char *fmt, ...)
{
	do_reiserfs_warning(fmt);
	if (sb)
		printk(KERN_WARNING "REISERFS warning (device %s): %s%s%s: "
		       "%s\n", sb->s_id, id ? id : "", id ? " " : "",
		       function, error_buf);
	else
		printk(KERN_WARNING "REISERFS warning: %s%s%s: %s\n",
		       id ? id : "", id ? " " : "", function, error_buf);
}

/* No newline.. reiserfs_info calls can be followed by printk's */
void reiserfs_info(struct super_block *sb, const char *fmt, ...)
{
	do_reiserfs_warning(fmt);
	if (sb)
		printk(KERN_NOTICE "REISERFS (device %s): %s",
		       sb->s_id, error_buf);
	else
		printk(KERN_NOTICE "REISERFS %s:", error_buf);
}

/* No newline.. reiserfs_printk calls can be followed by printk's */
static void reiserfs_printk(const char *fmt, ...)
{
	do_reiserfs_warning(fmt);
	printk(error_buf);
}

void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
{
#ifdef CONFIG_REISERFS_CHECK
	do_reiserfs_warning(fmt);
	if (s)
		printk(KERN_DEBUG "REISERFS debug (device %s): %s\n",
		       s->s_id, error_buf);
	else
		printk(KERN_DEBUG "REISERFS debug: %s\n", error_buf);
#endif
}

/*
 * The format:
 *
 *          maintainer-errorid: [function-name:] message
 *
 *   where errorid is unique to the maintainer and function-name is
 *   optional, is recommended, so that anyone can easily find the bug
 *   with a simple grep for the short to type string
 *   maintainer-errorid.  Don't bother with reusing errorids, there are
 *   lots of numbers out there.
 *
 *   Example:
 *
 *   reiserfs_panic(
 *     p_sb, "reiser-29: reiserfs_new_blocknrs: "
 *     "one of search_start or rn(%d) is equal to MAX_B_NUM,"
 *     "which means that we are optimizing location based on the "
 *     "bogus location of a temp buffer (%p).",
 *     rn, bh
 *   );
 *
 *   Regular panic()s sometimes clear the screen before the message can
 *   be read, thus the need for the while loop.
 *
 *   Numbering scheme for panic used by Vladimir and Anatoly( Hans completely
 *   ignores this scheme, and considers it pointless complexity):
 *
 *   panics in reiserfs_fs.h have numbers from 1000 to 1999
 *   super.c			2000 to 2999
 *   preserve.c (unused)	3000 to 3999
 *   bitmap.c			4000 to 4999
 *   stree.c			5000 to 5999
 *   prints.c			6000 to 6999
 *   namei.c			7000 to 7999
 *   fix_nodes.c		8000 to 8999
 *   dir.c			9000 to 9999
 *   lbalance.c			10000 to 10999
 *   ibalance.c			11000 to 11999 not ready
 *   do_balan.c			12000 to 12999
 *   inode.c			13000 to 13999
 *   file.c			14000 to 14999
 *   objectid.c			15000 - 15999
 *   buffer.c			16000 - 16999
 *   symlink.c			17000 - 17999
 *
 *  .  */

void __reiserfs_panic(struct super_block *sb, const char *id,
		      const char *function, const char *fmt, ...)
{
	do_reiserfs_warning(fmt);

#ifdef CONFIG_REISERFS_CHECK
	dump_stack();
#endif
	if (sb)
		printk(KERN_WARNING "REISERFS panic (device %s): %s%s%s: %s\n",
		      sb->s_id, id ? id : "", id ? " " : "",
		      function, error_buf);
	else
		printk(KERN_WARNING "REISERFS panic: %s%s%s: %s\n",
		      id ? id : "", id ? " " : "", function, error_buf);
	BUG();
}

void __reiserfs_error(struct super_block *sb, const char *id,
		      const char *function, const char *fmt, ...)
{
	do_reiserfs_warning(fmt);

	BUG_ON(sb == NULL);

	if (reiserfs_error_panic(sb))
		__reiserfs_panic(sb, id, function, error_buf);

	if (id && id[0])
		printk(KERN_CRIT "REISERFS error (device %s): %s %s: %s\n",
		       sb->s_id, id, function, error_buf);
	else
		printk(KERN_CRIT "REISERFS error (device %s): %s: %s\n",
		       sb->s_id, function, error_buf);

	if (sb_rdonly(sb))
		return;

	reiserfs_info(sb, "Remounting filesystem read-only\n");
	sb->s_flags |= SB_RDONLY;
	reiserfs_abort_journal(sb, -EIO);
}

void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
{
	do_reiserfs_warning(fmt);

	if (reiserfs_error_panic(sb)) {
		panic(KERN_CRIT "REISERFS panic (device %s): %s\n", sb->s_id,
		      error_buf);
	}

	if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
		return;

	printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
	       error_buf);

	sb->s_flags |= SB_RDONLY;
	reiserfs_abort_journal(sb, errno);
}

/*
 * this prints internal nodes (4 keys/items in line) (dc_number,
 * dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
 * dc_size)...
 */
static int print_internal(struct buffer_head *bh, int first, int last)
{
	struct reiserfs_key *key;
	struct disk_child *dc;
	int i;
	int from, to;

	if (!B_IS_KEYS_LEVEL(bh))
		return 1;

	check_internal(bh);

	if (first == -1) {
		from = 0;
		to = B_NR_ITEMS(bh);
	} else {
		from = first;
		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
	}

	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);

	dc = B_N_CHILD(bh, from);
	reiserfs_printk("PTR %d: %y ", from, dc);

	for (i = from, key = internal_key(bh, from), dc++; i < to;
	     i++, key++, dc++) {
		reiserfs_printk("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
		if (i && i % 4 == 0)
			printk("\n");
	}
	printk("\n");
	return 0;
}

static int print_leaf(struct buffer_head *bh, int print_mode, int first,
		      int last)
{
	struct block_head *blkh;
	struct item_head *ih;
	int i, nr;
	int from, to;

	if (!B_IS_ITEMS_LEVEL(bh))
		return 1;

	check_leaf(bh);

	blkh = B_BLK_HEAD(bh);
	ih = item_head(bh, 0);
	nr = blkh_nr_item(blkh);

	printk
	    ("\n===================================================================\n");
	reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);

	if (!(print_mode & PRINT_LEAF_ITEMS)) {
		reiserfs_printk("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
				&(ih->ih_key), &((ih + nr - 1)->ih_key));
		return 0;
	}

	if (first < 0 || first > nr - 1)
		from = 0;
	else
		from = first;

	if (last < 0 || last > nr)
		to = nr;
	else
		to = last;

	ih += from;
	printk
	    ("-------------------------------------------------------------------------------\n");
	printk
	    ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
	for (i = from; i < to; i++, ih++) {
		printk
		    ("-------------------------------------------------------------------------------\n");
		reiserfs_printk("|%2d| %h |\n", i, ih);
		if (print_mode & PRINT_LEAF_ITEMS)
			op_print_item(ih, ih_item_body(bh, ih));
	}

	printk
	    ("===================================================================\n");

	return 0;
}

char *reiserfs_hashname(int code)
{
	if (code == YURA_HASH)
		return "rupasov";
	if (code == TEA_HASH)
		return "tea";
	if (code == R5_HASH)
		return "r5";

	return "unknown";
}

/* return 1 if this is not super block */
static int print_super_block(struct buffer_head *bh)
{
	struct reiserfs_super_block *rs =
	    (struct reiserfs_super_block *)(bh->b_data);
	int skipped, data_blocks;
	char *version;

	if (is_reiserfs_3_5(rs)) {
		version = "3.5";
	} else if (is_reiserfs_3_6(rs)) {
		version = "3.6";
	} else if (is_reiserfs_jr(rs)) {
		version = ((sb_version(rs) == REISERFS_VERSION_2) ?
			   "3.6" : "3.5");
	} else {
		return 1;
	}

	printk("%pg\'s super block is in block %llu\n", bh->b_bdev,
	       (unsigned long long)bh->b_blocknr);
	printk("Reiserfs version %s\n", version);
	printk("Block count %u\n", sb_block_count(rs));
	printk("Blocksize %d\n", sb_blocksize(rs));
	printk("Free blocks %u\n", sb_free_blocks(rs));
	/*
	 * FIXME: this would be confusing if
	 * someone stores reiserfs super block in some data block ;)
//    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
	 */
	skipped = bh->b_blocknr;
	data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) -
	    (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) +
	     1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs);
	printk
	    ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
	     "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs),
	     (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
	      sb_reserved_for_journal(rs)), data_blocks);
	printk("Root block %u\n", sb_root_block(rs));
	printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
	printk("Journal dev %d\n", sb_jp_journal_dev(rs));
	printk("Journal orig size %d\n", sb_jp_journal_size(rs));
	printk("FS state %d\n", sb_fs_state(rs));
	printk("Hash function \"%s\"\n",
	       reiserfs_hashname(sb_hash_function_code(rs)));

	printk("Tree height %d\n", sb_tree_height(rs));
	return 0;
}

static int print_desc_block(struct buffer_head *bh)
{
	struct reiserfs_journal_desc *desc;

	if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
		return 1;

	desc = (struct reiserfs_journal_desc *)(bh->b_data);
	printk("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
	       (unsigned long long)bh->b_blocknr, get_desc_trans_id(desc),
	       get_desc_mount_id(desc), get_desc_trans_len(desc));

	return 0;
}
/* ..., int print_mode, int first, int last) */
void print_block(struct buffer_head *bh, ...)
{
	va_list args;
	int mode, first, last;

	if (!bh) {
		printk("print_block: buffer is NULL\n");
		return;
	}

	va_start(args, bh);

	mode = va_arg(args, int);
	first = va_arg(args, int);
	last = va_arg(args, int);
	if (print_leaf(bh, mode, first, last))
		if (print_internal(bh, first, last))
			if (print_super_block(bh))
				if (print_desc_block(bh))
					printk
					    ("Block %llu contains unformatted data\n",
					     (unsigned long long)bh->b_blocknr);

	va_end(args);
}

static char print_tb_buf[2048];

/* this stores initial state of tree balance in the print_tb_buf */
void store_print_tb(struct tree_balance *tb)
{
	int h = 0;
	int i;
	struct buffer_head *tbSh, *tbFh;

	if (!tb)
		return;

	sprintf(print_tb_buf, "\n"
		"BALANCING %d\n"
		"MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n"
		"=====================================================================\n"
		"* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
		REISERFS_SB(tb->tb_sb)->s_do_balance,
		tb->tb_mode, PATH_LAST_POSITION(tb->tb_path),
		tb->tb_path->pos_in_item);

	for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
		if (PATH_H_PATH_OFFSET(tb->tb_path, h) <=
		    tb->tb_path->path_length
		    && PATH_H_PATH_OFFSET(tb->tb_path,
					  h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
			tbSh = PATH_H_PBUFFER(tb->tb_path, h);
			tbFh = PATH_H_PPARENT(tb->tb_path, h);
		} else {
			tbSh = NULL;
			tbFh = NULL;
		}
		sprintf(print_tb_buf + strlen(print_tb_buf),
			"* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
			h,
			(tbSh) ? (long long)(tbSh->b_blocknr) : (-1LL),
			(tbSh) ? atomic_read(&tbSh->b_count) : -1,
			(tb->L[h]) ? (long long)(tb->L[h]->b_blocknr) : (-1LL),
			(tb->L[h]) ? atomic_read(&tb->L[h]->b_count) : -1,
			(tb->R[h]) ? (long long)(tb->R[h]->b_blocknr) : (-1LL),
			(tb->R[h]) ? atomic_read(&tb->R[h]->b_count) : -1,
			(tbFh) ? (long long)(tbFh->b_blocknr) : (-1LL),
			(tb->FL[h]) ? (long long)(tb->FL[h]->
						  b_blocknr) : (-1LL),
			(tb->FR[h]) ? (long long)(tb->FR[h]->
						  b_blocknr) : (-1LL),
			(tb->CFL[h]) ? (long long)(tb->CFL[h]->
						   b_blocknr) : (-1LL),
			(tb->CFR[h]) ? (long long)(tb->CFR[h]->
						   b_blocknr) : (-1LL));
	}

	sprintf(print_tb_buf + strlen(print_tb_buf),
		"=====================================================================\n"
		"* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
		"* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
		tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],
		tb->rbytes, tb->blknum[0], tb->s0num, tb->snum[0],
		tb->sbytes[0], tb->snum[1], tb->sbytes[1],
		tb->cur_blknum, tb->lkey[0], tb->rkey[0]);

	/* this prints balance parameters for non-leaf levels */
	h = 0;
	do {
		h++;
		sprintf(print_tb_buf + strlen(print_tb_buf),
			"* %d * %4d * %2d *    * %2d *    * %2d *\n",
			h, tb->insert_size[h], tb->lnum[h], tb->rnum[h],
			tb->blknum[h]);
	} while (tb->insert_size[h]);

	sprintf(print_tb_buf + strlen(print_tb_buf),
		"=====================================================================\n"
		"FEB list: ");

	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
	h = 0;
	for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
		sprintf(print_tb_buf + strlen(print_tb_buf),
			"%p (%llu %d)%s", tb->FEB[i],
			tb->FEB[i] ? (unsigned long long)tb->FEB[i]->
			b_blocknr : 0ULL,
			tb->FEB[i] ? atomic_read(&tb->FEB[i]->b_count) : 0,
			(i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");

	sprintf(print_tb_buf + strlen(print_tb_buf),
		"======================== the end ====================================\n");
}

void print_cur_tb(char *mes)
{
	printk("%s\n%s", mes, print_tb_buf);
}

static void check_leaf_block_head(struct buffer_head *bh)
{
	struct block_head *blkh;
	int nr;

	blkh = B_BLK_HEAD(bh);
	nr = blkh_nr_item(blkh);
	if (nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
		reiserfs_panic(NULL, "vs-6010", "invalid item number %z",
			       bh);
	if (blkh_free_space(blkh) > bh->b_size - BLKH_SIZE - IH_SIZE * nr)
		reiserfs_panic(NULL, "vs-6020", "invalid free space %z",
			       bh);

}

static void check_internal_block_head(struct buffer_head *bh)
{
	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
		reiserfs_panic(NULL, "vs-6025", "invalid level %z", bh);

	if (B_NR_ITEMS(bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
		reiserfs_panic(NULL, "vs-6030", "invalid item number %z", bh);

	if (B_FREE_SPACE(bh) !=
	    bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS(bh) -
	    DC_SIZE * (B_NR_ITEMS(bh) + 1))
		reiserfs_panic(NULL, "vs-6040", "invalid free space %z", bh);

}

void check_leaf(struct buffer_head *bh)
{
	int i;
	struct item_head *ih;

	if (!bh)
		return;
	check_leaf_block_head(bh);
	for (i = 0, ih = item_head(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
		op_check_item(ih, ih_item_body(bh, ih));
}

void check_internal(struct buffer_head *bh)
{
	if (!bh)
		return;
	check_internal_block_head(bh);
}

void print_statistics(struct super_block *s)
{

	/*
	   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
	   bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
	   REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
	   REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
	   REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
	 */

}
