In ext4_mb_mark_diskspace_used(), when the allocator detects that the allocated blocks overlap with filesystem metadata, it enters an error recovery path that marks these blocks as used in the bitmap via ext4_mb_mark_context() with flags=0. Without EXT4_MB_BITMAP_MARKED_CHECK, ext4_mb_mark_context() assumes all bits in the range will be flipped, so it sets changed=len unconditionally. However, in a corrupted filesystem, some of these metadata blocks may already be marked as used (bit=1) in the bitmap. Since mb_set_bits() is idempotent (sets bits to 1 regardless of current state), bits that are already set won't actually change, but the free clusters count is still decremented by the full range length, leading to an inaccurate free clusters count. Fix this by passing EXT4_MB_BITMAP_MARKED_CHECK, which correctly counts only the bits that actually changed state. Fixes: 2f94711b098b ("ext4: call ext4_mb_mark_context in ext4_mb_mark_diskspace_used") Signed-off-by: Baokun Li --- fs/ext4/mballoc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index ed1bd00e11cd..ff2023c9f52c 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4228,7 +4228,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac, handle_t *handle ac->ac_b_ex.fe_group, ac->ac_b_ex.fe_start, ac->ac_b_ex.fe_len, - 0, NULL); + EXT4_MB_BITMAP_MARKED_CHECK, NULL); if (!err) err = -EFSCORRUPTED; return err; -- 2.43.7