diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-02-18 19:06:54 +0100 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2019-02-20 21:14:20 +0100 |
commit | 875bc3fbf2724134234ddb3069c8e9862b0b19b3 (patch) | |
tree | 220cd162e9c5f80a2481712c5f993cc0acdaa664 /fs/nfs | |
parent | NFS: Pass error information to the pgio error cleanup routine (diff) | |
download | linux-875bc3fbf2724134234ddb3069c8e9862b0b19b3.tar.xz linux-875bc3fbf2724134234ddb3069c8e9862b0b19b3.zip |
NFS: Ensure NFS writeback allocations don't recurse back into NFS.
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>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/write.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 11df9f03245f..d1bc0384ac95 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -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; |