Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

lockd: Add helper for *_RES callbacks

parent 92737230
Loading
Loading
Loading
Loading
+20 −7
Original line number Diff line number Diff line
@@ -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
 */
+55 −95
Original line number Diff line number Diff line
@@ -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;

	if ((stat = nlm4svc_proc_test(rqstp, argp, &res)) == 0)
		stat = nlm4svc_callback(rqstp, NLMPROC_TEST_RES, &res);
	stat = func(rqstp, argp, &call->a_res);
	if (stat != 0) {
		nlm_release_call(call);
		return stat;
	}

static int
nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
	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");
	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.
 */
+53 −90
Original line number Diff line number Diff line
@@ -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;

	if ((stat = nlmsvc_proc_test(rqstp, argp, &res)) == 0)
		stat = nlmsvc_callback(rqstp, NLMPROC_TEST_RES, &res);
	stat = func(rqstp, argp, &call->a_res);
	if (stat != 0) {
		nlm_release_call(call);
		return stat;
	}

static int
nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp,
	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");
	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.
 */
+1 −0
Original line number Diff line number Diff line
@@ -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);