diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-05 18:32:03 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2012-06-05 18:38:47 -0400 |
commit | 9bce008bae8b57bc7b007bcc2071d1247a527120 (patch) | |
tree | a9321dc576008102345f3b7d5df7859e5155233e /fs/nfs/write.c | |
parent | cdf66442fab82916fe38f928b4f91815195a294c (diff) |
NFS: Fix a commit bug
The new commit code fails to copy the verifier into the wb_verf field
of _all_ the nfs_page structures; it only copies it into the first entry.
The consequence is that most requests end up failing to match in
nfs_commit_release.
Fix is to copy the verifier into the req->wb_verf field in
nfs_write_completion.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Fred Isaman <iisaman@netapp.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r-- | fs/nfs/write.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e6fe3d69d14c..4d6861c0dc14 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -80,6 +80,7 @@ struct nfs_write_header *nfs_writehdr_alloc(void) | |||
80 | INIT_LIST_HEAD(&hdr->rpc_list); | 80 | INIT_LIST_HEAD(&hdr->rpc_list); |
81 | spin_lock_init(&hdr->lock); | 81 | spin_lock_init(&hdr->lock); |
82 | atomic_set(&hdr->refcnt, 0); | 82 | atomic_set(&hdr->refcnt, 0); |
83 | hdr->verf = &p->verf; | ||
83 | } | 84 | } |
84 | return p; | 85 | return p; |
85 | } | 86 | } |
@@ -619,6 +620,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) | |||
619 | goto next; | 620 | goto next; |
620 | } | 621 | } |
621 | if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) { | 622 | if (test_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) { |
623 | memcpy(&req->wb_verf, hdr->verf, sizeof(req->wb_verf)); | ||
622 | nfs_mark_request_commit(req, hdr->lseg, &cinfo); | 624 | nfs_mark_request_commit(req, hdr->lseg, &cinfo); |
623 | goto next; | 625 | goto next; |
624 | } | 626 | } |
@@ -1255,15 +1257,14 @@ static void nfs_writeback_release_common(void *calldata) | |||
1255 | struct nfs_write_data *data = calldata; | 1257 | struct nfs_write_data *data = calldata; |
1256 | struct nfs_pgio_header *hdr = data->header; | 1258 | struct nfs_pgio_header *hdr = data->header; |
1257 | int status = data->task.tk_status; | 1259 | int status = data->task.tk_status; |
1258 | struct nfs_page *req = hdr->req; | ||
1259 | 1260 | ||
1260 | if ((status >= 0) && nfs_write_need_commit(data)) { | 1261 | if ((status >= 0) && nfs_write_need_commit(data)) { |
1261 | spin_lock(&hdr->lock); | 1262 | spin_lock(&hdr->lock); |
1262 | if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) | 1263 | if (test_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags)) |
1263 | ; /* Do nothing */ | 1264 | ; /* Do nothing */ |
1264 | else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) | 1265 | else if (!test_and_set_bit(NFS_IOHDR_NEED_COMMIT, &hdr->flags)) |
1265 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); | 1266 | memcpy(hdr->verf, &data->verf, sizeof(*hdr->verf)); |
1266 | else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) | 1267 | else if (memcmp(hdr->verf, &data->verf, sizeof(*hdr->verf))) |
1267 | set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags); | 1268 | set_bit(NFS_IOHDR_NEED_RESCHED, &hdr->flags); |
1268 | spin_unlock(&hdr->lock); | 1269 | spin_unlock(&hdr->lock); |
1269 | } | 1270 | } |