linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / lockd / svc4proc.c
index a2dd9cc..b10f913 100644 (file)
 
 #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
  */
@@ -229,90 +233,84 @@ 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_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;
 }
 
 /*
@@ -473,6 +471,55 @@ 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;
+
+       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.
  */