X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Flockd%2Fsvcproc.c;h=35681d9cf1fcf52ca816249221a5b4c48b293c4e;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=d210cf304e922f3f2eca906f0ec025cf2832f865;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index d210cf304..35681d9cf 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -22,6 +22,10 @@ #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) @@ -257,92 +261,84 @@ 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_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, - int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) +static int +nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, + void *resp) { - struct nlm_host *host; - struct nlm_rqst *call; - int stat; + struct nlm_res res; + u32 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; - } + dprintk("lockd: TEST_MSG called\n"); + memset(&res, 0, sizeof(res)); - call->a_flags = RPC_TASK_ASYNC; - if (nlm_async_reply(call, proc, &nlmsvc_callback_ops) < 0) - return rpc_system_err; - return rpc_success; + if ((stat = nlmsvc_proc_test(rqstp, argp, &res)) == 0) + stat = nlmsvc_callback(rqstp, NLMPROC_TEST_RES, &res); + return stat; } -static int nlmsvc_proc_test_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) { - dprintk("lockd: TEST_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test); -} + struct nlm_res res; + u32 stat; -static int nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) -{ dprintk("lockd: LOCK_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock); + memset(&res, 0, sizeof(res)); + + if ((stat = nlmsvc_proc_lock(rqstp, argp, &res)) == 0) + stat = nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, &res); + return stat; } -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"); - return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel); + memset(&res, 0, sizeof(res)); + + if ((stat = nlmsvc_proc_cancel(rqstp, argp, &res)) == 0) + stat = nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, &res); + return stat; } 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"); - return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock); + memset(&res, 0, sizeof(res)); + + if ((stat = nlmsvc_proc_unlock(rqstp, argp, &res)) == 0) + stat = nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, &res); + return stat; } 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"); - return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlmsvc_proc_granted); + memset(&res, 0, sizeof(res)); + + if ((stat = nlmsvc_proc_granted(rqstp, argp, &res)) == 0) + stat = nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, &res); + return stat; } /* @@ -500,6 +496,55 @@ 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; + + if (!(call = nlmclnt_alloc_call())) + return rpc_system_err; + + host = nlmclnt_lookup_host(&rqstp->rq_addr, + rqstp->rq_prot, rqstp->rq_vers); + if (!host) { + kfree(call); + return rpc_system_err; + } + + call->a_flags = RPC_TASK_ASYNC; + call->a_host = host; + memcpy(&call->a_args, resp, sizeof(*resp)); + + if (nlmsvc_async_call(call, proc, &nlmsvc_callback_ops) < 0) + goto error; + + return rpc_success; + error: + nlm_release_host(host); + kfree(call); + return rpc_system_err; +} + +static void nlmsvc_callback_exit(struct rpc_task *task, void *data) +{ + struct nlm_rqst *call = data; + + if (task->tk_status < 0) { + dprintk("lockd: %4d callback failed (errno = %d)\n", + task->tk_pid, -task->tk_status); + } + nlm_release_host(call->a_host); + kfree(call); +} + +static const struct rpc_call_ops nlmsvc_callback_ops = { + .rpc_call_done = nlmsvc_callback_exit, +}; + /* * NLM Server procedures. */