Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
  3  */
  4 
  5 #include <linux/config.h>
  6 #include <linux/time.h>
  7 #include <linux/fs.h>
  8 #include <linux/reiserfs_fs.h>
  9 #include <linux/string.h>
 10 #include <linux/buffer_head.h>
 11 
 12 #include <stdarg.h>
 13 
 14 static char error_buf[1024];
 15 static char fmt_buf[1024];
 16 static char off_buf[80];
 17 
 18 
 19 static char * reiserfs_cpu_offset (struct cpu_key * key)
 20 {
 21   if (cpu_key_k_type(key) == TYPE_DIRENTRY)
 22     sprintf (off_buf, "%Lu(%Lu)", 
 23              (unsigned long long)GET_HASH_VALUE (cpu_key_k_offset (key)),
 24              (unsigned long long)GET_GENERATION_NUMBER (cpu_key_k_offset (key)));
 25   else
 26     sprintf (off_buf, "0x%Lx", (unsigned long long)cpu_key_k_offset (key));
 27   return off_buf;
 28 }
 29 
 30 
 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)GET_HASH_VALUE (le_key_k_offset (version, key)),
 39              (unsigned long long)GET_GENERATION_NUMBER (le_key_k_offset (version, key)));
 40   else
 41     sprintf (off_buf, "0x%Lx", (unsigned long long)le_key_k_offset (version, key));
 42   return off_buf;
 43 }
 44 
 45 
 46 static char * cpu_type (struct cpu_key * key)
 47 {
 48     if (cpu_key_k_type (key) == TYPE_STAT_DATA)
 49         return "SD";
 50     if (cpu_key_k_type (key) == TYPE_DIRENTRY)
 51         return "DIR";
 52     if (cpu_key_k_type (key) == TYPE_DIRECT)
 53         return "DIRECT";
 54     if (cpu_key_k_type (key) == TYPE_INDIRECT)
 55         return "IND";
 56     return "UNKNOWN";
 57 }
 58 
 59 
 60 static char * le_type (struct reiserfs_key * key)
 61 {
 62     int version;
 63     
 64     version = le_key_version (key);
 65 
 66     if (le_key_k_type (version, key) == TYPE_STAT_DATA)
 67         return "SD";
 68     if (le_key_k_type (version, key) == TYPE_DIRENTRY)
 69         return "DIR";
 70     if (le_key_k_type (version, key) == TYPE_DIRECT)
 71         return "DIRECT";
 72     if (le_key_k_type (version, key) == TYPE_INDIRECT)
 73         return "IND";
 74     return "UNKNOWN";
 75 }
 76 
 77 
 78 /* %k */
 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), le_type (key));
 84   else
 85     sprintf (buf, "[NULL]");
 86 }
 87 
 88 
 89 /* %K */
 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 
100 static void sprintf_de_head( char *buf, struct reiserfs_de_head *deh )
101 {
102     if( deh )
103         sprintf( buf, "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", deh_offset(deh), deh_dir_id(deh),
104                  deh_objectid(deh), deh_location(deh), deh_state(deh) );
105     else
106         sprintf( buf, "[NULL]" );
107 
108 }
109 
110 static void sprintf_item_head (char * buf, struct item_head * ih)
111 {
112     if (ih) {
113         strcpy (buf, (ih_version (ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*");
114         sprintf_le_key (buf + strlen (buf), &(ih->ih_key));
115         sprintf (buf + strlen (buf), ", item_len %d, item_location %d, "
116                  "free_space(entry_count) %d",
117                  ih_item_len(ih), ih_location(ih), ih_free_space (ih));
118     } else
119         sprintf (buf, "[NULL]");
120 }
121 
122 
123 static void sprintf_direntry (char * buf, struct reiserfs_dir_entry * de)
124 {
125   char name[20];
126 
127   memcpy (name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen);
128   name [de->de_namelen > 19 ? 19 : de->de_namelen] = 0;
129   sprintf (buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid);
130 }
131 
132 
133 static void sprintf_block_head (char * buf, struct buffer_head * bh)
134 {
135   sprintf (buf, "level=%d, nr_items=%d, free_space=%d rdkey ",
136            B_LEVEL (bh), B_NR_ITEMS (bh), B_FREE_SPACE (bh));
137 }
138 
139 
140 static void sprintf_buffer_head (char * buf, struct buffer_head * bh) 
141 {
142   char b[BDEVNAME_SIZE];
143 
144   sprintf (buf, "dev %s, size %d, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)",
145            bdevname (bh->b_bdev, b), bh->b_size,
146            (unsigned long long)bh->b_blocknr,
147            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 
154 
155 static void sprintf_disk_child (char * buf, struct disk_child * dc)
156 {
157   sprintf (buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), dc_size(dc));
158 }
159 
160 
161 static char * is_there_reiserfs_struct (char * fmt, int * what, int * skip)
162 {
163   char * k = fmt;
164 
165   *skip = 0;
166   
167   while ((k = strchr (k, '%')) != NULL)
168   {
169     if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
170               k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a' ) {
171       *what = k[1];
172       break;
173     }
174     (*skip) ++;
175     k ++;
176   }
177   return k;
178 }
179 
180 
181 /* debugging reiserfs we used to print out a lot of different
182    variables, like keys, item headers, buffer heads etc. Values of
183    most fields matter. So it took a long time just to write
184    appropriative printk. With this reiserfs_warning you can use format
185    specification for complex structures like you used to do with
186    printfs for integers, doubles and pointers. For instance, to print
187    out key structure you have to write just: 
188    reiserfs_warning ("bad key %k", key); 
189    instead of 
190    printk ("bad key %lu %lu %lu %lu", key->k_dir_id, key->k_objectid, 
191            key->k_offset, key->k_uniqueness); 
192 */
193 
194 
195 static void
196 prepare_error_buf( const char *fmt, va_list args )
197 {
198     char * fmt1 = fmt_buf;
199     char * k;
200     char * p = error_buf;
201     int i, j, what, skip;
202 
203     strcpy (fmt1, fmt);
204 
205     while( (k = is_there_reiserfs_struct( fmt1, &what, &skip )) != NULL )
206     {
207         *k = 0;
208 
209         p += vsprintf (p, fmt1, args);
210 
211         for (i = 0; i < skip; i ++)
212             j = va_arg (args, int);
213 
214         switch (what) {
215         case 'k':
216             sprintf_le_key (p, va_arg(args, struct reiserfs_key *));
217             break;
218         case 'K':
219             sprintf_cpu_key (p, va_arg(args, struct cpu_key *));
220             break;
221         case 'h':
222             sprintf_item_head (p, va_arg(args, struct item_head *));
223             break;
224         case 't':
225             sprintf_direntry (p, va_arg(args, struct reiserfs_dir_entry *));
226             break;
227         case 'y':
228             sprintf_disk_child (p, va_arg(args, struct disk_child *));
229             break;
230         case 'z':
231             sprintf_block_head (p, va_arg(args, struct buffer_head *));
232             break;
233         case 'b':
234             sprintf_buffer_head (p, va_arg(args, struct buffer_head *));
235             break;
236         case 'a':
237             sprintf_de_head (p, va_arg(args, struct reiserfs_de_head *));
238             break;
239         }
240 
241         p += strlen (p);
242         fmt1 = k + 2;
243     }
244     vsprintf (p, fmt1, args);
245 
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 
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 */
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 */
289 static void reiserfs_printk (const char * fmt, ...)
290 {
291   do_reiserfs_warning(fmt);
292   printk (error_buf);
293 }
294 
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 
353 #ifdef CONFIG_REISERFS_CHECK
354 extern struct tree_balance * cur_tb;
355 #endif
356 
357 void reiserfs_panic (struct super_block * sb, const char * fmt, ...)
358 {
359   do_reiserfs_warning(fmt);
360   printk (KERN_EMERG "REISERFS: panic (device %s): %s\n",
361           reiserfs_bdevname (sb), error_buf);
362   BUG ();
363 
364   /* this is not actually called, but makes reiserfs_panic() "noreturn" */
365   panic ("REISERFS: panic (device %s): %s\n",
366          reiserfs_bdevname (sb), error_buf);
367 }
368 
369 void
370 reiserfs_abort (struct super_block *sb, int errno, const char *fmt, ...)
371 {
372     do_reiserfs_warning (fmt);
373 
374     if (reiserfs_error_panic (sb)) {
375         panic (KERN_CRIT "REISERFS: panic (device %s): %s\n",
376                reiserfs_bdevname (sb), error_buf);
377     }
378 
379     if (sb->s_flags & MS_RDONLY)
380         return;
381 
382     printk (KERN_CRIT "REISERFS: abort (device %s): %s\n",
383             reiserfs_bdevname (sb), error_buf);
384 
385     sb->s_flags |= MS_RDONLY;
386     reiserfs_journal_abort (sb, errno);
387 }
388 
389 /* this prints internal nodes (4 keys/items in line) (dc_number,
390    dc_size)[k_dirid, k_objectid, k_offset, k_uniqueness](dc_number,
391    dc_size)...*/
392 static int print_internal (struct buffer_head * bh, int first, int last)
393 {
394     struct reiserfs_key * key;
395     struct disk_child * dc;
396     int i;
397     int from, to;
398     
399     if (!B_IS_KEYS_LEVEL (bh))
400         return 1;
401 
402     check_internal (bh);
403     
404     if (first == -1) {
405         from = 0;
406         to = B_NR_ITEMS (bh);
407     } else {
408         from = first;
409         to = last < B_NR_ITEMS (bh) ? last : B_NR_ITEMS (bh);
410     }
411 
412     reiserfs_printk ("INTERNAL NODE (%ld) contains %z\n",  bh->b_blocknr, bh);
413     
414     dc = B_N_CHILD (bh, from);
415     reiserfs_printk ("PTR %d: %y ", from, dc);
416     
417     for (i = from, key = B_N_PDELIM_KEY (bh, from), dc ++; i < to; i ++, key ++, dc ++) {
418         reiserfs_printk ("KEY %d: %k PTR %d: %y ", i, key, i + 1, dc);
419         if (i && i % 4 == 0)
420             printk ("\n");
421     }
422     printk ("\n");
423     return 0;
424 }
425 
426 
427 
428 
429 
430 static int print_leaf (struct buffer_head * bh, int print_mode, int first, int last)
431 {
432     struct block_head * blkh;
433     struct item_head * ih;
434     int i, nr;
435     int from, to;
436 
437     if (!B_IS_ITEMS_LEVEL (bh))
438         return 1;
439 
440     check_leaf (bh);
441 
442     blkh = B_BLK_HEAD (bh);
443     ih = B_N_PITEM_HEAD (bh,0);
444     nr = blkh_nr_item(blkh);
445 
446     printk ("\n===================================================================\n");
447     reiserfs_printk ("LEAF NODE (%ld) contains %z\n", bh->b_blocknr, bh);
448 
449     if (!(print_mode & PRINT_LEAF_ITEMS)) {
450         reiserfs_printk ("FIRST ITEM_KEY: %k, LAST ITEM KEY: %k\n",
451                           &(ih->ih_key), &((ih + nr - 1)->ih_key));
452         return 0;
453     }
454 
455     if (first < 0 || first > nr - 1) 
456         from = 0;
457     else 
458         from = first;
459 
460     if (last < 0 || last > nr )
461         to = nr;
462     else
463         to = last;
464 
465     ih += from;
466     printk ("-------------------------------------------------------------------------------\n");
467     printk ("|##|   type    |           key           | ilen | free_space | version | loc  |\n");
468     for (i = from; i < to; i++, ih ++) {
469         printk ("-------------------------------------------------------------------------------\n");
470         reiserfs_printk ("|%2d| %h |\n", i, ih);
471         if (print_mode & PRINT_LEAF_ITEMS)
472             op_print_item (ih, B_I_PITEM (bh, ih));
473     }
474 
475     printk ("===================================================================\n");
476 
477     return 0;
478 }
479 
480 char * reiserfs_hashname(int code)
481 {
482     if ( code == YURA_HASH)
483         return "rupasov";
484     if ( code == TEA_HASH)
485         return "tea";
486     if ( code == R5_HASH)
487         return "r5";
488 
489     return "unknown";
490 }
491 
492 /* return 1 if this is not super block */
493 static int print_super_block (struct buffer_head * bh)
494 {
495     struct reiserfs_super_block * rs = (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) + 1 : sb_reserved_for_journal(rs)) -      
523             sb_free_blocks(rs);
524     printk ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n"
525             "1 super block, %d data blocks\n", 
526             skipped, sb_bmap_nr(rs), (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) :
527                                       sb_reserved_for_journal(rs)) , data_blocks);
528     printk ("Root block %u\n", sb_root_block(rs));
529     printk ("Journal block (first) %d\n", sb_jp_journal_1st_block(rs));
530     printk ("Journal dev %d\n", sb_jp_journal_dev(rs));
531     printk ("Journal orig size %d\n", sb_jp_journal_size(rs));
532     printk ("FS state %d\n", sb_fs_state(rs));
533     printk ("Hash function \"%s\"\n",
534             reiserfs_hashname(sb_hash_function_code(rs)));
535     
536     printk ("Tree height %d\n", sb_tree_height(rs));
537     return 0;
538 }
539 
540 static int print_desc_block (struct buffer_head * bh)
541 {
542     struct reiserfs_journal_desc * desc;
543 
544     if (memcmp(get_journal_desc_magic (bh), JOURNAL_DESC_MAGIC, 8))
545         return 1;
546 
547     desc = (struct reiserfs_journal_desc *)(bh->b_data);
548     printk ("Desc block %llu (j_trans_id %d, j_mount_id %d, j_len %d)",
549             (unsigned long long)bh->b_blocknr, get_desc_trans_id (desc), get_desc_mount_id (desc),
550             get_desc_trans_len (desc));
551 
552     return 0;
553 }
554 
555 
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 ("Block %llu contains unformatted data\n", (unsigned long long)bh->b_blocknr);
576 }
577 
578 
579 
580 static char print_tb_buf[2048];
581 
582 /* this stores initial state of tree balance in the print_tb_buf */
583 void store_print_tb (struct tree_balance * tb)
584 {
585     int h = 0;
586     int i;
587     struct buffer_head * tbSh, * tbFh;
588 
589     if (!tb)
590         return;
591 
592     sprintf (print_tb_buf, "\n"
593              "BALANCING %d\n"
594              "MODE=%c, ITEM_POS=%d POS_IN_ITEM=%d\n" 
595              "=====================================================================\n"
596              "* h *    S    *    L    *    R    *   F   *   FL  *   FR  *  CFL  *  CFR  *\n",
597              REISERFS_SB(tb->tb_sb)->s_do_balance,
598              tb->tb_mode, PATH_LAST_POSITION (tb->tb_path), tb->tb_path->pos_in_item);
599   
600     for (h = 0; h < sizeof(tb->insert_size) / sizeof (tb->insert_size[0]); h ++) {
601         if (PATH_H_PATH_OFFSET (tb->tb_path, h) <= tb->tb_path->path_length && 
602             PATH_H_PATH_OFFSET (tb->tb_path, h) > ILLEGAL_PATH_ELEMENT_OFFSET) {
603             tbSh = PATH_H_PBUFFER (tb->tb_path, h);
604             tbFh = PATH_H_PPARENT (tb->tb_path, h);
605         } else {
606             tbSh = NULL;
607             tbFh = NULL;
608         }
609         sprintf (print_tb_buf + strlen (print_tb_buf),
610                  "* %d * %3lld(%2d) * %3lld(%2d) * %3lld(%2d) * %5lld * %5lld * %5lld * %5lld * %5lld *\n",
611                  h, 
612                  (tbSh) ? (long long)(tbSh->b_blocknr):(-1LL),
613                  (tbSh) ? atomic_read (&(tbSh->b_count)) : -1,
614                  (tb->L[h]) ? (long long)(tb->L[h]->b_blocknr):(-1LL),
615                  (tb->L[h]) ? atomic_read (&(tb->L[h]->b_count)) : -1,
616                  (tb->R[h]) ? (long long)(tb->R[h]->b_blocknr):(-1LL),
617                  (tb->R[h]) ? atomic_read (&(tb->R[h]->b_count)) : -1,
618                  (tbFh) ? (long long)(tbFh->b_blocknr):(-1LL),
619                  (tb->FL[h]) ? (long long)(tb->FL[h]->b_blocknr):(-1LL),
620                  (tb->FR[h]) ? (long long)(tb->FR[h]->b_blocknr):(-1LL),
621                  (tb->CFL[h]) ? (long long)(tb->CFL[h]->b_blocknr):(-1LL),
622                  (tb->CFR[h]) ? (long long)(tb->CFR[h]->b_blocknr):(-1LL));
623     }
624 
625     sprintf (print_tb_buf + strlen (print_tb_buf), 
626              "=====================================================================\n"
627              "* h * size * ln * lb * rn * rb * blkn * s0 * s1 * s1b * s2 * s2b * curb * lk * rk *\n"
628              "* 0 * %4d * %2d * %2d * %2d * %2d * %4d * %2d * %2d * %3d * %2d * %3d * %4d * %2d * %2d *\n",
629              tb->insert_size[0], tb->lnum[0], tb->lbytes, tb->rnum[0],tb->rbytes, tb->blknum[0], 
630              tb->s0num, tb->s1num,tb->s1bytes,  tb->s2num, tb->s2bytes, tb->cur_blknum, tb->lkey[0], tb->rkey[0]);
631 
632     /* this prints balance parameters for non-leaf levels */
633     h = 0;
634     do {
635         h++;
636         sprintf (print_tb_buf + strlen (print_tb_buf),
637                  "* %d * %4d * %2d *    * %2d *    * %2d *\n",
638                 h, tb->insert_size[h], tb->lnum[h], tb->rnum[h], tb->blknum[h]);
639     } while (tb->insert_size[h]);
640 
641     sprintf (print_tb_buf + strlen (print_tb_buf), 
642              "=====================================================================\n"
643              "FEB list: ");
644 
645     /* print FEB list (list of buffers in form (bh (b_blocknr, b_count), that will be used for new nodes) */
646     h = 0;
647     for (i = 0; i < sizeof (tb->FEB) / sizeof (tb->FEB[0]); i ++)
648         sprintf (print_tb_buf + strlen (print_tb_buf),
649                  "%p (%llu %d)%s", tb->FEB[i], tb->FEB[i] ? (unsigned long long)tb->FEB[i]->b_blocknr : 0ULL,
650                  tb->FEB[i] ? atomic_read (&(tb->FEB[i]->b_count)) : 0, 
651                  (i == sizeof (tb->FEB) / sizeof (tb->FEB[0]) - 1) ? "\n" : ", ");
652 
653     sprintf (print_tb_buf + strlen (print_tb_buf), 
654              "======================== the end ====================================\n");
655 }
656 
657 void print_cur_tb (char * mes)
658 {
659     printk ("%s\n%s", mes, print_tb_buf);
660 }
661 
662 static void check_leaf_block_head (struct buffer_head * bh)
663 {
664   struct block_head * blkh;
665   int nr;
666 
667   blkh = B_BLK_HEAD (bh);
668   nr = blkh_nr_item(blkh);
669   if ( nr > (bh->b_size - BLKH_SIZE) / IH_SIZE)
670     reiserfs_panic (NULL, "vs-6010: check_leaf_block_head: invalid item number %z", bh);
671   if ( blkh_free_space(blkh) > 
672       bh->b_size - BLKH_SIZE - IH_SIZE * nr )
673     reiserfs_panic (NULL, "vs-6020: check_leaf_block_head: invalid free space %z", bh);
674     
675 }
676 
677 static void check_internal_block_head (struct buffer_head * bh)
678 {
679     struct block_head * blkh;
680     
681     blkh = B_BLK_HEAD (bh);
682     if (!(B_LEVEL (bh) > DISK_LEAF_NODE_LEVEL && B_LEVEL (bh) <= MAX_HEIGHT))
683         reiserfs_panic (NULL, "vs-6025: check_internal_block_head: invalid level %z", bh);
684 
685     if (B_NR_ITEMS (bh) > (bh->b_size - BLKH_SIZE) / IH_SIZE)
686         reiserfs_panic (NULL, "vs-6030: check_internal_block_head: invalid item number %z", bh);
687 
688     if (B_FREE_SPACE (bh) != 
689         bh->b_size - BLKH_SIZE - KEY_SIZE * B_NR_ITEMS (bh) - DC_SIZE * (B_NR_ITEMS (bh) + 1))
690         reiserfs_panic (NULL, "vs-6040: check_internal_block_head: invalid free space %z", bh);
691 
692 }
693 
694 
695 void check_leaf (struct buffer_head * bh)
696 {
697     int i;
698     struct item_head * ih;
699 
700     if (!bh)
701         return;
702     check_leaf_block_head (bh);
703     for (i = 0, ih = B_N_PITEM_HEAD (bh, 0); i < B_NR_ITEMS (bh); i ++, ih ++)
704         op_check_item (ih, B_I_PITEM (bh, ih));
705 }
706 
707 
708 void check_internal (struct buffer_head * bh)
709 {
710   if (!bh)
711     return;
712   check_internal_block_head (bh);
713 }
714 
715 
716 void print_statistics (struct super_block * s)
717 {
718 
719   /*
720   printk ("reiserfs_put_super: session statistics: balances %d, fix_nodes %d, \
721 bmap with search %d, without %d, dir2ind %d, ind2dir %d\n",
722           REISERFS_SB(s)->s_do_balance, REISERFS_SB(s)->s_fix_nodes,
723           REISERFS_SB(s)->s_bmaps, REISERFS_SB(s)->s_bmaps_without_search,
724           REISERFS_SB(s)->s_direct2indirect, REISERFS_SB(s)->s_indirect2direct);
725   */
726 
727 }
728 
  This page was automatically generated by the LXR engine.