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/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 
 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 
 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 
 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 
 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 */
 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 */
 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,
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 
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 
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 
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 
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 
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 
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 
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 
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 #ifdef CONFIG_REISERFS_CHECK
353 extern struct tree_balance *cur_tb;
354 #endif
355 
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 
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)...*/
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 
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 
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 */
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 
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 
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 */
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 
671 void print_cur_tb(char *mes)
672 {
673         printk("%s\n%s", mes, print_tb_buf);
674 }
675 
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 
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 
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 
730 void check_internal(struct buffer_head *bh)
731 {
732         if (!bh)
733                 return;
734         check_internal_block_head(bh);
735 }
736 
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 
  This page was automatically generated by the LXR engine.