Skip to content

Commit

Permalink
NFS: Fix an Oops when truncating a file
Browse files Browse the repository at this point in the history
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: stable@kernel.org
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Feb 3, 2010
1 parent a2c0b9e commit 9f557cd
Showing 1 changed file with 9 additions and 8 deletions.
17 changes: 9 additions & 8 deletions fs/nfs/pagelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ void nfs_release_request(struct nfs_page *req)
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.
* @req: request to wait upon.
Expand All @@ -186,14 +192,9 @@ void nfs_release_request(struct nfs_page *req)
int
nfs_wait_on_request(struct nfs_page *req)
{
int ret = 0;

if (!test_bit(PG_BUSY, &req->wb_flags))
goto out;
ret = out_of_line_wait_on_bit(&req->wb_flags, PG_BUSY,
nfs_wait_bit_killable, TASK_KILLABLE);
out:
return ret;
return wait_on_bit(&req->wb_flags, PG_BUSY,
nfs_wait_bit_uninterruptible,
TASK_UNINTERRUPTIBLE);
}

/**
Expand Down

0 comments on commit 9f557cd

Please sign in to comment.