aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-02-06 14:07:15 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-02-13 01:40:38 -0500
commita301b777714087ea1d63dbec0173a13d416cd7a9 (patch)
treeccf5e747d0411c7af15279c66389ad4e1155ef04 /fs/nfs/write.c
parentb0c4fddca2bc3967381b728732a8850de35e1b20 (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>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index dea17375eb30..febdade91670 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
153 i_size_write(inode, end); 153 i_size_write(inode, end);
154} 154}
155 155
156/* A writeback failed: mark the page as bad, and invalidate the page cache */
157static void nfs_set_pageerror(struct page *page)
158{
159 SetPageError(page);
160 nfs_zap_mapping(page->mapping->host, page->mapping);
161}
162
156/* We can set the PG_uptodate flag if we see that a write request 163/* We can set the PG_uptodate flag if we see that a write request
157 * covers the full page. 164 * covers the full page.
158 */ 165 */
@@ -714,7 +721,7 @@ int nfs_updatepage(struct file *file, struct page *page,
714 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n", 721 dprintk("NFS: nfs_updatepage returns %d (isize %Ld)\n",
715 status, (long long)i_size_read(inode)); 722 status, (long long)i_size_read(inode));
716 if (status < 0) 723 if (status < 0)
717 ClearPageUptodate(page); 724 nfs_set_pageerror(page);
718 return status; 725 return status;
719} 726}
720 727
@@ -976,8 +983,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
976 return; 983 return;
977 984
978 if (task->tk_status < 0) { 985 if (task->tk_status < 0) {
979 ClearPageUptodate(page); 986 nfs_set_pageerror(page);
980 SetPageError(page);
981 req->wb_context->error = task->tk_status; 987 req->wb_context->error = task->tk_status;
982 dprintk(", error = %d\n", task->tk_status); 988 dprintk(", error = %d\n", task->tk_status);
983 } else { 989 } else {
@@ -1034,8 +1040,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1034 (long long)req_offset(req)); 1040 (long long)req_offset(req));
1035 1041
1036 if (task->tk_status < 0) { 1042 if (task->tk_status < 0) {
1037 ClearPageUptodate(page); 1043 nfs_set_pageerror(page);
1038 SetPageError(page);
1039 req->wb_context->error = task->tk_status; 1044 req->wb_context->error = task->tk_status;
1040 end_page_writeback(page); 1045 end_page_writeback(page);
1041 nfs_inode_remove_request(req); 1046 nfs_inode_remove_request(req);