提交 9f557cd8 编写于 作者: T Trond Myklebust

NFS: Fix an Oops when truncating a file

The VM/VFS does not allow mapping->a_ops->invalidatepage() to fail.
Unfortunately, nfs_wb_page_cancel() may fail if a fatal signal occurs.
Since the NFS code assumes that the page stays mapped for as long as the
writeback is active, we can end up Oopsing (among other things).

The only safe fix here is to convert nfs_wait_on_request(), so as to make
it uninterruptible (as is already the case with wait_on_page_writeback()).
Signed-off-by: NTrond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
上级 a2c0b9e2
...@@ -176,6 +176,12 @@ void nfs_release_request(struct nfs_page *req) ...@@ -176,6 +176,12 @@ void nfs_release_request(struct nfs_page *req)
kref_put(&req->wb_kref, nfs_free_request); kref_put(&req->wb_kref, nfs_free_request);
} }
static int nfs_wait_bit_uninterruptible(void *word)
{
io_schedule();
return 0;
}
/** /**
* nfs_wait_on_request - Wait for a request to complete. * nfs_wait_on_request - Wait for a request to complete.
* @req: request to wait upon. * @req: request to wait upon.
...@@ -186,14 +192,9 @@ void nfs_release_request(struct nfs_page *req) ...@@ -186,14 +192,9 @@ void nfs_release_request(struct nfs_page *req)
int int
nfs_wait_on_request(struct nfs_page *req) nfs_wait_on_request(struct nfs_page *req)
{ {
int ret = 0; return wait_on_bit(&req->wb_flags, PG_BUSY,
nfs_wait_bit_uninterruptible,
if (!test_bit(PG_BUSY, &req->wb_flags)) TASK_UNINTERRUPTIBLE);
goto out;
ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
nfs_wait_bit_killable, TASK_KILLABLE);
out:
return ret;
} }
/** /**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册