linux/fs/ext4
Baokun Li de25d6e961 ext4: only update i_reserved_data_blocks on successful block allocation
In our fault injection test, we create an ext4 file, migrate it to
non-extent based file, then punch a hole and finally trigger a WARN_ON
in the ext4_da_update_reserve_space():

EXT4-fs warning (device sda): ext4_da_update_reserve_space:369:
ino 14, used 11 with only 10 reserved data blocks

When writing back a non-extent based file, if we enable delalloc, the
number of reserved blocks will be subtracted from the number of blocks
mapped by ext4_ind_map_blocks(), and the extent status tree will be
updated. We update the extent status tree by first removing the old
extent_status and then inserting the new extent_status. If the block range
we remove happens to be in an extent, then we need to allocate another
extent_status with ext4_es_alloc_extent().

       use old    to remove   to add new
    |----------|------------|------------|
              old extent_status

The problem is that the allocation of a new extent_status failed due to a
fault injection, and __es_shrink() did not get free memory, resulting in
a return of -ENOMEM. Then do_writepages() retries after receiving -ENOMEM,
we map to the same extent again, and the number of reserved blocks is again
subtracted from the number of blocks in that extent. Since the blocks in
the same extent are subtracted twice, we end up triggering WARN_ON at
ext4_da_update_reserve_space() because used > ei->i_reserved_data_blocks.

For non-extent based file, we update the number of reserved blocks after
ext4_ind_map_blocks() is executed, which causes a problem that when we call
ext4_ind_map_blocks() to create a block, it doesn't always create a block,
but we always reduce the number of reserved blocks. So we move the logic
for updating reserved blocks to ext4_ind_map_blocks() to ensure that the
number of reserved blocks is updated only after we do succeed in allocating
some new blocks.

Fixes: 5f634d064c ("ext4: Fix quota accounting error with fallocate")
Cc: stable@kernel.org
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://lore.kernel.org/r/20230424033846.4732-2-libaokun1@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2023-06-26 19:34:56 -04:00
..
.kunitconfig ext4: add .kunitconfig fragment to enable ext4-specific tests 2021-02-11 23:16:30 -05:00
acl.c fs: port acl to mnt_idmap 2023-01-19 09:24:28 +01:00
acl.h fs: port ->set_acl() to pass mnt_idmap 2023-01-19 09:24:27 +01:00
balloc.c ext4: drop the call to ext4_error() from ext4_get_group_info() 2023-06-14 22:24:05 -04:00
bitmap.c ext4: remove useless conditional branch code 2023-04-19 23:39:08 -04:00
block_validity.c ext4: add ext4_sb_block_valid() refactored out of ext4_inode_block_valid() 2022-02-25 21:34:56 -05:00
crypto.c ext4: refactor and move ext4_ioctl_get_encryption_pwsalt() 2022-05-21 22:24:24 -04:00
dir.c ext4: fix spelling errors in comments 2022-05-11 15:19:06 -04:00
ext4_extents.h ext4: fix sparse warnings 2021-08-30 23:36:50 -04:00
ext4_jbd2.c ext4: split ext4_journal_start trace for debug 2022-12-01 10:46:54 -05:00
ext4_jbd2.h ext4: split ext4_journal_start trace for debug 2022-12-01 10:46:54 -05:00
ext4.h ext4: Give symbolic names to mballoc criterias 2023-06-26 19:34:56 -04:00
extents_status.c ext4: fix data races when using cached status extents 2023-05-13 18:05:04 -04:00
extents_status.h ext4: fix extent_status trace points 2020-01-25 02:03:03 -05:00
extents.c ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline 2023-04-28 12:56:35 -04:00
fast_commit.c ext4: use ext4_fc_tl_mem in fast-commit replay path 2023-02-09 10:43:23 -05:00
fast_commit.h ext4: add missing validation of fast-commit record lengths 2022-12-08 21:49:24 -05:00
file.c fs: add FMODE_DIO_PARALLEL_WRITE flag 2023-04-03 07:14:20 -06:00
fsmap.c ext4: fix another off-by-one fsmap error on 1k block filesystems 2023-03-07 20:20:48 -05:00
fsmap.h ext4: fsmap: fix the block/inode bitmap comment 2021-06-24 09:48:29 -04:00
fsync.c ext4: fix fsync for non-directories 2023-05-30 15:33:57 -04:00
hash.c ext4: improve error handling from ext4_dirhash() 2023-05-13 18:05:05 -04:00
ialloc.c ext4: allow ext4_get_group_info() to fail 2023-05-13 18:02:46 -04:00
indirect.c ext4: only update i_reserved_data_blocks on successful block allocation 2023-06-26 19:34:56 -04:00
inline.c ext4: Make ext4_write_inline_data_end() use folio 2023-06-15 00:02:10 -04:00
inode-test.c fs: ext4: Modify inode-test.c to use KUnit parameterized testing feature 2020-12-02 16:07:25 -07:00
inode.c ext4: only update i_reserved_data_blocks on successful block allocation 2023-06-26 19:34:56 -04:00
ioctl.c Bug fixes and regressions for ext4, the most serious of which is a 2023-03-12 08:55:55 -07:00
Kconfig ext: EXT4_KUNIT_TESTS should depend on EXT4_FS instead of selecting it 2021-02-11 23:12:59 -05:00
Makefile ext4: move ext4 crypto code to its own file crypto.c 2022-05-21 22:24:24 -04:00
mballoc.c ext4: Give symbolic names to mballoc criterias 2023-06-26 19:34:56 -04:00
mballoc.h ext4: Give symbolic names to mballoc criterias 2023-06-26 19:34:56 -04:00
migrate.c ext4: avoid deadlock in fs reclaim with page writeback 2023-05-13 18:05:04 -04:00
mmp.c ext4: fix lockdep warning when enabling MMP 2023-05-07 21:11:18 -04:00
move_extent.c - Nick Piggin's "shoot lazy tlbs" series, to improve the peformance of 2023-04-27 19:42:02 -07:00
namei.c ext4: improve error handling from ext4_dirhash() 2023-05-13 18:05:05 -04:00
orphan.c ext4: remove trailing newline from ext4_msg() message 2022-12-08 21:49:23 -05:00
page-io.c ext4: remove unneeded check of nr_to_submit 2023-04-19 23:38:33 -04:00
readpage.c ext4: Call fsverity_verify_folio() 2023-06-15 00:02:10 -04:00
resize.c ext4: remove unused group parameter in ext4_block_bitmap_csum_set 2023-03-23 23:00:08 -04:00
super.c ext4: Ensure ext4_mb_prefetch_fini() is called for all prefetched BGs 2023-06-26 19:34:56 -04:00
symlink.c fs: port ->getattr() to pass mnt_idmap 2023-01-19 09:24:25 +01:00
sysfs.c ext4: Give symbolic names to mballoc criterias 2023-06-26 19:34:56 -04:00
truncate.h ext4: Convert to use mapping->invalidate_lock 2021-07-13 14:29:00 +02:00
verity.c - Nick Piggin's "shoot lazy tlbs" series, to improve the peformance of 2023-04-27 19:42:02 -07:00
xattr_hurd.c fs: port xattr to mnt_idmap 2023-01-19 09:24:28 +01:00
xattr_security.c fs: port xattr to mnt_idmap 2023-01-19 09:24:28 +01:00
xattr_trusted.c fs: port xattr to mnt_idmap 2023-01-19 09:24:28 +01:00
xattr_user.c fs: port xattr to mnt_idmap 2023-01-19 09:24:28 +01:00
xattr.c ext4: only check dquot_initialize_needed() when debugging 2023-06-08 10:06:40 -04:00
xattr.h ext4: remove EA inode entry from mbcache on inode eviction 2022-08-02 23:56:25 -04:00