aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2007-07-25 14:09:54 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:15:23 -0400
commit7b159fc18d417980f57aef64cab3417ee6af70f8 (patch)
tree880f31179a9836ad9cd63b91dd6d77b61b01017c /fs/nfs/write.c
parent34901f70d119d88126e7390351b8c780646628e1 (diff)
NFS: Fall back to synchronous writes when a background write errors...
This helps prevent huge queues of background writes from building up whenever the server runs out of disk or quota space, or if someone changes the file access modes behind our backs. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index b3c5f5db73a4..fb396ea5accf 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -110,6 +110,13 @@ void nfs_writedata_release(void *wdata)
110 nfs_writedata_free(wdata); 110 nfs_writedata_free(wdata);
111} 111}
112 112
113static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
114{
115 ctx->error = error;
116 smp_wmb();
117 set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
118}
119
113static struct nfs_page *nfs_page_find_request_locked(struct page *page) 120static struct nfs_page *nfs_page_find_request_locked(struct page *page)
114{ 121{
115 struct nfs_page *req = NULL; 122 struct nfs_page *req = NULL;
@@ -945,7 +952,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
945 952
946 if (task->tk_status < 0) { 953 if (task->tk_status < 0) {
947 nfs_set_pageerror(page); 954 nfs_set_pageerror(page);
948 req->wb_context->error = task->tk_status; 955 nfs_context_set_write_error(req->wb_context, task->tk_status);
949 dprintk(", error = %d\n", task->tk_status); 956 dprintk(", error = %d\n", task->tk_status);
950 goto out; 957 goto out;
951 } 958 }
@@ -1008,7 +1015,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
1008 1015
1009 if (task->tk_status < 0) { 1016 if (task->tk_status < 0) {
1010 nfs_set_pageerror(page); 1017 nfs_set_pageerror(page);
1011 req->wb_context->error = task->tk_status; 1018 nfs_context_set_write_error(req->wb_context, task->tk_status);
1012 dprintk(", error = %d\n", task->tk_status); 1019 dprintk(", error = %d\n", task->tk_status);
1013 goto remove_request; 1020 goto remove_request;
1014 } 1021 }
@@ -1222,7 +1229,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1222 req->wb_bytes, 1229 req->wb_bytes,
1223 (long long)req_offset(req)); 1230 (long long)req_offset(req));
1224 if (task->tk_status < 0) { 1231 if (task->tk_status < 0) {
1225 req->wb_context->error = task->tk_status; 1232 nfs_context_set_write_error(req->wb_context, task->tk_status);
1226 nfs_inode_remove_request(req); 1233 nfs_inode_remove_request(req);
1227 dprintk(", error = %d\n", task->tk_status); 1234 dprintk(", error = %d\n", task->tk_status);
1228 goto next; 1235 goto next;