Commit 63e4863f authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: make recall callback an asynchronous rpc

As with the probe, this removes the need for another kthread.
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 3aea09dc
...@@ -494,6 +494,49 @@ nfsd4_probe_callback(struct nfs4_client *clp) ...@@ -494,6 +494,49 @@ nfsd4_probe_callback(struct nfs4_client *clp)
do_probe_callback(clp); do_probe_callback(clp);
} }
static void nfsd4_cb_recall_done(struct rpc_task *task, void *calldata)
{
struct nfs4_delegation *dp = calldata;
struct nfs4_client *clp = dp->dl_client;
switch (task->tk_status) {
case -EIO:
/* Network partition? */
atomic_set(&clp->cl_cb_conn.cb_set, 0);
warn_no_callback_path(clp, task->tk_status);
case -EBADHANDLE:
case -NFS4ERR_BAD_STATEID:
/* Race: client probably got cb_recall
* before open reply granting delegation */
break;
default:
/* success, or error we can't handle */
return;
}
if (dp->dl_retries--) {
rpc_delay(task, 2*HZ);
task->tk_status = 0;
rpc_restart_call(task);
} else {
atomic_set(&clp->cl_cb_conn.cb_set, 0);
warn_no_callback_path(clp, task->tk_status);
}
}
static void nfsd4_cb_recall_release(void *calldata)
{
struct nfs4_delegation *dp = calldata;
struct nfs4_client *clp = dp->dl_client;
nfs4_put_delegation(dp);
put_nfs4_client(clp);
}
static const struct rpc_call_ops nfsd4_cb_recall_ops = {
.rpc_call_done = nfsd4_cb_recall_done,
.rpc_release = nfsd4_cb_recall_release,
};
/* /*
* called with dp->dl_count inc'ed. * called with dp->dl_count inc'ed.
*/ */
...@@ -507,32 +550,13 @@ nfsd4_cb_recall(struct nfs4_delegation *dp) ...@@ -507,32 +550,13 @@ nfsd4_cb_recall(struct nfs4_delegation *dp)
.rpc_argp = dp, .rpc_argp = dp,
.rpc_cred = clp->cl_cb_conn.cb_cred .rpc_cred = clp->cl_cb_conn.cb_cred
}; };
int status = 0; int status;
dp->dl_retries = 1; dp->dl_retries = 1;
status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT); status = rpc_call_async(clnt, &msg, RPC_TASK_SOFT,
while (dp->dl_retries--) { &nfsd4_cb_recall_ops, dp);
switch (status) { if (status) {
case -EIO: put_nfs4_client(clp);
/* Network partition? */ nfs4_put_delegation(dp);
atomic_set(&clp->cl_cb_conn.cb_set, 0);
case -EBADHANDLE:
case -NFS4ERR_BAD_STATEID:
/* Race: client probably got cb_recall
* before open reply granting delegation */
break;
default:
goto out_put_cred;
}
ssleep(2);
status = rpc_call_sync(clnt, &msg, RPC_TASK_SOFT);
} }
out_put_cred:
/*
* Success or failure, now we're either waiting for lease expiration
* or deleg_return.
*/
put_nfs4_client(clp);
nfs4_put_delegation(dp);
return;
} }
...@@ -2059,19 +2059,6 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access) ...@@ -2059,19 +2059,6 @@ nfs4_file_downgrade(struct file *filp, unsigned int share_access)
} }
} }
/*
* Recall a delegation
*/
static int
do_recall(void *__dp)
{
struct nfs4_delegation *dp = __dp;
dp->dl_file->fi_had_conflict = true;
nfsd4_cb_recall(dp);
return 0;
}
/* /*
* Spawn a thread to perform a recall on the delegation represented * Spawn a thread to perform a recall on the delegation represented
* by the lease (file_lock) * by the lease (file_lock)
...@@ -2083,8 +2070,7 @@ do_recall(void *__dp) ...@@ -2083,8 +2070,7 @@ do_recall(void *__dp)
static static
void nfsd_break_deleg_cb(struct file_lock *fl) void nfsd_break_deleg_cb(struct file_lock *fl)
{ {
struct nfs4_delegation *dp= (struct nfs4_delegation *)fl->fl_owner; struct nfs4_delegation *dp = (struct nfs4_delegation *)fl->fl_owner;
struct task_struct *t;
dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl); dprintk("NFSD nfsd_break_deleg_cb: dp %p fl %p\n",dp,fl);
if (!dp) if (!dp)
...@@ -2112,16 +2098,8 @@ void nfsd_break_deleg_cb(struct file_lock *fl) ...@@ -2112,16 +2098,8 @@ void nfsd_break_deleg_cb(struct file_lock *fl)
*/ */
fl->fl_break_time = 0; fl->fl_break_time = 0;
t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall"); dp->dl_file->fi_had_conflict = true;
if (IS_ERR(t)) { nfsd4_cb_recall(dp);
struct nfs4_client *clp = dp->dl_client;
printk(KERN_INFO "NFSD: Callback thread failed for "
"for client (clientid %08x/%08x)\n",
clp->cl_clientid.cl_boot, clp->cl_clientid.cl_id);
put_nfs4_client(dp->dl_client);
nfs4_put_delegation(dp);
}
} }
/* /*
......
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