From: Matthew Wilcox 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 Signed-off-by: Andrew Morton --- 25-akpm/fs/ext3/balloc.c | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff -puN fs/ext3/balloc.c~ext3-free-block-accounting-fix fs/ext3/balloc.c --- 25/fs/ext3/balloc.c~ext3-free-block-accounting-fix Thu Jan 27 14:07:41 2005 +++ 25-akpm/fs/ext3/balloc.c Thu Jan 27 14:07:41 2005 @@ -288,6 +288,7 @@ void ext3_free_blocks_sb(handle_t *handl 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; _