ext4: don't count free clusters from a corrupt block group
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 31 Oct 2013 15:46:31 +0000 (11:46 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 31 Oct 2013 15:46:31 +0000 (11:46 -0400)
A bg that's been flagged "corrupt" by definition has no free blocks,
so that the allocator won't be tempted to use the damaged bg.
Therefore, we shouldn't count the clusters in the damaged group when
calculating free counts.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
fs/ext4/balloc.c

index dc5d572ebd6a41ae5aebbb5f7b73346b3b4c010e..6ea7b1436bbc201e872d6ee18f7321b2e099f156 100644 (file)
@@ -640,6 +640,7 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
        struct ext4_group_desc *gdp;
        ext4_group_t i;
        ext4_group_t ngroups = ext4_get_groups_count(sb);
+       struct ext4_group_info *grp;
 #ifdef EXT4FS_DEBUG
        struct ext4_super_block *es;
        ext4_fsblk_t bitmap_count;
@@ -655,7 +656,11 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
                gdp = ext4_get_group_desc(sb, i, NULL);
                if (!gdp)
                        continue;
-               desc_count += ext4_free_group_clusters(sb, gdp);
+               grp = NULL;
+               if (EXT4_SB(sb)->s_group_info)
+                       grp = ext4_get_group_info(sb, i);
+               if (!grp || !EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
+                       desc_count += ext4_free_group_clusters(sb, gdp);
                brelse(bitmap_bh);
                bitmap_bh = ext4_read_block_bitmap(sb, i);
                if (bitmap_bh == NULL)
@@ -679,7 +684,11 @@ ext4_fsblk_t ext4_count_free_clusters(struct super_block *sb)
                gdp = ext4_get_group_desc(sb, i, NULL);
                if (!gdp)
                        continue;
-               desc_count += ext4_free_group_clusters(sb, gdp);
+               grp = NULL;
+               if (EXT4_SB(sb)->s_group_info)
+                       grp = ext4_get_group_info(sb, i);
+               if (!grp || !EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
+                       desc_count += ext4_free_group_clusters(sb, gdp);
        }
 
        return desc_count;