diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-01 09:22:36 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 15:25:04 -0400 |
commit | fc01cea963a246742ff15e118ce5259e3091352c (patch) | |
tree | bf2bd0fdb99910aa8045d53574504e49c577bbf0 /fs/nfs/nfs4proc.c | |
parent | 8328d59f380e26477b9c1ede99e33d021365bcd1 (diff) |
nfs41: sequence operation
Implement the sequence operation conforming to
http://tools.ietf.org/html/draft-ietf-nfsv4-minorversion1-26
Check returned sessionid, slotid and slot sequenceid in decode_sequence.
If the server returns different values for sessionID, slotID or slot sequence
number than what was sent, the server is looney tunes.
Pass the sequence operation status to nfs41_sequence_done in order to
determine when to increment the slot sequence ID.
Free slot is separated from sequence done.
Signed-off-by: Rahul Iyer <iyer@netapp.com>
Signed-off-by: Ricardo Labiaga <ricardo.labiaga@netapp.com>
Signed-off-by: Andy Adamson<andros@umich.edu>
[nfs41: sequence res use slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfs41: deref slot table in decode_sequence only for minorversion!=0]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: nfs4_call_sync]
[nfs41: remove SEQ4_STATUS_USE_TK_STATUS]
[nfs41: return ESERVERFAULT in decode_sequence]
[no sr_session, no sr_flags]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: use nfs4_call_sync_sequence to renew session lease]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: remove nfs4_call_sync_sequence forward definition]
Signed-off-by: Andy Adamson <andros@netapp.com>
[nfs41: use struct nfs_client for nfs41_proc_async_sequence]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: pass *session in seq_args and seq_res]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41 nfs41_sequence_call_done update error checking]
[nfs41 nfs41_sequence_done update error checking]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: remove switch on error from nfs41_sequence_call_done]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r-- | fs/nfs/nfs4proc.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5fe208b486d4..17768095f0cc 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -4567,6 +4567,98 @@ int nfs4_proc_destroy_session(struct nfs4_session *session) | |||
4567 | return status; | 4567 | return status; |
4568 | } | 4568 | } |
4569 | 4569 | ||
4570 | /* | ||
4571 | * Renew the cl_session lease. | ||
4572 | */ | ||
4573 | static int nfs4_proc_sequence(struct nfs_client *clp, struct rpc_cred *cred) | ||
4574 | { | ||
4575 | struct nfs4_sequence_args args; | ||
4576 | struct nfs4_sequence_res res; | ||
4577 | |||
4578 | struct rpc_message msg = { | ||
4579 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE], | ||
4580 | .rpc_argp = &args, | ||
4581 | .rpc_resp = &res, | ||
4582 | .rpc_cred = cred, | ||
4583 | }; | ||
4584 | |||
4585 | args.sa_cache_this = 0; | ||
4586 | |||
4587 | return nfs4_call_sync_sequence(clp, clp->cl_rpcclient, &msg, &args, | ||
4588 | &res, 0); | ||
4589 | } | ||
4590 | |||
4591 | void nfs41_sequence_call_done(struct rpc_task *task, void *data) | ||
4592 | { | ||
4593 | struct nfs_client *clp = (struct nfs_client *)data; | ||
4594 | |||
4595 | nfs41_sequence_done(clp, task->tk_msg.rpc_resp, task->tk_status); | ||
4596 | |||
4597 | if (task->tk_status < 0) { | ||
4598 | dprintk("%s ERROR %d\n", __func__, task->tk_status); | ||
4599 | |||
4600 | if (_nfs4_async_handle_error(task, NULL, clp, NULL) | ||
4601 | == -EAGAIN) { | ||
4602 | rpc_restart_call(task); | ||
4603 | return; | ||
4604 | } | ||
4605 | } | ||
4606 | nfs41_sequence_free_slot(clp, task->tk_msg.rpc_resp); | ||
4607 | dprintk("%s rpc_cred %p\n", __func__, task->tk_msg.rpc_cred); | ||
4608 | |||
4609 | put_rpccred(task->tk_msg.rpc_cred); | ||
4610 | kfree(task->tk_msg.rpc_argp); | ||
4611 | kfree(task->tk_msg.rpc_resp); | ||
4612 | |||
4613 | dprintk("<-- %s\n", __func__); | ||
4614 | } | ||
4615 | |||
4616 | static void nfs41_sequence_prepare(struct rpc_task *task, void *data) | ||
4617 | { | ||
4618 | struct nfs_client *clp; | ||
4619 | struct nfs4_sequence_args *args; | ||
4620 | struct nfs4_sequence_res *res; | ||
4621 | |||
4622 | clp = (struct nfs_client *)data; | ||
4623 | args = task->tk_msg.rpc_argp; | ||
4624 | res = task->tk_msg.rpc_resp; | ||
4625 | |||
4626 | if (nfs4_setup_sequence(clp, args, res, 0, task)) | ||
4627 | return; | ||
4628 | rpc_call_start(task); | ||
4629 | } | ||
4630 | |||
4631 | static const struct rpc_call_ops nfs41_sequence_ops = { | ||
4632 | .rpc_call_done = nfs41_sequence_call_done, | ||
4633 | .rpc_call_prepare = nfs41_sequence_prepare, | ||
4634 | }; | ||
4635 | |||
4636 | static int nfs41_proc_async_sequence(struct nfs_client *clp, | ||
4637 | struct rpc_cred *cred) | ||
4638 | { | ||
4639 | struct nfs4_sequence_args *args; | ||
4640 | struct nfs4_sequence_res *res; | ||
4641 | struct rpc_message msg = { | ||
4642 | .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SEQUENCE], | ||
4643 | .rpc_cred = cred, | ||
4644 | }; | ||
4645 | |||
4646 | args = kzalloc(sizeof(*args), GFP_KERNEL); | ||
4647 | if (!args) | ||
4648 | return -ENOMEM; | ||
4649 | res = kzalloc(sizeof(*res), GFP_KERNEL); | ||
4650 | if (!res) { | ||
4651 | kfree(args); | ||
4652 | return -ENOMEM; | ||
4653 | } | ||
4654 | res->sr_slotid = NFS4_MAX_SLOT_TABLE; | ||
4655 | msg.rpc_argp = args; | ||
4656 | msg.rpc_resp = res; | ||
4657 | |||
4658 | return rpc_call_async(clp->cl_rpcclient, &msg, RPC_TASK_SOFT, | ||
4659 | &nfs41_sequence_ops, (void *)clp); | ||
4660 | } | ||
4661 | |||
4570 | #endif /* CONFIG_NFS_V4_1 */ | 4662 | #endif /* CONFIG_NFS_V4_1 */ |
4571 | 4663 | ||
4572 | struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { | 4664 | struct nfs4_state_recovery_ops nfs4_reboot_recovery_ops = { |