diff options
| author | Matthew Wilcox <matthew@wil.cx> | 2005-03-07 17:47:28 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-03-07 17:47:28 -0800 |
| commit | bb596f367f0112c71dd5b8d278dfdb8044074d53 (patch) | |
| tree | 5108fccde6208793e83e78ab55d796bafea8cdab | |
| parent | 94ee039d596b1a381a1070fe091e7d0f6aea7bf2 (diff) | |
[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: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
| -rw-r--r-- | fs/ext3/balloc.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 0ad9c35b1350..f069d75e5da7 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -288,6 +288,7 @@ void ext3_free_blocks_sb(handle_t *handle, struct super_block *sb, struct ext3_super_block * es; struct ext3_sb_info *sbi; int err = 0, ret; + unsigned group_freed; *pdquot_freed_blocks = 0; sbi = EXT3_SB(sb); @@ -358,7 +359,7 @@ do_more: 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... */ @@ -421,15 +422,15 @@ do_more: jbd_lock_bh_state(bitmap_bh); BUFFER_TRACE(bitmap_bh, "bit already cleared"); } else { - (*pdquot_freed_blocks)++; + group_freed++; } } jbd_unlock_bh_state(bitmap_bh); spin_lock(sb_bgl_lock(sbi, block_group)); - gdp->bg_free_blocks_count = - cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + - *pdquot_freed_blocks); + desc->bg_free_blocks_count = + cpu_to_le16(le16_to_cpu(desc->bg_free_blocks_count) + + group_freed); spin_unlock(sb_bgl_lock(sbi, block_group)); percpu_counter_mod(&sbi->s_freeblocks_counter, count); @@ -441,6 +442,7 @@ do_more: BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); ret = ext3_journal_dirty_metadata(handle, gd_bh); if (!err) err = ret; + *pdquot_freed_blocks += group_freed; if (overflow && !err) { block += count; |
