diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-02-06 11:07:15 -0800 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-02-12 22:40:38 -0800 |
commit | a301b777714087ea1d63dbec0173a13d416cd7a9 (patch) | |
tree | ccf5e747d0411c7af15279c66389ad4e1155ef04 | |
parent | b0c4fddca2bc3967381b728732a8850de35e1b20 (diff) |
NFS: Don't use ClearPageUptodate() when writeback fails
ClearPageUptodate() will just cause races here. What we really want to do
is to invalidate the page cache.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/write.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index dea17375eb3..febdade9167 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -153,6 +153,13 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c i_size_write(inode, end); } +/* A writeback failed: mark the page as bad, and invalidate the page cache */ +static void nfs_set_pageerror(struct page *page) +{ + SetPageError(page); + nfs_zap_mapping(page->mapping->host, page->mapping); +} + /* We can set the PG_uptodate flag if we see that a write request * covers the full page. */ @@ -714,7 +721,7 @@ int nfs_updatepage(struct file *file, struct page *page, dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", status, (long long)i_size_read(inode)); if (status < 0) - ClearPageUptodate(page); + nfs_set_pageerror(page); return status; } @@ -976,8 +983,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) return; if (task->tk_status < 0) { - ClearPageUptodate(page); - SetPageError(page); + nfs_set_pageerror(page); req->wb_context->error = task->tk_status; dprintk(", error = %d\n", task->tk_status); } else { @@ -1034,8 +1040,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) (long long)req_offset(req)); if (task->tk_status < 0) { - ClearPageUptodate(page); - SetPageError(page); + nfs_set_pageerror(page); req->wb_context->error = task->tk_status; end_page_writeback(page); nfs_inode_remove_request(req); |