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