From: chuguangqing chuguangqing@inspur.com
[ Upstream commit 1534f72dc2a11ded38b0e0268fbcc0ca24e9fd4a ]
The parent function ext4_xattr_inode_lookup_create already uses GFP_NOFS for memory alloction, so the function ext4_xattr_inode_cache_find should use same gfp_flag.
Signed-off-by: chuguangqing chuguangqing@inspur.com Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES - In `fs/ext4/xattr.c:1538` the patch switches the `kvmalloc(value_len, …)` allocation in `ext4_xattr_inode_cache_find()` from `GFP_KERNEL` to `GFP_NOFS`. This path runs while `ext4_xattr_set_handle()` already holds the xattr write lock and has an active jbd2 handle that set `PF_MEMALLOC_NOFS` (see `fs/ext4/xattr.c:2342` and the `WARN_ON_ONCE` directly above the allocation at `fs/ext4/xattr.c:1528`). Keeping `__GFP_FS` in this context lets direct reclaim re-enter ext4 and wait on the same locks, producing the deadlocks and lockdep splats the warning is trying to highlight. - The new flag matches the rest of the call chain: `ext4_xattr_inode_lookup_create()` subsequently inserts into the mbcache with `GFP_NOFS` (`fs/ext4/xattr.c:1604`), so this change makes the cache lookup/allocation path consistent and eliminates the only remaining `GFP_KERNEL` allocation while the NOFS guard is active. - This is a one-line, well-scoped bug fix that simply narrows allocator context; it cannot change behaviour outside the reclaim path, but it removes a real hang risk seen under memory pressure during xattr updates. There are no prerequisite refactors or API changes, so the patch is safe to carry into stable branches whenever `ext4_xattr_inode_cache_find()` exists.
Natural next step: after backporting, run the ext4 xattr fstests (e.g. generic/030, generic/031) under memory pressure to confirm the deadlock no longer reproduces.
fs/ext4/xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index b0e60a44dae9d..ce7253b3f5499 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -1535,7 +1535,7 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, WARN_ON_ONCE(ext4_handle_valid(journal_current_handle()) && !(current->flags & PF_MEMALLOC_NOFS));
- ea_data = kvmalloc(value_len, GFP_KERNEL); + ea_data = kvmalloc(value_len, GFP_NOFS); if (!ea_data) { mb_cache_entry_put(ea_inode_cache, ce); return NULL;