diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2007-04-15 01:11:52 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-04-15 06:46:48 +0200 |
commit | 60fa3f769f7651a60125a0f44e3ffe3246d7cf39 (patch) | |
tree | 1acbd0749726d8bddafab619e173874af0153c84 /fs/nfs/direct.c | |
parent | NFS: Fix an Oops in nfs_setattr() (diff) | |
download | linux-60fa3f769f7651a60125a0f44e3ffe3246d7cf39.tar.xz linux-60fa3f769f7651a60125a0f44e3ffe3246d7cf39.zip |
NFS: Fix two bugs in the O_DIRECT write code
Do not flag an error if the COMMIT call fails and we decide to resend the
writes. Let the resend flag the error if it fails.
If a write has failed, then nfs_direct_write_result should not attempt to
send a commit. It should just exit asap and return the error to the user.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nfs/direct.c')
-rw-r--r-- | fs/nfs/direct.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index b1c98ea39b72..2877744cb606 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -432,10 +432,10 @@ static void nfs_direct_commit_result(struct rpc_task *task, void *calldata) if (NFS_PROTO(data->inode)->commit_done(task, data) != 0) return; if (unlikely(task->tk_status < 0)) { - dreq->error = task->tk_status; + dprintk("NFS: %5u commit failed with error %d.\n", + task->tk_pid, task->tk_status); dreq->flags = NFS_ODIRECT_RESCHED_WRITES; - } - if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) { + } else if (memcmp(&dreq->verf, &data->verf, sizeof(data->verf))) { dprintk("NFS: %5u commit verify failed\n", task->tk_pid); dreq->flags = NFS_ODIRECT_RESCHED_WRITES; } @@ -531,9 +531,12 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata) spin_lock(&dreq->lock); + if (unlikely(dreq->error != 0)) + goto out_unlock; if (unlikely(status < 0)) { + /* An error has occured, so we should not commit */ + dreq->flags = 0; dreq->error = status; - goto out_unlock; } dreq->count += data->res.count; |