linux/fs/ext4
Long Li 2f3d93e210 ext4: fix race in buffer_head read fault injection
When I enabled ext4 debug for fault injection testing, I encountered the
following warning:

  EXT4-fs error (device sda): ext4_read_inode_bitmap:201: comm fsstress:
         Cannot read inode bitmap - block_group = 8, inode_bitmap = 1051
  WARNING: CPU: 0 PID: 511 at fs/buffer.c:1181 mark_buffer_dirty+0x1b3/0x1d0

The root cause of the issue lies in the improper implementation of ext4's
buffer_head read fault injection. The actual completion of buffer_head
read and the buffer_head fault injection are not atomic, which can lead
to the uptodate flag being cleared on normally used buffer_heads in race
conditions.

[CPU0]           [CPU1]         [CPU2]
ext4_read_inode_bitmap
  ext4_read_bh()
  <bh read complete>
                 ext4_read_inode_bitmap
                   if (buffer_uptodate(bh))
                     return bh
                               jbd2_journal_commit_transaction
                                 __jbd2_journal_refile_buffer
                                   __jbd2_journal_unfile_buffer
                                     __jbd2_journal_temp_unlink_buffer
  ext4_simulate_fail_bh()
    clear_buffer_uptodate
                                      mark_buffer_dirty
                                        <report warning>
                                        WARN_ON_ONCE(!buffer_uptodate(bh))

The best approach would be to perform fault injection in the IO completion
callback function, rather than after IO completion. However, the IO
completion callback function cannot get the fault injection code in sb.

Fix it by passing the result of fault injection into the bh read function,
we simulate faults within the bh read function itself. This requires adding
an extra parameter to the bh read functions that need fault injection.

Fixes: 46f870d690 ("ext4: simulate various I/O and checksum errors when reading metadata")
Signed-off-by: Long Li <leo.lilong@huawei.com>
Link: https://patch.msgid.link/20240906091746.510163-1-leo.lilong@huawei.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
2024-11-12 23:54:14 -05:00
..
.kunitconfig ext4: add .kunitconfig fragment to enable ext4-specific tests 2021-02-11 23:16:30 -05:00
acl.c ext4: convert to ctime accessor functions 2023-07-24 10:29:54 +02:00
acl.h Revert "ext4: apply umask if ACL support is disabled" 2024-05-02 18:25:39 -04:00
balloc.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
bitmap.c ext4: move checksum length calculation of inode bitmap into ext4_inode_bitmap_csum_[verify/set]() functions 2024-09-03 22:12:15 -04:00
block_validity.c ext4: block_validity: Remove unnecessary ‘NULL’ values from new_node 2024-06-27 09:34:00 -04:00
crypto.c ext4: Move CONFIG_UNICODE defguards into the code flow 2024-06-07 17:00:45 +02:00
dir.c Lots of cleanups and bug fixes this cycle, primarily in the block 2024-09-20 19:26:45 -07:00
ext4_extents.h ext4: fix sparse warnings 2021-08-30 23:36:50 -04:00
ext4_jbd2.c use ->bd_mapping instead of ->bd_inode->i_mapping 2024-05-03 02:36:51 -04:00
ext4_jbd2.h ext4: split ext4_journal_start trace for debug 2022-12-01 10:46:54 -05:00
ext4.h ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
extents_status.c ext4: don't pass full mapping flags to ext4_es_insert_extent() 2024-11-12 23:54:14 -05:00
extents_status.h ext4: don't pass full mapping flags to ext4_es_insert_extent() 2024-11-12 23:54:14 -05:00
extents.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
fast_commit.c ext4: simplify if condition 2024-11-12 23:54:13 -05:00
fast_commit.h ext4: add missing validation of fast-commit record lengths 2022-12-08 21:49:24 -05:00
file.c ext4: Call ext4_journal_stop(handle) only once in ext4_dio_write_iter() 2024-10-30 17:42:44 -04:00
fsmap.c ext4: fix FS_IOC_GETFSMAP handling 2024-11-12 23:52:47 -05:00
fsmap.h ext4: fsmap: fix the block/inode bitmap comment 2021-06-24 09:48:29 -04:00
fsync.c ext4: drop EXT4_MF_FS_ABORTED flag 2023-07-29 18:37:53 -04:00
hash.c ext4: remove redundant checks of s_encoding 2023-08-27 11:27:13 -04:00
ialloc.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
indirect.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
inline.c Lots of cleanups and bug fixes this cycle, primarily in the block 2024-09-20 19:26:45 -07:00
inode-test.c ext4: add missing MODULE_DESCRIPTION() 2024-07-05 16:07:24 -04:00
inode.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
ioctl.c introduce fd_file(), convert all accessors to it. 2024-08-12 22:00:43 -04:00
Kconfig fs: add CONFIG_BUFFER_HEAD 2023-08-02 09:13:09 -06:00
Makefile ext4: move ext4 crypto code to its own file crypto.c 2022-05-21 22:24:24 -04:00
mballoc-test.c ext4: add test_mb_mark_used_cost to estimate cost of mb_mark_used 2024-05-03 00:12:32 -04:00
mballoc.c ext4: fix FS_IOC_GETFSMAP handling 2024-11-12 23:52:47 -05:00
mballoc.h ext4: fix FS_IOC_GETFSMAP handling 2024-11-12 23:52:47 -05:00
migrate.c ext4: fix i_data_sem unlock order in ext4_ind_migrate() 2024-09-03 22:14:17 -04:00
mmp.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
move_extent.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
namei.c ext4: WARN if a full dir leaf block has only one dentry 2024-11-12 23:49:55 -05:00
orphan.c ext4: remove trailing newline from ext4_msg() message 2022-12-08 21:49:23 -05:00
page-io.c ext4: remove calls to to set/clear the folio error flag 2024-05-09 00:23:51 -04:00
readpage.c ext4: reduce stack usage in ext4_mpage_readpages() 2024-08-26 21:47:03 -04:00
resize.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
super.c ext4: fix race in buffer_head read fault injection 2024-11-12 23:54:14 -05:00
symlink.c ext4_get_link(): fix breakage in RCU mode 2024-02-25 02:10:32 -05:00
sysfs.c ext4: add positive int attr pointer to avoid sysfs variables overflow 2024-05-02 23:48:30 -04:00
truncate.h ext4: Convert to use mapping->invalidate_lock 2021-07-13 14:29:00 +02:00
verity.c fs: Convert aops->write_begin to take a folio 2024-08-07 11:33:21 +02: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: mark fc as ineligible using an handle in ext4_xattr_set() 2024-10-04 17:36:09 -04:00
xattr.h ext4: annotate struct ext4_xattr_inode_array with __counted_by() 2024-08-26 23:40:06 -04:00