aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/mballoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/mballoc.c')
-rw-r--r--fs/ext4/mballoc.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index 307d447bbc43..65329f148da5 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -4706,9 +4706,7 @@ error_return:
4706 * @block: start physcial block to add to the block group 4706 * @block: start physcial block to add to the block group
4707 * @count: number of blocks to free 4707 * @count: number of blocks to free
4708 * 4708 *
4709 * This marks the blocks as free in the bitmap. We ask the 4709 * This marks the blocks as free in the bitmap and buddy.
4710 * mballoc to reload the buddy after this by setting group
4711 * EXT4_GROUP_INFO_NEED_INIT_BIT flag
4712 */ 4710 */
4713void ext4_add_groupblocks(handle_t *handle, struct super_block *sb, 4711void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
4714 ext4_fsblk_t block, unsigned long count) 4712 ext4_fsblk_t block, unsigned long count)
@@ -4720,6 +4718,7 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
4720 unsigned int i; 4718 unsigned int i;
4721 struct ext4_group_desc *desc; 4719 struct ext4_group_desc *desc;
4722 struct ext4_sb_info *sbi = EXT4_SB(sb); 4720 struct ext4_sb_info *sbi = EXT4_SB(sb);
4721 struct ext4_buddy e4b;
4723 int err = 0, ret, blk_free_count; 4722 int err = 0, ret, blk_free_count;
4724 ext4_grpblk_t blocks_freed; 4723 ext4_grpblk_t blocks_freed;
4725 struct ext4_group_info *grp; 4724 struct ext4_group_info *grp;
@@ -4767,15 +4766,10 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
4767 err = ext4_journal_get_write_access(handle, gd_bh); 4766 err = ext4_journal_get_write_access(handle, gd_bh);
4768 if (err) 4767 if (err)
4769 goto error_return; 4768 goto error_return;
4770 /* 4769
4771 * make sure we don't allow a parallel init on other groups in the
4772 * same buddy cache
4773 */
4774 down_write(&grp->alloc_sem);
4775 for (i = 0, blocks_freed = 0; i < count; i++) { 4770 for (i = 0, blocks_freed = 0; i < count; i++) {
4776 BUFFER_TRACE(bitmap_bh, "clear bit"); 4771 BUFFER_TRACE(bitmap_bh, "clear bit");
4777 if (!ext4_clear_bit_atomic(ext4_group_lock_ptr(sb, block_group), 4772 if (!mb_test_bit(bit + i, bitmap_bh->b_data)) {
4778 bit + i, bitmap_bh->b_data)) {
4779 ext4_error(sb, "bit already cleared for block %llu", 4773 ext4_error(sb, "bit already cleared for block %llu",
4780 (ext4_fsblk_t)(block + i)); 4774 (ext4_fsblk_t)(block + i));
4781 BUFFER_TRACE(bitmap_bh, "bit already cleared"); 4775 BUFFER_TRACE(bitmap_bh, "bit already cleared");
@@ -4783,7 +4777,19 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
4783 blocks_freed++; 4777 blocks_freed++;
4784 } 4778 }
4785 } 4779 }
4780
4781 err = ext4_mb_load_buddy(sb, block_group, &e4b);
4782 if (err)
4783 goto error_return;
4784
4785 /*
4786 * need to update group_info->bb_free and bitmap
4787 * with group lock held. generate_buddy look at
4788 * them with group lock_held
4789 */
4786 ext4_lock_group(sb, block_group); 4790 ext4_lock_group(sb, block_group);
4791 mb_clear_bits(bitmap_bh->b_data, bit, count);
4792 mb_free_blocks(NULL, &e4b, bit, count);
4787 blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc); 4793 blk_free_count = blocks_freed + ext4_free_blks_count(sb, desc);
4788 ext4_free_blks_set(sb, desc, blk_free_count); 4794 ext4_free_blks_set(sb, desc, blk_free_count);
4789 desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc); 4795 desc->bg_checksum = ext4_group_desc_csum(sbi, block_group, desc);
@@ -4795,13 +4801,8 @@ void ext4_add_groupblocks(handle_t *handle, struct super_block *sb,
4795 atomic_add(blocks_freed, 4801 atomic_add(blocks_freed,
4796 &sbi->s_flex_groups[flex_group].free_blocks); 4802 &sbi->s_flex_groups[flex_group].free_blocks);
4797 } 4803 }
4798 /* 4804
4799 * request to reload the buddy with the 4805 ext4_mb_unload_buddy(&e4b);
4800 * new bitmap information
4801 */
4802 set_bit(EXT4_GROUP_INFO_NEED_INIT_BIT, &(grp->bb_state));
4803 grp->bb_free += blocks_freed;
4804 up_write(&grp->alloc_sem);
4805 4806
4806 /* We dirtied the bitmap block */ 4807 /* We dirtied the bitmap block */
4807 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); 4808 BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");