prints.c 21.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6
/*
 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
 */

#include <linux/time.h>
#include <linux/fs.h>
7
#include "reiserfs.h"
Linus Torvalds's avatar
Linus Torvalds committed
8 9 10 11 12 13 14 15 16
#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];

17
static char *reiserfs_cpu_offset(struct cpu_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
18
{
19
	if (cpu_key_k_type(key) == TYPE_DIRENTRY)
20
		sprintf(off_buf, "%llu(%llu)",
21 22 23 24 25 26 27 28
			(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;
Linus Torvalds's avatar
Linus Torvalds committed
29 30
}

31
static char *le_offset(struct reiserfs_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
32
{
33
	int version;
Linus Torvalds's avatar
Linus Torvalds committed
34

35 36
	version = le_key_version(key);
	if (le_key_k_type(version, key) == TYPE_DIRENTRY)
37
		sprintf(off_buf, "%llu(%llu)",
38 39 40 41 42 43 44 45
			(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;
Linus Torvalds's avatar
Linus Torvalds committed
46 47
}

48
static char *cpu_type(struct cpu_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
49
{
50 51 52 53 54 55 56 57 58
	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";
Linus Torvalds's avatar
Linus Torvalds committed
59 60
}

61
static char *le_type(struct reiserfs_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
62
{
63
	int version;
Linus Torvalds's avatar
Linus Torvalds committed
64

65
	version = le_key_version(key);
Linus Torvalds's avatar
Linus Torvalds committed
66

67 68 69 70 71 72 73 74 75 76
	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";
}
Linus Torvalds's avatar
Linus Torvalds committed
77 78

/* %k */
79
static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
80
{
81
	if (key)
82 83 84 85
		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));
86
	else
87
		return scnprintf(buf, size, "[NULL]");
Linus Torvalds's avatar
Linus Torvalds committed
88 89 90
}

/* %K */
91
static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key)
Linus Torvalds's avatar
Linus Torvalds committed
92
{
93
	if (key)
94 95 96 97
		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));
98
	else
99
		return scnprintf(buf, size, "[NULL]");
Linus Torvalds's avatar
Linus Torvalds committed
100 101
}

102 103
static int scnprintf_de_head(char *buf, size_t size,
			     struct reiserfs_de_head *deh)
Linus Torvalds's avatar
Linus Torvalds committed
104
{
105
	if (deh)
106 107 108 109 110
		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));
111
	else
112
		return scnprintf(buf, size, "[NULL]");
Linus Torvalds's avatar
Linus Torvalds committed
113 114 115

}

116
static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih)
Linus Torvalds's avatar
Linus Torvalds committed
117
{
118
	if (ih) {
119 120 121 122 123 124 125 126 127 128 129 130 131 132
		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;
133
	} else
134
		return scnprintf(buf, size, "[NULL]");
Linus Torvalds's avatar
Linus Torvalds committed
135 136
}

137 138
static int scnprintf_direntry(char *buf, size_t size,
			      struct reiserfs_dir_entry *de)
Linus Torvalds's avatar
Linus Torvalds committed
139
{
140
	char name[20];
Linus Torvalds's avatar
Linus Torvalds committed
141

142 143
	memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
	name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
144 145
	return scnprintf(buf, size, "\"%s\"==>[%d %d]",
			 name, de->de_dir_id, de->de_objectid);
Linus Torvalds's avatar
Linus Torvalds committed
146 147
}

148
static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh)
Linus Torvalds's avatar
Linus Torvalds committed
149
{
150 151 152
	return scnprintf(buf, size,
			 "level=%d, nr_items=%d, free_space=%d rdkey ",
			 B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh));
Linus Torvalds's avatar
Linus Torvalds committed
153 154
}

155
static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh)
Linus Torvalds's avatar
Linus Torvalds committed
156
{
157 158 159 160 161 162 163 164 165
	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");
Linus Torvalds's avatar
Linus Torvalds committed
166 167
}

168
static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc)
Linus Torvalds's avatar
Linus Torvalds committed
169
{
170 171
	return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]",
			 dc_block_number(dc), dc_size(dc));
Linus Torvalds's avatar
Linus Torvalds committed
172 173
}

174
static char *is_there_reiserfs_struct(char *fmt, int *what)
Linus Torvalds's avatar
Linus Torvalds committed
175
{
176
	char *k = fmt;
Linus Torvalds's avatar
Linus Torvalds committed
177

178 179 180 181 182 183 184 185 186 187
	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;
}
Linus Torvalds's avatar
Linus Torvalds committed
188

189 190 191 192 193 194 195 196 197 198 199 200 201
/*
 * 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);
 */
202
static DEFINE_SPINLOCK(error_lock);
203 204 205 206 207
static void prepare_error_buf(const char *fmt, va_list args)
{
	char *fmt1 = fmt_buf;
	char *k;
	char *p = error_buf;
208
	char * const end = &error_buf[sizeof(error_buf)];
209
	int what;
210

211 212
	spin_lock(&error_lock);

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

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

221
		p += vscnprintf(p, end - p, fmt1, args);
222 223 224

		switch (what) {
		case 'k':
225 226
			p += scnprintf_le_key(p, end - p,
					      va_arg(args, struct reiserfs_key *));
227 228
			break;
		case 'K':
229 230
			p += scnprintf_cpu_key(p, end - p,
					       va_arg(args, struct cpu_key *));
231 232
			break;
		case 'h':
233 234
			p += scnprintf_item_head(p, end - p,
						 va_arg(args, struct item_head *));
235 236
			break;
		case 't':
237 238
			p += scnprintf_direntry(p, end - p,
						va_arg(args, struct reiserfs_dir_entry *));
239 240
			break;
		case 'y':
241 242
			p += scnprintf_disk_child(p, end - p,
						  va_arg(args, struct disk_child *));
243 244
			break;
		case 'z':
245 246
			p += scnprintf_block_head(p, end - p,
						  va_arg(args, struct buffer_head *));
247 248
			break;
		case 'b':
249 250
			p += scnprintf_buffer_head(p, end - p,
						   va_arg(args, struct buffer_head *));
251 252
			break;
		case 'a':
253 254
			p += scnprintf_de_head(p, end - p,
					       va_arg(args, struct reiserfs_de_head *));
255 256 257 258 259
			break;
		}

		fmt1 = k + 2;
	}
260 261
	p += vscnprintf(p, end - p, fmt1, args);
out_unlock:
262
	spin_unlock(&error_lock);
Linus Torvalds's avatar
Linus Torvalds committed
263 264 265

}

266 267 268 269 270 271 272 273 274 275
/*
 * 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
 */
Linus Torvalds's avatar
Linus Torvalds committed
276 277 278 279 280 281 282 283 284

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

285 286
void __reiserfs_warning(struct super_block *sb, const char *id,
			 const char *function, const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
287
{
288 289
	do_reiserfs_warning(fmt);
	if (sb)
290 291 292
		printk(KERN_WARNING "REISERFS warning (device %s): %s%s%s: "
		       "%s\n", sb->s_id, id ? id : "", id ? " " : "",
		       function, error_buf);
293
	else
294 295
		printk(KERN_WARNING "REISERFS warning: %s%s%s: %s\n",
		       id ? id : "", id ? " " : "", function, error_buf);
Linus Torvalds's avatar
Linus Torvalds committed
296 297 298
}

/* No newline.. reiserfs_info calls can be followed by printk's */
299
void reiserfs_info(struct super_block *sb, const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
300
{
301 302
	do_reiserfs_warning(fmt);
	if (sb)
303 304
		printk(KERN_NOTICE "REISERFS (device %s): %s",
		       sb->s_id, error_buf);
305
	else
306
		printk(KERN_NOTICE "REISERFS %s:", error_buf);
Linus Torvalds's avatar
Linus Torvalds committed
307 308 309
}

/* No newline.. reiserfs_printk calls can be followed by printk's */
310
static void reiserfs_printk(const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
311
{
312 313
	do_reiserfs_warning(fmt);
	printk(error_buf);
Linus Torvalds's avatar
Linus Torvalds committed
314 315
}

316
void reiserfs_debug(struct super_block *s, int level, const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
317 318
{
#ifdef CONFIG_REISERFS_CHECK
319 320
	do_reiserfs_warning(fmt);
	if (s)
321 322
		printk(KERN_DEBUG "REISERFS debug (device %s): %s\n",
		       s->s_id, error_buf);
323
	else
324
		printk(KERN_DEBUG "REISERFS debug: %s\n", error_buf);
Linus Torvalds's avatar
Linus Torvalds committed
325 326 327
#endif
}

328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
/*
 * 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
 *
 *  .  */
Linus Torvalds's avatar
Linus Torvalds committed
374

375 376
void __reiserfs_panic(struct super_block *sb, const char *id,
		      const char *function, const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
377
{
378
	do_reiserfs_warning(fmt);
Linus Torvalds's avatar
Linus Torvalds committed
379

380
#ifdef CONFIG_REISERFS_CHECK
381
	dump_stack();
382 383
#endif
	if (sb)
384
		printk(KERN_WARNING "REISERFS panic (device %s): %s%s%s: %s\n",
385 386 387
		      sb->s_id, id ? id : "", id ? " " : "",
		      function, error_buf);
	else
388
		printk(KERN_WARNING "REISERFS panic: %s%s%s: %s\n",
389
		      id ? id : "", id ? " " : "", function, error_buf);
390
	BUG();
Linus Torvalds's avatar
Linus Torvalds committed
391 392
}

393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
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);

410
	if (sb_rdonly(sb))
411 412 413
		return;

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

418
void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...)
Linus Torvalds's avatar
Linus Torvalds committed
419
{
420
	do_reiserfs_warning(fmt);
Linus Torvalds's avatar
Linus Torvalds committed
421

422
	if (reiserfs_error_panic(sb)) {
423 424
		panic(KERN_CRIT "REISERFS panic (device %s): %s\n", sb->s_id,
		      error_buf);
425
	}
Linus Torvalds's avatar
Linus Torvalds committed
426

427
	if (reiserfs_is_journal_aborted(SB_JOURNAL(sb)))
428
		return;
Linus Torvalds's avatar
Linus Torvalds committed
429

430 431
	printk(KERN_CRIT "REISERFS abort (device %s): %s\n", sb->s_id,
	       error_buf);
Linus Torvalds's avatar
Linus Torvalds committed
432

433
	sb->s_flags |= SB_RDONLY;
434
	reiserfs_abort_journal(sb, errno);
Linus Torvalds's avatar
Linus Torvalds committed
435 436
}

437 438 439 440 441
/*
 * 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)...
 */
442
static int print_internal(struct buffer_head *bh, int first, int last)
Linus Torvalds's avatar
Linus Torvalds committed
443
{
444 445 446 447
	struct reiserfs_key *key;
	struct disk_child *dc;
	int i;
	int from, to;
Linus Torvalds's avatar
Linus Torvalds committed
448

449 450
	if (!B_IS_KEYS_LEVEL(bh))
		return 1;
Linus Torvalds's avatar
Linus Torvalds committed
451

452
	check_internal(bh);
Linus Torvalds's avatar
Linus Torvalds committed
453

454 455 456 457 458 459 460
	if (first == -1) {
		from = 0;
		to = B_NR_ITEMS(bh);
	} else {
		from = first;
		to = last < B_NR_ITEMS(bh) ? last : B_NR_ITEMS(bh);
	}
Linus Torvalds's avatar
Linus Torvalds committed
461

462
	reiserfs_printk("INTERNAL NODE (%ld) contains %z\n", bh->b_blocknr, bh);
Linus Torvalds's avatar
Linus Torvalds committed
463

464 465
	dc = B_N_CHILD(bh, from);
	reiserfs_printk("PTR %d: %y ", from, dc);
Linus Torvalds's avatar
Linus Torvalds committed
466

467
	for (i = from, key = internal_key(bh, from), dc++; i < to;
468 469 470 471 472 473 474 475
	     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;
}
Linus Torvalds's avatar
Linus Torvalds committed
476

477 478 479 480 481 482 483
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;
Linus Torvalds's avatar
Linus Torvalds committed
484

485 486
	if (!B_IS_ITEMS_LEVEL(bh))
		return 1;
Linus Torvalds's avatar
Linus Torvalds committed
487

488
	check_leaf(bh);
Linus Torvalds's avatar
Linus Torvalds committed
489

490
	blkh = B_BLK_HEAD(bh);
491
	ih = item_head(bh, 0);
492
	nr = blkh_nr_item(blkh);
Linus Torvalds's avatar
Linus Torvalds committed
493

494 495 496
	printk
	    ("\n===================================================================\n");
	reiserfs_printk("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
Linus Torvalds's avatar
Linus Torvalds committed
497

498 499 500 501 502
	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;
	}
Linus Torvalds's avatar
Linus Torvalds committed
503

504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
	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)
524
			op_print_item(ih, ih_item_body(bh, ih));
525
	}
Linus Torvalds's avatar
Linus Torvalds committed
526

527 528
	printk
	    ("===================================================================\n");
Linus Torvalds's avatar
Linus Torvalds committed
529

530
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
531 532
}

533
char *reiserfs_hashname(int code)
Linus Torvalds's avatar
Linus Torvalds committed
534
{
535 536 537 538 539 540
	if (code == YURA_HASH)
		return "rupasov";
	if (code == TEA_HASH)
		return "tea";
	if (code == R5_HASH)
		return "r5";
Linus Torvalds's avatar
Linus Torvalds committed
541

542
	return "unknown";
Linus Torvalds's avatar
Linus Torvalds committed
543 544 545
}

/* return 1 if this is not super block */
546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
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;
	}

564
	printk("%pg\'s super block is in block %llu\n", bh->b_bdev,
565 566 567 568 569
	       (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));
570 571 572
	/*
	 * FIXME: this would be confusing if
	 * someone stores reiserfs super block in some data block ;)
Linus Torvalds's avatar
Linus Torvalds committed
573
//    skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs);
574
	 */
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
	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;
Linus Torvalds's avatar
Linus Torvalds committed
594 595
}

596
static int print_desc_block(struct buffer_head *bh)
Linus Torvalds's avatar
Linus Torvalds committed
597
{
598
	struct reiserfs_journal_desc *desc;
Linus Torvalds's avatar
Linus Torvalds committed
599

600 601
	if (memcmp(get_journal_desc_magic(bh), JOURNAL_DESC_MAGIC, 8))
		return 1;
Linus Torvalds's avatar
Linus Torvalds committed
602

603 604 605 606
	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));
Linus Torvalds's avatar
Linus Torvalds committed
607

608
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
609
}
610 611
/* ..., int print_mode, int first, int last) */
void print_block(struct buffer_head *bh, ...)
Linus Torvalds's avatar
Linus Torvalds committed
612
{
613 614
	va_list args;
	int mode, first, last;
Linus Torvalds's avatar
Linus Torvalds committed
615

616 617 618 619
	if (!bh) {
		printk("print_block: buffer is NULL\n");
		return;
	}
Linus Torvalds's avatar
Linus Torvalds committed
620

621 622
	va_start(args, bh);

623 624 625 626 627 628 629 630 631 632
	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);
633 634

	va_end(args);
Linus Torvalds's avatar
Linus Torvalds committed
635 636 637 638 639
}

static char print_tb_buf[2048];

/* this stores initial state of tree balance in the print_tb_buf */
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
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);

658
	for (h = 0; h < ARRAY_SIZE(tb->insert_size); h++) {
659 660 661 662 663 664 665 666 667 668 669 670 671 672
		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),
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 679 680 681 682 683 684 685 686
			(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));
Linus Torvalds's avatar
Linus Torvalds committed
687 688
	}

689 690 691 692 693
	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],
694 695 696
		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]);
697 698 699 700 701 702 703 704 705 706

	/* 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]);
Linus Torvalds's avatar
Linus Torvalds committed
707

708 709 710
	sprintf(print_tb_buf + strlen(print_tb_buf),
		"=====================================================================\n"
		"FEB list: ");
Linus Torvalds's avatar
Linus Torvalds committed
711

712 713
	/* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
	h = 0;
714
	for (i = 0; i < ARRAY_SIZE(tb->FEB); i++)
715 716 717 718
		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,
719
			tb->FEB[i] ? atomic_read(&tb->FEB[i]->b_count) : 0,
720
			(i == ARRAY_SIZE(tb->FEB) - 1) ? "\n" : ", ");
Linus Torvalds's avatar
Linus Torvalds committed
721

722 723
	sprintf(print_tb_buf + strlen(print_tb_buf),
		"======================== the end ====================================\n");
Linus Torvalds's avatar
Linus Torvalds committed
724 725
}

726 727 728 729
void print_cur_tb(char *mes)
{
	printk("%s\n%s", mes, print_tb_buf);
}
Linus Torvalds's avatar
Linus Torvalds committed
730

731
static void check_leaf_block_head(struct buffer_head *bh)
Linus Torvalds's avatar
Linus Torvalds committed
732
{
733 734 735 736 737 738
	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)
739
		reiserfs_panic(NULL, "vs-6010", "invalid item number %z",
740 741
			       bh);
	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);
Linus Torvalds's avatar
Linus Torvalds committed
744 745 746

}

747 748 749 750 751 752
static void check_internal_block_head(struct buffer_head *bh)
{
	struct block_head *blkh;

	blkh = B_BLK_HEAD(bh);
	if (!(B_LEVEL(bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL(bh) <= MAX_HEIGHT))
753
		reiserfs_panic(NULL, "vs-6025", "invalid level %z", bh);
754 755

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

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

}
Linus Torvalds's avatar
Linus Torvalds committed
764

765
void check_leaf(struct buffer_head *bh)
Linus Torvalds's avatar
Linus Torvalds committed
766
{
767 768 769 770 771 772
	int i;
	struct item_head *ih;

	if (!bh)
		return;
	check_leaf_block_head(bh);
773 774
	for (i = 0, ih = item_head(bh, 0); i < B_NR_ITEMS(bh); i++, ih++)
		op_check_item(ih, ih_item_body(bh, ih));
Linus Torvalds's avatar
Linus Torvalds committed
775 776
}

777 778 779 780 781 782
void check_internal(struct buffer_head *bh)
{
	if (!bh)
		return;
	check_internal_block_head(bh);
}
Linus Torvalds's avatar
Linus Torvalds committed
783

784
void print_statistics(struct super_block *s)
Linus Torvalds's avatar
Linus Torvalds committed
785 786
{

787 788 789 790 791 792 793
	/*
	   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);
	 */
Linus Torvalds's avatar
Linus Torvalds committed
794 795

}