NFS: Ensure NFS writeback allocations don't recurse back into NFS.
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 18 Feb 2019 18:06:54 +0000 (13:06 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 20 Feb 2019 20:14:20 +0000 (15:14 -0500)
All the allocations that we can hit in the NFS layer and sunrpc layers
themselves are already marked as GFP_NOFS, but we need to ensure that
any calls to generic kernel functionality do the right thing as well.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/write.c

index 11df9f0..d1bc038 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/iversion.h>
 
 #include <linux/uaccess.h>
+#include <linux/sched/mm.h>
 
 #include "delegation.h"
 #include "internal.h"
@@ -712,11 +713,13 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
 {
        struct inode *inode = mapping->host;
        struct nfs_pageio_descriptor pgio;
-       struct nfs_io_completion *ioc = nfs_io_completion_alloc(GFP_NOFS);
+       struct nfs_io_completion *ioc;
+       unsigned int pflags = memalloc_nofs_save();
        int err;
 
        nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGES);
 
+       ioc = nfs_io_completion_alloc(GFP_NOFS);
        if (ioc)
                nfs_io_completion_init(ioc, nfs_io_completion_commit, inode);
 
@@ -727,6 +730,8 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
        nfs_pageio_complete(&pgio);
        nfs_io_completion_put(ioc);
 
+       memalloc_nofs_restore(pflags);
+
        if (err < 0)
                goto out_err;
        err = pgio.pg_error;