RPC: Clean up RPC task structure
Shrink the RPC task structure. Instead of storing separate pointers for task->tk_exit and task->tk_release, put them in a structure. Also pass the user data pointer as a parameter instead of passing it via task->tk_calldata. This enables us to nest callbacks. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
@@ -26,11 +26,12 @@
|
||||
static int nlmclnt_test(struct nlm_rqst *, struct file_lock *);
|
||||
static int nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
|
||||
static int nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
|
||||
static void nlmclnt_unlock_callback(struct rpc_task *);
|
||||
static void nlmclnt_cancel_callback(struct rpc_task *);
|
||||
static int nlm_stat_to_errno(u32 stat);
|
||||
static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);
|
||||
|
||||
static const struct rpc_call_ops nlmclnt_unlock_ops;
|
||||
static const struct rpc_call_ops nlmclnt_cancel_ops;
|
||||
|
||||
/*
|
||||
* Cookie counter for NLM requests
|
||||
*/
|
||||
@@ -399,8 +400,7 @@ in_grace_period:
|
||||
/*
|
||||
* Generic NLM call, async version.
|
||||
*/
|
||||
int
|
||||
nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
|
||||
int nlmsvc_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
|
||||
{
|
||||
struct nlm_host *host = req->a_host;
|
||||
struct rpc_clnt *clnt;
|
||||
@@ -419,13 +419,12 @@ nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
|
||||
msg.rpc_proc = &clnt->cl_procinfo[proc];
|
||||
|
||||
/* bootstrap and kick off the async RPC call */
|
||||
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
|
||||
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int
|
||||
nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
|
||||
static int nlmclnt_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
|
||||
{
|
||||
struct nlm_host *host = req->a_host;
|
||||
struct rpc_clnt *clnt;
|
||||
@@ -448,7 +447,7 @@ nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
|
||||
/* Increment host refcount */
|
||||
nlm_get_host(host);
|
||||
/* bootstrap and kick off the async RPC call */
|
||||
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
|
||||
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
|
||||
if (status < 0)
|
||||
nlm_release_host(host);
|
||||
return status;
|
||||
@@ -664,7 +663,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
|
||||
|
||||
if (req->a_flags & RPC_TASK_ASYNC) {
|
||||
status = nlmclnt_async_call(req, NLMPROC_UNLOCK,
|
||||
nlmclnt_unlock_callback);
|
||||
&nlmclnt_unlock_ops);
|
||||
/* Hrmf... Do the unlock early since locks_remove_posix()
|
||||
* really expects us to free the lock synchronously */
|
||||
do_vfs_lock(fl);
|
||||
@@ -692,10 +691,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
|
||||
return -ENOLCK;
|
||||
}
|
||||
|
||||
static void
|
||||
nlmclnt_unlock_callback(struct rpc_task *task)
|
||||
static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nlm_rqst *req = (struct nlm_rqst *) task->tk_calldata;
|
||||
struct nlm_rqst *req = data;
|
||||
int status = req->a_res.status;
|
||||
|
||||
if (RPC_ASSASSINATED(task))
|
||||
@@ -722,6 +720,10 @@ die:
|
||||
rpc_restart_call(task);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nlmclnt_unlock_ops = {
|
||||
.rpc_call_done = nlmclnt_unlock_callback,
|
||||
};
|
||||
|
||||
/*
|
||||
* Cancel a blocked lock request.
|
||||
* We always use an async RPC call for this in order not to hang a
|
||||
@@ -750,8 +752,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
|
||||
|
||||
nlmclnt_setlockargs(req, fl);
|
||||
|
||||
status = nlmclnt_async_call(req, NLMPROC_CANCEL,
|
||||
nlmclnt_cancel_callback);
|
||||
status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops);
|
||||
if (status < 0) {
|
||||
nlmclnt_release_lockargs(req);
|
||||
kfree(req);
|
||||
@@ -765,10 +766,9 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
|
||||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
nlmclnt_cancel_callback(struct rpc_task *task)
|
||||
static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nlm_rqst *req = (struct nlm_rqst *) task->tk_calldata;
|
||||
struct nlm_rqst *req = data;
|
||||
|
||||
if (RPC_ASSASSINATED(task))
|
||||
goto die;
|
||||
@@ -807,6 +807,10 @@ retry_cancel:
|
||||
rpc_delay(task, 30 * HZ);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nlmclnt_cancel_ops = {
|
||||
.rpc_call_done = nlmclnt_cancel_callback,
|
||||
};
|
||||
|
||||
/*
|
||||
* Convert an NLM status code to a generic kernel errno
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#define NLMDBG_FACILITY NLMDBG_CLIENT
|
||||
|
||||
static u32 nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *);
|
||||
static void nlm4svc_callback_exit(struct rpc_task *);
|
||||
|
||||
static const struct rpc_call_ops nlm4svc_callback_ops;
|
||||
|
||||
/*
|
||||
* Obtain client and file from arguments
|
||||
@@ -470,7 +471,6 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This is the generic lockd callback for async RPC calls
|
||||
*/
|
||||
@@ -494,7 +494,7 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
|
||||
call->a_host = host;
|
||||
memcpy(&call->a_args, resp, sizeof(*resp));
|
||||
|
||||
if (nlmsvc_async_call(call, proc, nlm4svc_callback_exit) < 0)
|
||||
if (nlmsvc_async_call(call, proc, &nlm4svc_callback_ops) < 0)
|
||||
goto error;
|
||||
|
||||
return rpc_success;
|
||||
@@ -504,10 +504,9 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
|
||||
return rpc_system_err;
|
||||
}
|
||||
|
||||
static void
|
||||
nlm4svc_callback_exit(struct rpc_task *task)
|
||||
static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata;
|
||||
struct nlm_rqst *call = data;
|
||||
|
||||
if (task->tk_status < 0) {
|
||||
dprintk("lockd: %4d callback failed (errno = %d)\n",
|
||||
@@ -517,6 +516,10 @@ nlm4svc_callback_exit(struct rpc_task *task)
|
||||
kfree(call);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nlm4svc_callback_ops = {
|
||||
.rpc_call_done = nlm4svc_callback_exit,
|
||||
};
|
||||
|
||||
/*
|
||||
* NLM Server procedures.
|
||||
*/
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
|
||||
static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
|
||||
static int nlmsvc_remove_block(struct nlm_block *block);
|
||||
static void nlmsvc_grant_callback(struct rpc_task *task);
|
||||
|
||||
static const struct rpc_call_ops nlmsvc_grant_ops;
|
||||
|
||||
/*
|
||||
* The list of blocked locks to retry
|
||||
@@ -562,7 +563,7 @@ callback:
|
||||
/* Call the client */
|
||||
nlm_get_host(block->b_call.a_host);
|
||||
if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG,
|
||||
nlmsvc_grant_callback) < 0)
|
||||
&nlmsvc_grant_ops) < 0)
|
||||
nlm_release_host(block->b_call.a_host);
|
||||
up(&file->f_sema);
|
||||
}
|
||||
@@ -575,10 +576,9 @@ callback:
|
||||
* chain once more in order to have it removed by lockd itself (which can
|
||||
* then sleep on the file semaphore without disrupting e.g. the nfs client).
|
||||
*/
|
||||
static void
|
||||
nlmsvc_grant_callback(struct rpc_task *task)
|
||||
static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata;
|
||||
struct nlm_rqst *call = data;
|
||||
struct nlm_block *block;
|
||||
unsigned long timeout;
|
||||
struct sockaddr_in *peer_addr = RPC_PEERADDR(task->tk_client);
|
||||
@@ -614,6 +614,10 @@ nlmsvc_grant_callback(struct rpc_task *task)
|
||||
nlm_release_host(call->a_host);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nlmsvc_grant_ops = {
|
||||
.rpc_call_done = nlmsvc_grant_callback,
|
||||
};
|
||||
|
||||
/*
|
||||
* We received a GRANT_RES callback. Try to find the corresponding
|
||||
* block.
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#define NLMDBG_FACILITY NLMDBG_CLIENT
|
||||
|
||||
static u32 nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *);
|
||||
static void nlmsvc_callback_exit(struct rpc_task *);
|
||||
|
||||
static const struct rpc_call_ops nlmsvc_callback_ops;
|
||||
|
||||
#ifdef CONFIG_LOCKD_V4
|
||||
static u32
|
||||
@@ -518,7 +519,7 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
|
||||
call->a_host = host;
|
||||
memcpy(&call->a_args, resp, sizeof(*resp));
|
||||
|
||||
if (nlmsvc_async_call(call, proc, nlmsvc_callback_exit) < 0)
|
||||
if (nlmsvc_async_call(call, proc, &nlmsvc_callback_ops) < 0)
|
||||
goto error;
|
||||
|
||||
return rpc_success;
|
||||
@@ -528,10 +529,9 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
|
||||
return rpc_system_err;
|
||||
}
|
||||
|
||||
static void
|
||||
nlmsvc_callback_exit(struct rpc_task *task)
|
||||
static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
|
||||
{
|
||||
struct nlm_rqst *call = (struct nlm_rqst *) task->tk_calldata;
|
||||
struct nlm_rqst *call = data;
|
||||
|
||||
if (task->tk_status < 0) {
|
||||
dprintk("lockd: %4d callback failed (errno = %d)\n",
|
||||
@@ -541,6 +541,10 @@ nlmsvc_callback_exit(struct rpc_task *task)
|
||||
kfree(call);
|
||||
}
|
||||
|
||||
static const struct rpc_call_ops nlmsvc_callback_ops = {
|
||||
.rpc_call_done = nlmsvc_callback_exit,
|
||||
};
|
||||
|
||||
/*
|
||||
* NLM Server procedures.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user