/* return 1 if this is not super block */ static int print_super_block(struct buffer_head *bh) { struct reiserfs_super_block *rs = (struct reiserfs_super_block *)(bh->b_data); int skipped, data_blocks; char *version; char b[BDEVNAME_SIZE]; if (is_reiserfs_3_5(rs)) { version = "3.5"; } else if (is_reiserfs_3_6(rs)) { version = "3.6"; } else if (is_reiserfs_jr(rs)) { version = ((sb_version(rs) == REISERFS_VERSION_2) ? "3.6" : "3.5"); } else { return 1; } printk("%s\'s super block is in block %llu\n", bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr); printk("Reiserfs version %s\n", version); printk("Block count %u\n", sb_block_count(rs)); printk("Blocksize %d\n", sb_blocksize(rs)); printk("Free blocks %u\n", sb_free_blocks(rs)); // FIXME: this would be confusing if // someone stores reiserfs super block in some data block ;) // skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs); skipped = bh->b_blocknr; data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) - (!is_reiserfs_jr(rs) ? sb_jp_journal_size(rs) + 1 : sb_reserved_for_journal(rs)) - sb_free_blocks(rs); printk ("Busy blocks (skipped %d, bitmaps - %d, journal (or reserved) blocks - %d\n" "1 super block, %d data blocks\n", skipped, sb_bmap_nr(rs), (!is_reiserfs_jr(rs) ? (sb_jp_journal_size(rs) + 1) : sb_reserved_for_journal(rs)), data_blocks); printk("Root block %u\n", sb_root_block(rs)); printk("Journal block (first) %d\n", sb_jp_journal_1st_block(rs)); printk("Journal dev %d\n", sb_jp_journal_dev(rs)); printk("Journal orig size %d\n", sb_jp_journal_size(rs)); printk("FS state %d\n", sb_fs_state(rs)); printk("Hash function \"%s\"\n", reiserfs_hashname(sb_hash_function_code(rs))); printk("Tree height %d\n", sb_tree_height(rs)); return 0; }
/* * Read the super block */ static int read_super_block(struct reiserfs_mount *rmp, int offset) { struct buf *bp; int error, bits; struct reiserfs_super_block *rs; struct reiserfs_sb_info *sbi; uint16_t fs_blocksize; if (offset == REISERFS_OLD_DISK_OFFSET) { reiserfs_log(LOG_DEBUG, "reiserfs/super: read old format super block\n"); } else { reiserfs_log(LOG_DEBUG, "reiserfs/super: read new format super block\n"); } /* Read the super block */ if ((error = bread(rmp->rm_devvp, offset * btodb(REISERFS_BSIZE), REISERFS_BSIZE, NOCRED, &bp)) != 0) { reiserfs_log(LOG_ERR, "can't read device\n"); return (error); } /* Get it from the buffer data */ rs = (struct reiserfs_super_block *)bp->b_data; if (!is_any_reiserfs_magic_string(rs)) { brelse(bp); return (EINVAL); } fs_blocksize = sb_blocksize(rs); brelse(bp); bp = NULL; if (fs_blocksize <= 0) { reiserfs_log(LOG_ERR, "unexpected null block size"); return (EINVAL); } /* Read the super block (for double check) * We can't read the same blkno with a different size: it causes * panic() if INVARIANTS is set. So we keep REISERFS_BSIZE */ if ((error = bread(rmp->rm_devvp, offset * REISERFS_BSIZE / fs_blocksize * btodb(fs_blocksize), REISERFS_BSIZE, NOCRED, &bp)) != 0) { reiserfs_log(LOG_ERR, "can't reread the super block\n"); return (error); } rs = (struct reiserfs_super_block *)bp->b_data; if (sb_blocksize(rs) != fs_blocksize) { reiserfs_log(LOG_ERR, "unexpected block size " "(found=%u, expected=%u)\n", sb_blocksize(rs), fs_blocksize); brelse(bp); return (EINVAL); } reiserfs_log(LOG_DEBUG, "magic: `%s'\n", rs->s_v1.s_magic); reiserfs_log(LOG_DEBUG, "label: `%s'\n", rs->s_label); reiserfs_log(LOG_DEBUG, "block size: %6d\n", sb_blocksize(rs)); reiserfs_log(LOG_DEBUG, "block count: %6u\n", rs->s_v1.s_block_count); reiserfs_log(LOG_DEBUG, "bitmaps number: %6u\n", rs->s_v1.s_bmap_nr); if (rs->s_v1.s_root_block == -1) { log(LOG_ERR, "reiserfs: Unfinished reiserfsck --rebuild-tree run " "detected. Please\n" "run reiserfsck --rebuild-tree and wait for a " "completion. If that\n" "fails, get newer reiserfsprogs package"); brelse(bp); return (EINVAL); } sbi = rmp->rm_reiserfs; sbi->s_blocksize = fs_blocksize; for (bits = 9, fs_blocksize >>= 9; fs_blocksize >>= 1; bits++) ; sbi->s_blocksize_bits = bits; /* Copy the buffer and release it */ sbi->s_rs = malloc(sizeof *rs, M_REISERFSMNT, M_WAITOK | M_ZERO); if (!sbi->s_rs) { reiserfs_log(LOG_ERR, "can not read the super block\n"); brelse(bp); return (ENOMEM); } bcopy(rs, sbi->s_rs, sizeof(struct reiserfs_super_block)); brelse(bp); if (is_reiserfs_jr(rs)) { if (sb_version(rs) == REISERFS_VERSION_2) reiserfs_log(LOG_INFO, "found reiserfs format \"3.6\"" " with non-standard journal"); else if (sb_version(rs) == REISERFS_VERSION_1) reiserfs_log(LOG_INFO, "found reiserfs format \"3.5\"" " with non-standard journal"); else { reiserfs_log(LOG_ERR, "found unknown " "format \"%u\" of reiserfs with non-standard magic", sb_version(rs)); return (EINVAL); } } else { /* * s_version of standard format may contain incorrect * information, so we just look at the magic string */ reiserfs_log(LOG_INFO, "found reiserfs format \"%s\" with standard journal\n", is_reiserfs_3_5(rs) ? "3.5" : "3.6"); } return (0); }