#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
*/
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_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp,
- int (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *))
+static int
+nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
+ void *resp)
{
- 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;
+ struct nlm_res res;
+ u32 stat;
- 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, &nlm4svc_callback_ops) < 0)
- return rpc_system_err;
- return rpc_success;
+ if ((stat = nlm4svc_proc_test(rqstp, argp, &res)) == 0)
+ stat = nlm4svc_callback(rqstp, NLMPROC_TEST_RES, &res);
+ return stat;
}
-static int nlm4svc_proc_test_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)
{
- dprintk("lockd: TEST_MSG called\n");
- return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, argp, nlm4svc_proc_test);
-}
+ struct nlm_res res;
+ u32 stat;
-static int nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
- void *resp)
-{
dprintk("lockd: LOCK_MSG called\n");
- return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlm4svc_proc_lock);
+ memset(&res, 0, sizeof(res));
+
+ if ((stat = nlm4svc_proc_lock(rqstp, argp, &res)) == 0)
+ stat = nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, &res);
+ return stat;
}
-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");
- return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlm4svc_proc_cancel);
+ memset(&res, 0, sizeof(res));
+
+ if ((stat = nlm4svc_proc_cancel(rqstp, argp, &res)) == 0)
+ stat = nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, &res);
+ return stat;
}
-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");
- return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlm4svc_proc_unlock);
+ memset(&res, 0, sizeof(res));
+
+ if ((stat = nlm4svc_proc_unlock(rqstp, argp, &res)) == 0)
+ stat = nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, &res);
+ return stat;
}
-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");
- return nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlm4svc_proc_granted);
+ memset(&res, 0, sizeof(res));
+
+ if ((stat = nlm4svc_proc_granted(rqstp, argp, &res)) == 0)
+ stat = nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, &res);
+ return stat;
}
/*
}
+/*
+ * 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;
+
+ 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, &nlm4svc_callback_ops) < 0)
+ goto error;
+
+ return rpc_success;
+ error:
+ kfree(call);
+ nlm_release_host(host);
+ return rpc_system_err;
+}
+
+static void nlm4svc_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 nlm4svc_callback_ops = {
+ .rpc_call_done = nlm4svc_callback_exit,
+};
+
/*
* NLM Server procedures.
*/