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; }