diff options
| author | Sergey Senozhatsky <senozhatsky@chromium.org> | 2026-08-27 21:50:20 +0900 |
|---|---|---|
| committer | Theodore Ts'o <tytso@mit.edu> | 2026-10-08 11:06:42 -0400 |
| commit | 19e16597f9baf1b5719a3a6c710486446f6808fd (patch) | |
| tree | 36564246b3500cd1fc859081be033de4d016be22 /scripts/Makefile.thinlto | |
| parent | aed43f47e1edeee1454eea86006a8c09480e5ed3 (diff) | |
| download | linux-19e16597f9baf1b5719a3a6c710486446f6808fd.tar.gz linux-19e16597f9baf1b5719a3a6c710486446f6808fd.zip | |
ext4: fix ABBA deadlock in ext4_rmdir()
We observe the following ABBA deadlock (casefolding enabled):
INFO: task jbd2/dm-13-8:447 blocked for more than 720 seconds.
task:jbd2/dm-13-8 state:D stack:0 pid:447 tgid:447 ppid:2
Call Trace:
<TASK>
__schedule+0xc2c/0xe60
schedule+0x40/0xe0
jbd2_journal_wait_updates+0x8f/0xf0
jbd2_journal_commit_transaction+0x321/0x1850
kjournald2+0xa9/0x230
kthread+0x226/0x2a0
ret_from_fork+0x101/0x1e0
ret_from_fork_asm+0x1a/0x30
INFO: task Thread-10:4161 blocked for more than 720 seconds.
task:Thread-10 state:D stack:0 pid:4161 tgid:3848 ppid:540
Call Trace:
<TASK>
__schedule+0xc2c/0xe60
schedule+0x40/0xe0
wait_transaction_locked+0x8c/0xd0
start_this_handle+0x252/0x870
jbd2__journal_start+0x120/0x280
__ext4_journal_start_sb+0x11a/0x250
ext4_evict_inode+0x208/0x760
iput+0x222/0x5c0
dput+0x293/0x690
____fput+0x145/0x2b0
task_work_run+0x7a/0xb0
exit_to_user_mode_loop+0xc0/0xd0
do_syscall_64+0x14b/0xf10
entry_SYSCALL_64_after_hwframe+0x76/0x7e
NMI backtrace for cpu 0
CPU: 0 UID: 1010216 PID: 4160 Comm: Thread-7
RIP: 0010:d_walk+0x0/0x290
[..]
Call Trace:
<TASK>
shrink_dcache_parent+0xb2/0x100
d_invalidate+0x50/0x110
ext4_rmdir+0x3a2/0x3d0
vfs_rmdir+0x9d/0x1d0
do_rmdir+0xf0/0x330
__x64_sys_unlinkat+0x34/0x50
do_syscall_64+0x61/0xf10
The problem is that ext4_rmdir() calls d_invalidate() before stopping
the jbd2 transaction handle. Because d_invalidate() traverses child
dentries it can encounter dying or in-use dentries. If a concurrent
thread executing __dentry_kill() on a child dentry invokes ext4_evict_inode(),
it requests a new transaction handle via ext4_journal_start(), which
waits for all running handles to close. However, the thread executing
ext4_rmdir() still holds its active transaction handle while looping
in shrink_dcache_parent() waiting for the dying child dentry to complete
eviction.
Stop transaction handle in ext4_rmdir() before calling d_invalidate().
Cc: stable@kernel.org
Fixes: b886ee3e778e ("ext4: Support case-insensitive file name lookups")
Co-developed-by: Sarthak Kukreti <sarthakkukreti@google.com>
Signed-off-by: Sarthak Kukreti <sarthakkukreti@google.com>
Signed-off-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Baokun Li <libaokun@linux.alibaba.com>
Reviewed-by: Zhang Yi <yi.zhang@huawei.com>
Link: https://patch.msgid.link/20260827125158.4030598-1-senozhatsky@chromium.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions
