Commit d4716624 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

lockd: Add helper for *_RES callbacks


Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 92737230
......@@ -354,14 +354,10 @@ in_grace_period:
/*
* Generic NLM call, async version.
*/
int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
static int __nlm_async_call(struct nlm_rqst *req, u32 proc, struct rpc_message *msg, const struct rpc_call_ops *tk_ops)
{
struct nlm_host *host = req->a_host;
struct rpc_clnt *clnt;
struct rpc_message msg = {
.rpc_argp = &req->a_args,
.rpc_resp = &req->a_res,
};
int status = -ENOLCK;
dprintk("lockd: call procedure %d on %s (async)\n",
......@@ -371,10 +367,10 @@ int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk
clnt = nlm_bind_host(host);
if (clnt == NULL)
goto out_err;
msg.rpc_proc = &clnt->cl_procinfo[proc];
msg->rpc_proc = &clnt->cl_procinfo[proc];
/* bootstrap and kick off the async RPC call */
status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
status = rpc_call_async(clnt, msg, RPC_TASK_ASYNC, tk_ops, req);
if (status == 0)
return 0;
out_err:
......@@ -382,6 +378,23 @@ out_err:
return status;
}
int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
{
struct rpc_message msg = {
.rpc_argp = &req->a_args,
.rpc_resp = &req->a_res,
};
return __nlm_async_call(req, proc, &msg, tk_ops);
}
int nlm_async_reply(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
{
struct rpc_message msg = {
.rpc_argp = &req->a_res,
};
return __nlm_async_call(req, proc, &msg, tk_ops);
}
/*
* TEST for the presence of a conflicting lock
*/
......
......@@ -21,10 +21,6 @@
#define NLMDBG_FACILITY NLMDBG_CLIENT
static u32 nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *);
static const struct rpc_call_ops nlm4svc_callback_ops;
/*
* Obtain client and file from arguments
*/
......@@ -233,84 +229,90 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp,
return rpc_success;
}
/*
* This is the generic lockd callback for async RPC calls
*/
static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %4d callback returned %d\n", task->tk_pid,
-task->tk_status);
}
static void nlm4svc_callback_release(void *data)
{
nlm_release_call(data);
}
static const struct rpc_call_ops nlm4svc_callback_ops = {
.rpc_call_done = nlm4svc_callback_exit,
.rpc_release = nlm4svc_callback_release,
};
/*
* `Async' versions of the above service routines. They aren't really,
* because we send the callback before the reply proper. I hope this
* doesn't break any clients.
*/
static int
nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
static int nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *))
{
struct nlm_res res;
u32 stat;
struct nlm_host *host;
struct nlm_rqst *call;
int stat;
dprintk("lockd: TEST_MSG called\n");
memset(&res, 0, sizeof(res));
host = nlmsvc_lookup_host(rqstp);
if (host == NULL)
return rpc_system_err;
call = nlm_alloc_call(host);
if (call == NULL)
return rpc_system_err;
stat = func(rqstp, argp, &call->a_res);
if (stat != 0) {
nlm_release_call(call);
return stat;
}
if ((stat = nlm4svc_proc_test(rqstp, argp, &res)) == 0)
stat = nlm4svc_callback(rqstp, NLMPROC_TEST_RES, &res);
return stat;
call->a_flags = RPC_TASK_ASYNC;
if (nlm_async_reply(call, proc, &nlm4svc_callback_ops) < 0)
return rpc_system_err;
return rpc_success;
}
static int
nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: TEST_MSG called\n");
return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, argp, nlm4svc_proc_test);
}
static int nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
dprintk("lockd: LOCK_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlm4svc_proc_lock(rqstp, argp, &res)) == 0)
stat = nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, &res);
return stat;
return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlm4svc_proc_lock);
}
static int
nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: CANCEL_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlm4svc_proc_cancel(rqstp, argp, &res)) == 0)
stat = nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, &res);
return stat;
return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlm4svc_proc_cancel);
}
static int
nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: UNLOCK_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlm4svc_proc_unlock(rqstp, argp, &res)) == 0)
stat = nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, &res);
return stat;
return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlm4svc_proc_unlock);
}
static int
nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: GRANTED_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlm4svc_proc_granted(rqstp, argp, &res)) == 0)
stat = nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, &res);
return stat;
return nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlm4svc_proc_granted);
}
/*
......@@ -471,48 +473,6 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp,
}
/*
* This is the generic lockd callback for async RPC calls
*/
static u32
nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
{
struct nlm_host *host;
struct nlm_rqst *call;
host = nlmsvc_lookup_host(rqstp);
if (host == NULL)
return rpc_system_err;
call = nlm_alloc_call(host);
if (call == NULL)
return rpc_system_err;
call->a_flags = RPC_TASK_ASYNC;
memcpy(&call->a_args, resp, sizeof(*resp));
if (nlm_async_call(call, proc, &nlm4svc_callback_ops) < 0)
return rpc_system_err;
return rpc_success;
}
static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %4d callback returned %d\n", task->tk_pid,
-task->tk_status);
}
static void nlm4svc_callback_release(void *data)
{
nlm_release_call(data);
}
static const struct rpc_call_ops nlm4svc_callback_ops = {
.rpc_call_done = nlm4svc_callback_exit,
.rpc_release = nlm4svc_callback_release,
};
/*
* NLM Server procedures.
*/
......
......@@ -22,10 +22,6 @@
#define NLMDBG_FACILITY NLMDBG_CLIENT
static u32 nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *);
static const struct rpc_call_ops nlmsvc_callback_ops;
#ifdef CONFIG_LOCKD_V4
static u32
cast_to_nlm(u32 status, u32 vers)
......@@ -261,84 +257,92 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp,
return rpc_success;
}
/*
* This is the generic lockd callback for async RPC calls
*/
static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %4d callback returned %d\n", task->tk_pid,
-task->tk_status);
}
static void nlmsvc_callback_release(void *data)
{
nlm_release_call(data);
}
static const struct rpc_call_ops nlmsvc_callback_ops = {
.rpc_call_done = nlmsvc_callback_exit,
.rpc_release = nlmsvc_callback_release,
};
/*
* `Async' versions of the above service routines. They aren't really,
* because we send the callback before the reply proper. I hope this
* doesn't break any clients.
*/
static int
nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
static int nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *))
{
struct nlm_res res;
u32 stat;
struct nlm_host *host;
struct nlm_rqst *call;
int stat;
dprintk("lockd: TEST_MSG called\n");
memset(&res, 0, sizeof(res));
host = nlmsvc_lookup_host(rqstp);
if (host == NULL)
return rpc_system_err;
call = nlm_alloc_call(host);
if (call == NULL)
return rpc_system_err;
stat = func(rqstp, argp, &call->a_res);
if (stat != 0) {
nlm_release_call(call);
return stat;
}
if ((stat = nlmsvc_proc_test(rqstp, argp, &res)) == 0)
stat = nlmsvc_callback(rqstp, NLMPROC_TEST_RES, &res);
return stat;
call->a_flags = RPC_TASK_ASYNC;
if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0)
return rpc_system_err;
return rpc_success;
}
static int
nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: TEST_MSG called\n");
return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test);
}
static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
dprintk("lockd: LOCK_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlmsvc_proc_lock(rqstp, argp, &res)) == 0)
stat = nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, &res);
return stat;
return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock);
}
static int
nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
static int nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: CANCEL_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlmsvc_proc_cancel(rqstp, argp, &res)) == 0)
stat = nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, &res);
return stat;
return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel);
}
static int
nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: UNLOCK_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlmsvc_proc_unlock(rqstp, argp, &res)) == 0)
stat = nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, &res);
return stat;
return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock);
}
static int
nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
void *resp)
{
struct nlm_res res;
u32 stat;
dprintk("lockd: GRANTED_MSG called\n");
memset(&res, 0, sizeof(res));
if ((stat = nlmsvc_proc_granted(rqstp, argp, &res)) == 0)
stat = nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, &res);
return stat;
return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlmsvc_proc_granted);
}
/*
......@@ -496,47 +500,6 @@ nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp,
return rpc_success;
}
/*
* This is the generic lockd callback for async RPC calls
*/
static u32
nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
{
struct nlm_host *host;
struct nlm_rqst *call;
host = nlmsvc_lookup_host(rqstp);
if (host == NULL)
return rpc_system_err;
call = nlm_alloc_call(host);
if (call == NULL)
return rpc_system_err;
call->a_flags = RPC_TASK_ASYNC;
memcpy(&call->a_args, resp, sizeof(*resp));
if (nlm_async_call(call, proc, &nlmsvc_callback_ops) < 0)
return rpc_system_err;
return rpc_success;
}
static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
{
dprintk("lockd: %4d callback returned %d\n", task->tk_pid,
-task->tk_status);
}
static void nlmsvc_callback_release(void *data)
{
nlm_release_call(data);
}
static const struct rpc_call_ops nlmsvc_callback_ops = {
.rpc_call_done = nlmsvc_callback_exit,
.rpc_release = nlmsvc_callback_release,
};
/*
* NLM Server procedures.
*/
......
......@@ -151,6 +151,7 @@ extern unsigned long nlmsvc_timeout;
struct nlm_rqst * nlm_alloc_call(struct nlm_host *host);
void nlm_release_call(struct nlm_rqst *);
int nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *);
int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *);
struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl);
void nlmclnt_finish_block(struct nlm_wait *block);
int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout);
......
Supports Markdown
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