nfs41: get_lease_time
get_lease_time uses the FSINFO rpc operation to get the lease time attribute. nfs4_get_lease_time() is only called from the state manager on session setup so don't recover from clientid or sequence level errors. We do need to recover from NFS4ERR_DELAY or NFS4ERR_GRACE. Use NFS4_POLL_RETRY_MIN - the Linux server returns NFS4ERR_DELAY when an upcall is needed to resolve an uncached export referenced by a file handle. [nfs41: sequence res use slotid] Signed-off-by: Andy Adamson<andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: remove extraneous rpc_clnt pointer] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: have get_lease_time work on nfs_client] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: get_lease_time recover from NFS4ERR_DELAY] 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] [define nfs4_get_lease_time_{args,res}] Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
committed by
Benny Halevy
parent
99fe60d062
commit
2050f0cc07
@@ -4189,6 +4189,100 @@ static int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
|
||||
return status;
|
||||
}
|
||||
|
||||
struct nfs4_get_lease_time_data {
|
||||
struct nfs4_get_lease_time_args *args;
|
||||
struct nfs4_get_lease_time_res *res;
|
||||
struct nfs_client *clp;
|
||||
};
|
||||
|
||||
static void nfs4_get_lease_time_prepare(struct rpc_task *task,
|
||||
void *calldata)
|
||||
{
|
||||
int ret;
|
||||
struct nfs4_get_lease_time_data *data =
|
||||
(struct nfs4_get_lease_time_data *)calldata;
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
/* just setup sequence, do not trigger session recovery
|
||||
since we're invoked within one */
|
||||
ret = nfs41_setup_sequence(data->clp->cl_session,
|
||||
&data->args->la_seq_args,
|
||||
&data->res->lr_seq_res, 0, task);
|
||||
|
||||
BUG_ON(ret == -EAGAIN);
|
||||
rpc_call_start(task);
|
||||
dprintk("<-- %s\n", __func__);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from nfs4_state_manager thread for session setup, so don't recover
|
||||
* from sequence operation or clientid errors.
|
||||
*/
|
||||
static void nfs4_get_lease_time_done(struct rpc_task *task, void *calldata)
|
||||
{
|
||||
struct nfs4_get_lease_time_data *data =
|
||||
(struct nfs4_get_lease_time_data *)calldata;
|
||||
|
||||
dprintk("--> %s\n", __func__);
|
||||
nfs41_sequence_done(data->clp, &data->res->lr_seq_res, task->tk_status);
|
||||
switch (task->tk_status) {
|
||||
case -NFS4ERR_DELAY:
|
||||
case -NFS4ERR_GRACE:
|
||||
dprintk("%s Retry: tk_status %d\n", __func__, task->tk_status);
|
||||
rpc_delay(task, NFS4_POLL_RETRY_MIN);
|
||||
task->tk_status = 0;
|
||||
rpc_restart_call(task);
|
||||
return;
|
||||
}
|
||||
nfs41_sequence_free_slot(data->clp, &data->res->lr_seq_res);
|
||||
dprintk("<-- %s\n", __func__);
|
||||
}
|
||||
|
||||
struct rpc_call_ops nfs4_get_lease_time_ops = {
|
||||
.rpc_call_prepare = nfs4_get_lease_time_prepare,
|
||||
.rpc_call_done = nfs4_get_lease_time_done,
|
||||
};
|
||||
|
||||
int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
|
||||
{
|
||||
struct rpc_task *task;
|
||||
struct nfs4_get_lease_time_args args;
|
||||
struct nfs4_get_lease_time_res res = {
|
||||
.lr_fsinfo = fsinfo,
|
||||
};
|
||||
struct nfs4_get_lease_time_data data = {
|
||||
.args = &args,
|
||||
.res = &res,
|
||||
.clp = clp,
|
||||
};
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GET_LEASE_TIME],
|
||||
.rpc_argp = &args,
|
||||
.rpc_resp = &res,
|
||||
};
|
||||
struct rpc_task_setup task_setup = {
|
||||
.rpc_client = clp->cl_rpcclient,
|
||||
.rpc_message = &msg,
|
||||
.callback_ops = &nfs4_get_lease_time_ops,
|
||||
.callback_data = &data
|
||||
};
|
||||
int status;
|
||||
|
||||
res.lr_seq_res.sr_slotid = NFS4_MAX_SLOT_TABLE;
|
||||
dprintk("--> %s\n", __func__);
|
||||
task = rpc_run_task(&task_setup);
|
||||
|
||||
if (IS_ERR(task))
|
||||
status = PTR_ERR(task);
|
||||
else {
|
||||
status = task->tk_status;
|
||||
rpc_put_task(task);
|
||||
}
|
||||
dprintk("<-- %s return %d\n", __func__, status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Destroy the slot table */
|
||||
static void nfs4_destroy_slot_table(struct nfs4_session *session)
|
||||
{
|
||||
|
Reference in New Issue
Block a user