ext4: fix bigalloc cluster freeing when hole punching under load
authorEric Whitney <enwlinux@gmail.com>
Fri, 1 Mar 2019 04:34:11 +0000 (23:34 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 1 Mar 2019 04:34:11 +0000 (23:34 -0500)
commit7bd75230b43727b258a4f7a59d62114cffe1b6c8
tree788e02fdbc2264f24557d2037a026bf7e0ae5c04
parentbc1d69d6151f1911ecb120a8dbd65e47210b7a72
ext4: fix bigalloc cluster freeing when hole punching under load

Ext4 may not free clusters correctly when punching holes in bigalloc
file systems under high load conditions.  If it's not possible to
extend and restart the journal in ext4_ext_rm_leaf() when preparing to
remove blocks from a punched region, a retry of the entire punch
operation is triggered in ext4_ext_remove_space().  This causes a
partial cluster to be set to the first cluster in the extent found to
the right of the punched region.  However, if the punch operation
prior to the retry had made enough progress to delete one or more
extents and a partial cluster candidate for freeing had already been
recorded, the retry would overwrite the partial cluster.  The loss of
this information makes it impossible to correctly free the original
partial cluster in all cases.

This bug can cause generic/476 to fail when run as part of
xfstests-bld's bigalloc and bigalloc_1k test cases.  The failure is
reported when e2fsck detects bad iblocks counts greater than expected
in units of whole clusters and also detects a number of negative block
bitmap differences equal to the iblocks discrepancy in cluster units.

Signed-off-by: Eric Whitney <enwlinux@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/extents.c