
From: Matthew Wilcox <matthew@wil.cx>

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>
---

 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	2005-03-07 20:41:35.000000000 -0800
+++ 25-akpm/fs/ext3/balloc.c	2005-03-07 21:14:38.000000000 -0800
@@ -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;
_
