From: Goldwyn Rodrigues <rgoldwyn@xxxxxxxx> The superblock shrinkers are responsible for pruning dcache and icache. which evicts the inode by calling into local filesystem code. Protect allocations under memalloc_nofs_save/restore(). Signed-off-by: Goldwyn Rodrigues <rgoldwyn@xxxxxxxx> --- fs/super.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/super.c b/fs/super.c index 672538ca9831..26fc2679118d 100644 --- a/fs/super.c +++ b/fs/super.c @@ -35,6 +35,7 @@ #include <linux/fsnotify.h> #include <linux/lockdep.h> #include <linux/user_namespace.h> +#include <linux/sched/mm.h> #include "internal.h" @@ -63,6 +64,7 @@ static unsigned long super_cache_scan(struct shrinker *shrink, long freed = 0; long dentries; long inodes; + unsigned flags; sb = container_of(shrink, struct super_block, s_shrink); @@ -70,9 +72,11 @@ static unsigned long super_cache_scan(struct shrinker *shrink, * Deadlock avoidance. We may hold various FS locks, and we don't want * to recurse into the FS that called us in clear_inode() and friends.. */ - if (!(sc->gfp_mask & __GFP_FS)) + if (!(sc->gfp_mask & __GFP_FS) || (current->flags & PF_MEMALLOC_NOFS)) return SHRINK_STOP; + flags = memalloc_nofs_save(); + if (!trylock_super(sb)) return SHRINK_STOP; @@ -107,6 +111,7 @@ static unsigned long super_cache_scan(struct shrinker *shrink, freed += sb->s_op->free_cached_objects(sb, sc); } + memalloc_nofs_restore(flags); up_read(&sb->s_umount); return freed; } -- 2.16.2