/*
 * 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 <linux/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 = min_t(int, 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);
	 */

}
