/* 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; }
/* 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; if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) == 0) { version = "3.5"; } else if( strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING)) == 0) { version = "3.6"; } else { return 1; } printk ("%s\'s super block in block %ld\n======================\n", kdevname (bh->b_dev), 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) - (sb_orig_journal_size(rs) + 1) - sb_free_blocks(rs); printk ("Busy blocks (skipped %d, bitmaps - %d, journal blocks - %d\n" "1 super blocks, %d data blocks\n", skipped, sb_bmap_nr(rs), (sb_orig_journal_size(rs) + 1), data_blocks); printk ("Root block %u\n", sb_root_block(rs)); printk ("Journal block (first) %d\n", sb_journal_block(rs)); printk ("Journal dev %d\n", sb_journal_dev(rs)); printk ("Journal orig size %d\n", sb_orig_journal_size(rs)); printk ("Filesystem state %s\n", (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR"); printk ("Hash function \"%s\"\n", sb_hash_function_code(rs) == TEA_HASH ? "tea" : ( sb_hash_function_code(rs) == YURA_HASH ? "rupasov" : (sb_hash_function_code(rs) == R5_HASH ? "r5" : "unknown"))); printk ("Tree height %d\n", sb_tree_height(rs)); return 0; }
// // a portion of this function, particularly the VFS interface portion, // was derived from minix or ext2's analog and evolved as the // prototype did. You should be able to tell which portion by looking // at the ext2 code and comparing. It's subfunctions contain no code // used as a template unless they are so labeled. // static int reiserfs_statfs (struct super_block * s, struct statfs * buf) { struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); /* changed to accomodate gcc folks.*/ buf->f_type = REISERFS_SUPER_MAGIC; buf->f_bsize = s->s_blocksize; buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1; buf->f_bfree = sb_free_blocks(rs); buf->f_bavail = buf->f_bfree; buf->f_files = -1; buf->f_ffree = -1; buf->f_namelen = (REISERFS_MAX_NAME_LEN (s->s_blocksize)); return 0; }
/* * The statfs syscall */ static int reiserfs_statfs(struct mount *mp, struct statfs *sbp) { struct reiserfs_mount *rmp; struct reiserfs_sb_info *sbi; struct reiserfs_super_block *rs; reiserfs_log(LOG_DEBUG, "get private data\n"); rmp = VFSTOREISERFS(mp); sbi = rmp->rm_reiserfs; rs = sbi->s_rs; reiserfs_log(LOG_DEBUG, "fill statfs structure\n"); sbp->f_bsize = sbi->s_blocksize; sbp->f_iosize = sbp->f_bsize; sbp->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1; sbp->f_bfree = sb_free_blocks(rs); sbp->f_bavail = sbp->f_bfree; sbp->f_files = 0; sbp->f_ffree = 0; reiserfs_log(LOG_DEBUG, " block size = %ju\n", (intmax_t)sbp->f_bsize); reiserfs_log(LOG_DEBUG, " IO size = %ju\n", (intmax_t)sbp->f_iosize); reiserfs_log(LOG_DEBUG, " block count = %ju\n", (intmax_t)sbp->f_blocks); reiserfs_log(LOG_DEBUG, " free blocks = %ju\n", (intmax_t)sbp->f_bfree); reiserfs_log(LOG_DEBUG, " avail blocks = %ju\n", (intmax_t)sbp->f_bavail); reiserfs_log(LOG_DEBUG, "...done\n"); if (sbp != &mp->mnt_stat) { reiserfs_log(LOG_DEBUG, "copying monut point info\n"); sbp->f_type = mp->mnt_vfc->vfc_typenum; bcopy((caddr_t)mp->mnt_stat.f_mntonname, (caddr_t)&sbp->f_mntonname[0], MNAMELEN); bcopy((caddr_t)mp->mnt_stat.f_mntfromname, (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); reiserfs_log(LOG_DEBUG, " mount from: %s\n", sbp->f_mntfromname); reiserfs_log(LOG_DEBUG, " mount on: %s\n", sbp->f_mntonname); reiserfs_log(LOG_DEBUG, "...done\n"); } return (0); }
static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, struct inode *inode, b_blocknr_t block, int for_unformatted) { struct super_block * s = th->t_super; struct reiserfs_super_block * rs; struct buffer_head * sbh; struct reiserfs_bitmap_info *apbi; int nr, offset; BUG_ON (!th->t_trans_id); PROC_INFO_INC( s, free_block ); rs = SB_DISK_SUPER_BLOCK (s); sbh = SB_BUFFER_WITH_SB (s); apbi = SB_AP_BITMAP(s); get_bit_address (s, block, &nr, &offset); if (nr >= sb_bmap_nr (rs)) { reiserfs_warning (s, "vs-4075: reiserfs_free_block: " "block %lu is out of range on %s", block, reiserfs_bdevname (s)); return; } reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ; /* clear bit for the given block in bit map */ if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) { reiserfs_warning (s, "vs-4080: reiserfs_free_block: " "free_block (%s:%lu)[dev:blocknr]: bit already cleared", reiserfs_bdevname (s), block); } apbi[nr].free_count ++; journal_mark_dirty (th, s, apbi[nr].bh); reiserfs_prepare_for_journal(s, sbh, 1) ; /* update super block */ set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 ); journal_mark_dirty (th, s, sbh); if (for_unformatted) DQUOT_FREE_BLOCK_NODIRTY(inode, 1); }
static void _reiserfs_free_block (struct reiserfs_transaction_handle *th, b_blocknr_t block) { struct super_block * s = th->t_super; struct reiserfs_super_block * rs; struct buffer_head * sbh; struct reiserfs_bitmap_info *apbi; int nr, offset; PROC_INFO_INC( s, free_block ); rs = SB_DISK_SUPER_BLOCK (s); sbh = SB_BUFFER_WITH_SB (s); apbi = SB_AP_BITMAP(s); get_bit_address (s, block, &nr, &offset); if (nr >= sb_bmap_nr (rs)) { reiserfs_warning ("vs-4075: reiserfs_free_block: " "block %lu is out of range on %s\n", block, bdevname(s->s_dev)); return; } reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ; /* clear bit for the given block in bit map */ if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) { reiserfs_warning ("vs-4080: reiserfs_free_block: " "free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n", s->s_dev, block); } if (offset < apbi[nr].first_zero_hint) { apbi[nr].first_zero_hint = offset; } apbi[nr].free_count ++; journal_mark_dirty (th, s, apbi[nr].bh); reiserfs_prepare_for_journal(s, sbh, 1) ; /* update super block */ set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 ); journal_mark_dirty (th, s, sbh); }
/* I wonder if it would be less modest now that we use journaling. -Hans */ void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block) { struct super_block * s = th->t_super; struct reiserfs_super_block * rs; struct buffer_head * sbh; struct buffer_head ** apbh; int nr, offset; RFALSE(!s, "vs-4060: trying to free block on nonexistent device"); RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block"); PROC_INFO_INC( s, free_block ); rs = SB_DISK_SUPER_BLOCK (s); sbh = SB_BUFFER_WITH_SB (s); apbh = SB_AP_BITMAP (s); get_bit_address (s, block, &nr, &offset); /* mark it before we clear it, just in case */ journal_mark_freed(th, s, block) ; reiserfs_prepare_for_journal(s, apbh[nr], 1 ) ; /* clear bit for the given block in bit map */ if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) { reiserfs_warning ("vs-4080: reiserfs_free_block: " "free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n", s->s_dev, block); } journal_mark_dirty (th, s, apbh[nr]); reiserfs_prepare_for_journal(s, sbh, 1) ; /* update super block */ set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 ); journal_mark_dirty (th, s, sbh); s->s_dirt = 1; }