On Sun, 2019-01-27 at 10:19 -0500, Benjamin Coddington wrote: > We can't have nfs_wb_page() truncate the page from the mapping if > there's > an error on the context without returning that error, because we may > be in > nfs_updatepage() holding the page and trying to update the > request. Not > having any error returned means we'll proceed to create a new request > and > dereference the truncated page->mapping. > > If we're going to remove the page, always return the error that > signaled us > to do so in nfs_page_async_flush(). > > Fixes: c373fff7bd25 ("NFSv4: Don't special case "launder"") > Cc: stable@xxxxxxxxxxxxxxx # v4.11 > Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx> > --- > fs/nfs/write.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/fs/nfs/write.c b/fs/nfs/write.c > index 5a0bbf917a32..c274339176cc 100644 > --- a/fs/nfs/write.c > +++ b/fs/nfs/write.c > @@ -622,9 +622,11 @@ static int nfs_page_async_flush(struct > nfs_pageio_descriptor *pgio, > WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags)); > > ret = 0; > - /* If there is a fatal error that covers this write, just exit > */ > - if (nfs_error_is_fatal_on_server(req->wb_context->error)) > + /* If there is a fatal on server error on this context, just > exit */ > + if (nfs_error_is_fatal_on_server(req->wb_context->error)) { > + ret = req->wb_context->error; > goto out_launder; > + } > > if (!nfs_pageio_add_request(pgio, req)) { > ret = pgio->pg_error; Hi Ben We were apparently both looking at the same code last week ☺. I have a similar patch, but that also fixes a similar clobbering issue with the nfs_error_is_fatal() error just a few lines further down. Without the extra hunk, we could end up converting an interrupted call into a 'successful' write. Cheers Trond --- >From 676d3340abc26ce9ff2b7609c293454dec6d4897 Mon Sep 17 00:00:00 2001 From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Date: Tue, 22 Jan 2019 07:34:45 -0500 Subject: [PATCH] NFS: Fix up return value on fatal errors in nfs_page_async_flush() Ensure that we return the fatal error value that caused us to exit nfs_page_async_flush(). Fixes: a6598813a4c5 ("NFS: Don't write back further requests...") Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx> Cc: stable@xxxxxxxxxxxxxxx # v4.12+ --- fs/nfs/write.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 5a0bbf917a32..f12cb31a41e5 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -621,11 +621,12 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, nfs_set_page_writeback(page); WARN_ON_ONCE(test_bit(PG_CLEAN, &req->wb_flags)); - ret = 0; + ret = req->wb_context->error; /* If there is a fatal error that covers this write, just exit */ - if (nfs_error_is_fatal_on_server(req->wb_context->error)) + if (nfs_error_is_fatal_on_server(ret)) goto out_launder; + ret = 0; if (!nfs_pageio_add_request(pgio, req)) { ret = pgio->pg_error; /* @@ -635,9 +636,9 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio, nfs_context_set_write_error(req->wb_context, ret); if (nfs_error_is_fatal_on_server(ret)) goto out_launder; - } + } else + ret = -EAGAIN; nfs_redirty_request(req); - ret = -EAGAIN; } else nfs_add_stats(page_file_mapping(page)->host, NFSIOS_WRITEPAGES, 1); -- 2.20.1 -- Trond Myklebust Linux NFS client maintainer, Hammerspace trond.myklebust@xxxxxxxxxxxxxxx