diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 3f8ad7c54efa..f96e38155b5c 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -354,14 +354,10 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc) /* * 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 @@ int nlm_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk 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 */ diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index cb51c7025825..a2dd9ccb9b32 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -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, +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_host *host; + struct nlm_rqst *call; + int stat; + + 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; + } + + 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_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { - struct nlm_res res; - u32 stat; - dprintk("lockd: TEST_MSG called\n"); - memset(&res, 0, sizeof(res)); - - if ((stat = nlm4svc_proc_test(rqstp, argp, &res)) == 0) - stat = nlm4svc_callback(rqstp, NLMPROC_TEST_RES, &res); - return stat; + 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, +static int nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { - struct nlm_res res; - u32 stat; - 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. */ diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 956d1d71e2af..d210cf304e92 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -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, +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_host *host; + struct nlm_rqst *call; + int stat; + + 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; + } + + 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_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { - struct nlm_res res; - u32 stat; - dprintk("lockd: TEST_MSG called\n"); - memset(&res, 0, sizeof(res)); - - if ((stat = nlmsvc_proc_test(rqstp, argp, &res)) == 0) - stat = nlmsvc_callback(rqstp, NLMPROC_TEST_RES, &res); - return stat; + 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, +static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, void *resp) { - struct nlm_res res; - u32 stat; - 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. */ diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index e7ba8110d579..a04137d0c5de 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -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);