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