aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-09-22 13:39:11 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2016-09-27 14:34:50 -0400
commit9c27869d3f0680fa01d15616891a666d9e30fd83 (patch)
tree20a4f8f3925b4b0568fbeb191e6d788d28512907 /fs/nfs
parent26f474432a7b4be336ed40d94f5a8245781cfc67 (diff)
NFSv4: Pass the stateid to the exception handler in nfs4_read/write_done_cb
The actual stateid used in the READ or WRITE can represent a delegation, a lock or a stateid, so it is useful to pass it as an argument to the exception handler when an expired/revoked response is received from the server. It also ensures that we don't re-label the state as needing recovery if that has already occurred. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Tested-by: Oleg Drokin <green@linuxhacker.ru> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/nfs4proc.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 446de949f960..d1e60c915a07 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -4525,11 +4525,18 @@ static int nfs4_read_done_cb(struct rpc_task *task, struct nfs_pgio_header *hdr)
4525 struct nfs_server *server = NFS_SERVER(hdr->inode); 4525 struct nfs_server *server = NFS_SERVER(hdr->inode);
4526 4526
4527 trace_nfs4_read(hdr, task->tk_status); 4527 trace_nfs4_read(hdr, task->tk_status);
4528 if (nfs4_async_handle_error(task, server, 4528 if (task->tk_status < 0) {
4529 hdr->args.context->state, 4529 struct nfs4_exception exception = {
4530 NULL) == -EAGAIN) { 4530 .inode = hdr->inode,
4531 rpc_restart_call_prepare(task); 4531 .state = hdr->args.context->state,
4532 return -EAGAIN; 4532 .stateid = &hdr->args.stateid,
4533 };
4534 task->tk_status = nfs4_async_handle_exception(task,
4535 server, task->tk_status, &exception);
4536 if (exception.retry) {
4537 rpc_restart_call_prepare(task);
4538 return -EAGAIN;
4539 }
4533 } 4540 }
4534 4541
4535 __nfs4_read_done_cb(hdr); 4542 __nfs4_read_done_cb(hdr);
@@ -4598,11 +4605,19 @@ static int nfs4_write_done_cb(struct rpc_task *task,
4598 struct inode *inode = hdr->inode; 4605 struct inode *inode = hdr->inode;
4599 4606
4600 trace_nfs4_write(hdr, task->tk_status); 4607 trace_nfs4_write(hdr, task->tk_status);
4601 if (nfs4_async_handle_error(task, NFS_SERVER(inode), 4608 if (task->tk_status < 0) {
4602 hdr->args.context->state, 4609 struct nfs4_exception exception = {
4603 NULL) == -EAGAIN) { 4610 .inode = hdr->inode,
4604 rpc_restart_call_prepare(task); 4611 .state = hdr->args.context->state,
4605 return -EAGAIN; 4612 .stateid = &hdr->args.stateid,
4613 };
4614 task->tk_status = nfs4_async_handle_exception(task,
4615 NFS_SERVER(inode), task->tk_status,
4616 &exception);
4617 if (exception.retry) {
4618 rpc_restart_call_prepare(task);
4619 return -EAGAIN;
4620 }
4606 } 4621 }
4607 if (task->tk_status >= 0) { 4622 if (task->tk_status >= 0) {
4608 renew_lease(NFS_SERVER(inode), hdr->timestamp); 4623 renew_lease(NFS_SERVER(inode), hdr->timestamp);