Commit bb596f36 authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Linus Torvalds

[PATCH] ext3: free block accounting fix

If we chose to "do_more", we would double-count the amount freed in the
second and subsequent block groups.  Fix it the same way as was done in
ext2 a couple of years ago.
Signed-off-by: default avatarMatthew Wilcox <matthew@wil.cx>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 94ee039d
...@@ -288,6 +288,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, ...@@ -288,6 +288,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
struct ext3_super_block * es; struct ext3_super_block * es;
struct ext3_sb_info *sbi; struct ext3_sb_info *sbi;
int err = 0, ret; int err = 0, ret;
unsigned group_freed;
*pdquot_freed_blocks = 0; *pdquot_freed_blocks = 0;
sbi = EXT3_SB(sb); sbi = EXT3_SB(sb);
...@@ -358,7 +359,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, ...@@ -358,7 +359,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
jbd_lock_bh_state(bitmap_bh); jbd_lock_bh_state(bitmap_bh);
for (i = 0; i < count; i++) { for (i = 0, group_freed = 0; i < count; i++) {
/* /*
* An HJ special. This is expensive... * An HJ special. This is expensive...
*/ */
...@@ -421,15 +422,15 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, ...@@ -421,15 +422,15 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
jbd_lock_bh_state(bitmap_bh); jbd_lock_bh_state(bitmap_bh);
BUFFER_TRACE(bitmap_bh, "bit already cleared"); BUFFER_TRACE(bitmap_bh, "bit already cleared");
} else { } else {
(*pdquot_freed_blocks)++; group_freed++;
} }
} }
jbd_unlock_bh_state(bitmap_bh); jbd_unlock_bh_state(bitmap_bh);
spin_lock(sb_bgl_lock(sbi, block_group)); spin_lock(sb_bgl_lock(sbi, block_group));
gdp->bg_free_blocks_count = desc->bg_free_blocks_count =
cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) +
*pdquot_freed_blocks); group_freed);
spin_unlock(sb_bgl_lock(sbi, block_group)); spin_unlock(sb_bgl_lock(sbi, block_group));
percpu_counter_mod(&sbi->s_freeblocks_counter, count); percpu_counter_mod(&sbi->s_freeblocks_counter, count);
...@@ -441,6 +442,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, ...@@ -441,6 +442,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb,
BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); BUFFER_TRACE(gd_bh, "dirtied group descriptor block");
ret = ext3_journal_dirty_metadata(handle, gd_bh); ret = ext3_journal_dirty_metadata(handle, gd_bh);
if (!err) err = ret; if (!err) err = ret;
*pdquot_freed_blocks += group_freed;
if (overflow && !err) { if (overflow && !err) {
block += count; block += count;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment