[RFC 0/1] ubifs: inode deletion deadlock
From: Wang Zhaolong
Date: Wed Jul 10 2024 - 23:06:49 EST
Hi.
While the previous patch set [1] aimed to address the ABBA deadlock between
inode reclaiming and deleted inode writing, I discovered that the problem
still persists in the form of an AA deadlock after applying those changes.
The core issue is that although [1] avoids the ABBA deadlock by getting the
xattr inodes before locking BASEHD's wbuf->io_mutex. But the inode reclaiming
process can still get stuck waiting for the xattr inodes that have already
been marked as I_FREEING.
root@debian:~# cat /proc/537/stack
[<0>] __wait_on_freeing_inode+0xb2/0xf0
[<0>] find_inode_fast.isra.0+0x63/0xb0
[<0>] iget_locked+0x72/0x1c0
[<0>] ubifs_iget+0x3e/0x5c0 [ubifs]
[<0>] ubifs_jnl_write_inode+0x11f/0x6c0 [ubifs]
[<0>] ubifs_evict_inode.cold+0x39/0x6a [ubifs]
[<0>] evict+0xd1/0x1a0
[<0>] inode_lru_isolate+0x238/0x2b0
[<0>] __list_lru_walk_one+0x77/0x150
[<0>] list_lru_walk_one+0x4a/0x70
[<0>] prune_icache_sb+0x49/0x80
[<0>] super_cache_scan+0x124/0x1b0
[<0>] do_shrink_slab+0x13e/0x2c0
[<0>] shrink_slab+0xac/0x2b0
[<0>] drop_slab_node+0x45/0x90
[<0>] drop_slab+0x38/0x70
[<0>] drop_caches_sysctl_handler+0x74/0x90
[<0>] proc_sys_call_handler+0x143/0x260
[<0>] new_sync_write+0x116/0x1c0
[<0>] vfs_write+0x1b7/0x250
[<0>] ksys_write+0x5f/0xe0
[<0>] do_syscall_64+0x33/0x40
[<0>] entry_SYSCALL_64_after_hwframe+0x67/0xd1
root@debian:~# cat /proc/541/stack
[<0>] __wait_on_freeing_inode+0xb2/0xf0
[<0>] find_inode_fast.isra.0+0x63/0xb0
[<0>] iget_locked+0x72/0x1c0
[<0>] ubifs_iget+0x3e/0x5c0 [ubifs]
[<0>] ubifs_jnl_write_inode+0x11f/0x6c0 [ubifs]
[<0>] ubifs_evict_inode.cold+0x39/0x6a [ubifs]
[<0>] evict+0xd1/0x1a0
[<0>] do_unlinkat+0x1df/0x2f0
[<0>] do_syscall_64+0x33/0x40
[<0>] entry_SYSCALL_64_after_hwframe+0x67/0xd1
The root cause of the problem lies in two aspects:
1. UBIFS uses inodes to represent xattrs.
2. During the eviction process, iget_locked(), which waits for I_FREEING,
is called again.
Therefore, in this patch, I aim to provide a solution that avoids
waiting within the eviction process. However, I must admit that my
current code implementation is not very elegant and could be improved.
Wang Zhaolong (1):
ubifs: avoid deadlock when deleting an inode with xattr
fs/ubifs/journal.c | 42 ++++++++++++++++++++++++++++++++++--------
fs/ubifs/super.c | 15 +++++++++++++++
fs/ubifs/ubifs.h | 1 +
fs/ubifs/xattr.c | 12 +++++++-----
4 files changed, 57 insertions(+), 13 deletions(-)
--
2.34.3