Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfs: xfs_mru_cache_insert() should use GFP_NOFS

xfs_mru_cache_insert() can be called from within transaction context
during block allocation like so:

write(2)
....
xfs_get_blocks
xfs_iomap_write_direct
start transaction
xfs_bmapi_write
xfs_bmapi_allocate
xfs_bmap_btalloc
xfs_bmap_btalloc_filestreams
xfs_filestream_new_ag
xfs_filestream_pick_ag
xfs_mru_cache_insert
radix_tree_preload(GFP_KERNEL)

In this case, GFP_KERNEL is incorrect and can potentially lead to
deadlocks in memory reclaim. It should use GFP_NOFS allocations to
avoid lock recursion problems.

[dchinner: rewrote commit message]

Signed-off-by: Byoungyoung Lee <blee@gatech.edu>
Signed-off-by: Sanidhya Kashyap <sanidhya.gatech@gmail.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>

authored by

Byoungyoung Lee and committed by
Dave Chinner
20dafeef 65dd297a

+1 -1
+1 -1
fs/xfs/xfs_mru_cache.c
··· 437 437 if (!mru || !mru->lists) 438 438 return -EINVAL; 439 439 440 - if (radix_tree_preload(GFP_KERNEL)) 440 + if (radix_tree_preload(GFP_NOFS)) 441 441 return -ENOMEM; 442 442 443 443 INIT_LIST_HEAD(&elem->list_node);