Commit 6b9b2107 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

nfsd: give up on CB_LAYOUTRECALLs after two lease periods

Have the CB_LAYOUTRECALL code treat NFS4_OK and NFS4ERR_DELAY returns
equivalently. Change the code to periodically resend CB_LAYOUTRECALLS
until the ls_layouts list is empty or the client returns a different
error code.

If we go for two lease periods without the list being emptied or the
client sending a hard error, then we give up and clean out the list
anyway.
Signed-off-by: default avatarJeff Layton <jeff.layton@primarydata.com>
Tested-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 691412b4
...@@ -623,24 +623,39 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) ...@@ -623,24 +623,39 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
{ {
struct nfs4_layout_stateid *ls = struct nfs4_layout_stateid *ls =
container_of(cb, struct nfs4_layout_stateid, ls_recall); container_of(cb, struct nfs4_layout_stateid, ls_recall);
struct nfsd_net *nn;
ktime_t now, cutoff;
LIST_HEAD(reaplist); LIST_HEAD(reaplist);
switch (task->tk_status) { switch (task->tk_status) {
case 0: case 0:
case -NFS4ERR_DELAY:
/*
* Anything left? If not, then call it done. Note that we don't
* take the spinlock since this is an optimization and nothing
* should get added until the cb counter goes to zero.
*/
if (list_empty(&ls->ls_layouts))
return 1; return 1;
/* Poll the client until it's done with the layout */
now = ktime_get();
nn = net_generic(ls->ls_stid.sc_client->net, nfsd_net_id);
/* Client gets 2 lease periods to return it */
cutoff = ktime_add_ns(task->tk_start,
nn->nfsd4_lease * NSEC_PER_SEC * 2);
if (ktime_before(now, cutoff)) {
rpc_delay(task, HZ/100); /* 10 mili-seconds */
return 0;
}
/* Fallthrough */
case -NFS4ERR_NOMATCHING_LAYOUT: case -NFS4ERR_NOMATCHING_LAYOUT:
trace_layout_recall_done(&ls->ls_stid.sc_stateid); trace_layout_recall_done(&ls->ls_stid.sc_stateid);
task->tk_status = 0; task->tk_status = 0;
return 1; return 1;
case -NFS4ERR_DELAY:
/* Poll the client until it's done with the layout */
/* FIXME: cap number of retries.
* The pnfs standard states that we need to only expire
* the client after at-least "lease time" .eg lease-time * 2
* when failing to communicate a recall
*/
rpc_delay(task, HZ/100); /* 10 mili-seconds */
return 0;
default: default:
/* /*
* Unknown error or non-responding client, we'll need to fence. * Unknown error or non-responding client, we'll need to fence.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment