From: "Aneesh Kumar K.V" Subject: [RFC PATCH 1/3] ext4: Add blocks added during resize to bitmap Date: Fri, 24 Oct 2008 12:04:25 +0530 Message-ID: <1224830067-22963-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com> Cc: linux-ext4@vger.kernel.org, "Aneesh Kumar K.V" To: cmm@us.ibm.com, tytso@mit.edu, frederic.bohe@bull.net Return-path: Received: from e28smtp03.in.ibm.com ([59.145.155.3]:44591 "EHLO e28smtp03.in.ibm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751040AbYJXGei (ORCPT ); Fri, 24 Oct 2008 02:34:38 -0400 Received: from d28relay02.in.ibm.com (d28relay02.in.ibm.com [9.184.220.59]) by e28smtp03.in.ibm.com (8.13.1/8.13.1) with ESMTP id m9O6YUos002212 for ; Fri, 24 Oct 2008 12:04:30 +0530 Received: from d28av04.in.ibm.com (d28av04.in.ibm.com [9.184.220.66]) by d28relay02.in.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id m9O6YTaE593996 for ; Fri, 24 Oct 2008 12:04:29 +0530 Received: from d28av04.in.ibm.com (loopback [127.0.0.1]) by d28av04.in.ibm.com (8.13.1/8.13.3) with ESMTP id m9O6YSr7004896 for ; Fri, 24 Oct 2008 17:34:29 +1100 Sender: linux-ext4-owner@vger.kernel.org List-ID: With this change new blocks added during resize are marked as free in the block bitmap and the group is flagged with EXT4_GROUP_INFO_NEED_INIT_BIT flag. This make sure when mballoc tries to allocate blocks from the new group we would reload the buddy information using the bitmap present in the disk. Signed-off-by: Aneesh Kumar K.V --- fs/ext4/balloc.c | 52 +++++++++++++++------------------------------------- fs/ext4/ext4.h | 2 +- fs/ext4/resize.c | 10 ++-------- 3 files changed, 18 insertions(+), 46 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index b9821be..b67f1ff 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -20,6 +20,7 @@ #include "ext4.h" #include "ext4_jbd2.h" #include "group.h" +#include "mballoc.h" /* * balloc.c contains the blocks allocation and deallocation routines @@ -350,21 +351,18 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group) } /** - * ext4_free_blocks_sb() -- Free given blocks and update quota + * ext4_add_groupblocks() -- Add given blocks to an existing group and update quota * @handle: handle to this transaction * @sb: super block * @block: start physcial block to free * @count: number of blocks to free * @pdquot_freed_blocks: pointer to quota * - * XXX This function is only used by the on-line resizing code, which - * should probably be fixed up to call the mballoc variant. There - * this needs to be cleaned up later; in fact, I'm not convinced this - * is 100% correct in the face of the mballoc code. The online resizing - * code needs to be fixed up to more tightly (and correctly) interlock - * with the mballoc code. + * This marks the blocks as free in the bitmap. We ask the + * mballoc to reload the buddy after this by setting group + * EXT4_GROUP_INFO_NEED_INIT_BIT flag */ -void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, +void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, ext4_fsblk_t block, unsigned long count, unsigned long *pdquot_freed_blocks) { @@ -379,6 +377,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, struct ext4_sb_info *sbi; int err = 0, ret; ext4_grpblk_t group_freed; + struct ext4_group_info *grp; *pdquot_freed_blocks = 0; sbi = EXT4_SB(sb); @@ -419,7 +418,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, in_range(block + count - 1, ext4_inode_table(sb, desc), sbi->s_itb_per_group)) { ext4_error(sb, "ext4_free_blocks", - "Freeing blocks in system zones - " + "Adding blocks in system zones - " "Block = %llu, count = %lu", block, count); goto error_return; @@ -472,35 +471,7 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, cond_resched(); jbd_lock_bh_state(bitmap_bh); } - /* @@@ This prevents newly-allocated data from being - * freed and then reallocated within the same - * transaction. - * - * Ideally we would want to allow that to happen, but to - * do so requires making jbd2_journal_forget() capable of - * revoking the queued write of a data block, which - * implies blocking on the journal lock. *forget() - * cannot block due to truncate races. - * - * Eventually we can fix this by making jbd2_journal_forget() - * return a status indicating whether or not it was able - * to revoke the buffer. On successful revoke, it is - * safe not to set the allocation bit in the committed - * bitmap, because we know that there is no outstanding - * activity on the buffer any more and so it is safe to - * reallocate it. - */ - BUFFER_TRACE(bitmap_bh, "set in b_committed_data"); - J_ASSERT_BH(bitmap_bh, - bh2jh(bitmap_bh)->b_committed_data != NULL); - ext4_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, - bh2jh(bitmap_bh)->b_committed_data); - /* - * We clear the bit in the bitmap after setting the committed - * data bit, because this is the reverse order to that which - * the allocator uses. - */ BUFFER_TRACE(bitmap_bh, "clear bit"); if (!ext4_clear_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i, bitmap_bh->b_data)) { @@ -545,6 +516,13 @@ void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, goto do_more; } sb->s_dirt = 1; + /* + * request to reload the buddy with the + * new bitmap information + */ + grp = ext4_get_group_info(sb, block_group); + set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state)); + ext4_mb_update_group_info(grp, count); error_return: brelse(bitmap_bh); ext4_std_error(sb, err); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 3882a6c..ca915d5 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1024,7 +1024,7 @@ extern ext4_fsblk_t ext4_has_free_blocks(struct ext4_sb_info *sbi, s64 nblocks); extern void ext4_free_blocks(handle_t *handle, struct inode *inode, ext4_fsblk_t block, unsigned long count, int metadata); -extern void ext4_free_blocks_sb(handle_t *handle, struct super_block *sb, +extern void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, ext4_fsblk_t block, unsigned long count, unsigned long *pdquot_freed_blocks); extern ext4_fsblk_t ext4_count_free_blocks(struct super_block *); diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index b6ec184..a8403a8 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c @@ -977,7 +977,6 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, int err; unsigned long freed_blocks; ext4_group_t group; - struct ext4_group_info *grp; /* We don't need to worry about locking wrt other resizers just * yet: we're going to revalidate es->s_blocks_count after @@ -1076,7 +1075,8 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, unlock_super(sb); ext4_debug("freeing blocks %llu through %llu\n", o_blocks_count, o_blocks_count + add); - ext4_free_blocks_sb(handle, sb, o_blocks_count, add, &freed_blocks); + /* We add the blocks to the bitmap and set the group need init bit */ + ext4_add_groupblocks(handle, sb, o_blocks_count, add, &freed_blocks); ext4_debug("freed blocks %llu through %llu\n", o_blocks_count, o_blocks_count + add); if ((err = ext4_journal_stop(handle))) @@ -1119,12 +1119,6 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es, ClearPageUptodate(page); page_cache_release(page); } - - /* Get the info on the last group */ - grp = ext4_get_group_info(sb, group);