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>
This commit is contained in:
Trond Myklebust
2007-07-25 14:09:54 -04:00
parent 34901f70d1
commit 7b159fc18d
3 changed files with 57 additions and 23 deletions

View File

@@ -110,6 +110,13 @@ void nfs_writedata_release(void *wdata)
nfs_writedata_free(wdata);
}
static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
{
ctx->error = error;
smp_wmb();
set_bit(NFS_CONTEXT_ERROR_WRITE, &ctx->flags);
}
static struct nfs_page *nfs_page_find_request_locked(struct page *page)
{
struct nfs_page *req = NULL;
@@ -945,7 +952,7 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) {
nfs_set_pageerror(page);
req->wb_context->error = task->tk_status;
nfs_context_set_write_error(req->wb_context, task->tk_status);
dprintk(", error = %d\n", task->tk_status);
goto out;
}
@@ -1008,7 +1015,7 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata)
if (task->tk_status < 0) {
nfs_set_pageerror(page);
req->wb_context->error = task->tk_status;
nfs_context_set_write_error(req->wb_context, task->tk_status);
dprintk(", error = %d\n", task->tk_status);
goto remove_request;
}
@@ -1222,7 +1229,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
req->wb_bytes,
(long long)req_offset(req));
if (task->tk_status < 0) {
req->wb_context->error = task->tk_status;
nfs_context_set_write_error(req->wb_context, task->tk_status);
nfs_inode_remove_request(req);
dprintk(", error = %d\n", task->tk_status);
goto next;