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

Commit 963d8fe5 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

RPC: Clean up RPC task structure



 Shrink the RPC task structure. Instead of storing separate pointers
 for task->tk_exit and task->tk_release, put them in a structure.

 Also pass the user data pointer as a parameter instead of passing it via
 task->tk_calldata. This enables us to nest callbacks.

 Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent abbcf28f
Loading
Loading
Loading
Loading
+21 −17
Original line number Diff line number Diff line
@@ -26,11 +26,12 @@
static int	nlmclnt_test(struct nlm_rqst *, struct file_lock *);
static int	nlmclnt_lock(struct nlm_rqst *, struct file_lock *);
static int	nlmclnt_unlock(struct nlm_rqst *, struct file_lock *);
static void	nlmclnt_unlock_callback(struct rpc_task *);
static void	nlmclnt_cancel_callback(struct rpc_task *);
static int	nlm_stat_to_errno(u32 stat);
static void	nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host);

static const struct rpc_call_ops nlmclnt_unlock_ops;
static const struct rpc_call_ops nlmclnt_cancel_ops;

/*
 * Cookie counter for NLM requests
 */
@@ -399,8 +400,7 @@ nlmclnt_call(struct nlm_rqst *req, u32 proc)
/*
 * Generic NLM call, async version.
 */
int
nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
int nlmsvc_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
{
	struct nlm_host	*host = req->a_host;
	struct rpc_clnt	*clnt;
@@ -419,13 +419,12 @@ nlmsvc_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
	msg.rpc_proc = &clnt->cl_procinfo[proc];

        /* bootstrap and kick off the async RPC call */
        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);

	return status;
}

static int
nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
static int nlmclnt_async_call(struct nlm_rqst *req, u32 proc, const struct rpc_call_ops *tk_ops)
{
	struct nlm_host	*host = req->a_host;
	struct rpc_clnt	*clnt;
@@ -448,7 +447,7 @@ nlmclnt_async_call(struct nlm_rqst *req, u32 proc, rpc_action callback)
	/* Increment host refcount */
	nlm_get_host(host);
        /* bootstrap and kick off the async RPC call */
        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, callback, req);
        status = rpc_call_async(clnt, &msg, RPC_TASK_ASYNC, tk_ops, req);
	if (status < 0)
		nlm_release_host(host);
	return status;
@@ -664,7 +663,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)

	if (req->a_flags & RPC_TASK_ASYNC) {
		status = nlmclnt_async_call(req, NLMPROC_UNLOCK,
					nlmclnt_unlock_callback);
					&nlmclnt_unlock_ops);
		/* Hrmf... Do the unlock early since locks_remove_posix()
		 * really expects us to free the lock synchronously */
		do_vfs_lock(fl);
@@ -692,10 +691,9 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
	return -ENOLCK;
}

static void
nlmclnt_unlock_callback(struct rpc_task *task)
static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
{
	struct nlm_rqst	*req = (struct nlm_rqst *) task->tk_calldata;
	struct nlm_rqst	*req = data;
	int		status = req->a_res.status;

	if (RPC_ASSASSINATED(task))
@@ -722,6 +720,10 @@ nlmclnt_unlock_callback(struct rpc_task *task)
	rpc_restart_call(task);
}

static const struct rpc_call_ops nlmclnt_unlock_ops = {
	.rpc_call_done = nlmclnt_unlock_callback,
};

/*
 * Cancel a blocked lock request.
 * We always use an async RPC call for this in order not to hang a
@@ -750,8 +752,7 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)

	nlmclnt_setlockargs(req, fl);

	status = nlmclnt_async_call(req, NLMPROC_CANCEL,
					nlmclnt_cancel_callback);
	status = nlmclnt_async_call(req, NLMPROC_CANCEL, &nlmclnt_cancel_ops);
	if (status < 0) {
		nlmclnt_release_lockargs(req);
		kfree(req);
@@ -765,10 +766,9 @@ nlmclnt_cancel(struct nlm_host *host, struct file_lock *fl)
	return status;
}

static void
nlmclnt_cancel_callback(struct rpc_task *task)
static void nlmclnt_cancel_callback(struct rpc_task *task, void *data)
{
	struct nlm_rqst	*req = (struct nlm_rqst *) task->tk_calldata;
	struct nlm_rqst	*req = data;

	if (RPC_ASSASSINATED(task))
		goto die;
@@ -807,6 +807,10 @@ nlmclnt_cancel_callback(struct rpc_task *task)
	rpc_delay(task, 30 * HZ);
}

static const struct rpc_call_ops nlmclnt_cancel_ops = {
	.rpc_call_done = nlmclnt_cancel_callback,
};

/*
 * Convert an NLM status code to a generic kernel errno
 */
+9 −6
Original line number Diff line number Diff line
@@ -22,7 +22,8 @@
#define NLMDBG_FACILITY		NLMDBG_CLIENT

static u32	nlm4svc_callback(struct svc_rqst *, u32, struct nlm_res *);
static void	nlm4svc_callback_exit(struct rpc_task *);

static const struct rpc_call_ops nlm4svc_callback_ops;

/*
 * Obtain client and file from arguments
@@ -470,7 +471,6 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp,
}



/*
 * This is the generic lockd callback for async RPC calls
 */
@@ -494,7 +494,7 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
	call->a_host  = host;
	memcpy(&call->a_args, resp, sizeof(*resp));

	if (nlmsvc_async_call(call, proc, nlm4svc_callback_exit) < 0)
	if (nlmsvc_async_call(call, proc, &nlm4svc_callback_ops) < 0)
		goto error;

	return rpc_success;
@@ -504,10 +504,9 @@ nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
	return rpc_system_err;
}

static void
nlm4svc_callback_exit(struct rpc_task *task)
static void nlm4svc_callback_exit(struct rpc_task *task, void *data)
{
	struct nlm_rqst	*call = (struct nlm_rqst *) task->tk_calldata;
	struct nlm_rqst	*call = data;

	if (task->tk_status < 0) {
		dprintk("lockd: %4d callback failed (errno = %d)\n",
@@ -517,6 +516,10 @@ nlm4svc_callback_exit(struct rpc_task *task)
	kfree(call);
}

static const struct rpc_call_ops nlm4svc_callback_ops = {
	.rpc_call_done = nlm4svc_callback_exit,
};

/*
 * NLM Server procedures.
 */
+9 −5
Original line number Diff line number Diff line
@@ -41,7 +41,8 @@

static void	nlmsvc_insert_block(struct nlm_block *block, unsigned long);
static int	nlmsvc_remove_block(struct nlm_block *block);
static void	nlmsvc_grant_callback(struct rpc_task *task);

static const struct rpc_call_ops nlmsvc_grant_ops;

/*
 * The list of blocked locks to retry
@@ -562,7 +563,7 @@ nlmsvc_grant_blocked(struct nlm_block *block)
	/* Call the client */
	nlm_get_host(block->b_call.a_host);
	if (nlmsvc_async_call(&block->b_call, NLMPROC_GRANTED_MSG,
						nlmsvc_grant_callback) < 0)
						&nlmsvc_grant_ops) < 0)
		nlm_release_host(block->b_call.a_host);
	up(&file->f_sema);
}
@@ -575,10 +576,9 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 * chain once more in order to have it removed by lockd itself (which can
 * then sleep on the file semaphore without disrupting e.g. the nfs client).
 */
static void
nlmsvc_grant_callback(struct rpc_task *task)
static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
{
	struct nlm_rqst		*call = (struct nlm_rqst *) task->tk_calldata;
	struct nlm_rqst		*call = data;
	struct nlm_block	*block;
	unsigned long		timeout;
	struct sockaddr_in	*peer_addr = RPC_PEERADDR(task->tk_client);
@@ -614,6 +614,10 @@ nlmsvc_grant_callback(struct rpc_task *task)
	nlm_release_host(call->a_host);
}

static const struct rpc_call_ops nlmsvc_grant_ops = {
	.rpc_call_done = nlmsvc_grant_callback,
};

/*
 * We received a GRANT_RES callback. Try to find the corresponding
 * block.
+9 −5
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@
#define NLMDBG_FACILITY		NLMDBG_CLIENT

static u32	nlmsvc_callback(struct svc_rqst *, u32, struct nlm_res *);
static void	nlmsvc_callback_exit(struct rpc_task *);

static const struct rpc_call_ops nlmsvc_callback_ops;

#ifdef CONFIG_LOCKD_V4
static u32
@@ -518,7 +519,7 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
	call->a_host  = host;
	memcpy(&call->a_args, resp, sizeof(*resp));

	if (nlmsvc_async_call(call, proc, nlmsvc_callback_exit) < 0)
	if (nlmsvc_async_call(call, proc, &nlmsvc_callback_ops) < 0)
		goto error;

	return rpc_success;
@@ -528,10 +529,9 @@ nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_res *resp)
	return rpc_system_err;
}

static void
nlmsvc_callback_exit(struct rpc_task *task)
static void nlmsvc_callback_exit(struct rpc_task *task, void *data)
{
	struct nlm_rqst	*call = (struct nlm_rqst *) task->tk_calldata;
	struct nlm_rqst	*call = data;

	if (task->tk_status < 0) {
		dprintk("lockd: %4d callback failed (errno = %d)\n",
@@ -541,6 +541,10 @@ nlmsvc_callback_exit(struct rpc_task *task)
	kfree(call);
}

static const struct rpc_call_ops nlmsvc_callback_ops = {
	.rpc_call_done = nlmsvc_callback_exit,
};

/*
 * NLM Server procedures.
 */
+0 −1
Original line number Diff line number Diff line
@@ -269,7 +269,6 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq,

		data->task.tk_cookie = (unsigned long) inode;
		data->task.tk_calldata = data;
		data->task.tk_release = nfs_readdata_release;
		data->complete = nfs_direct_read_result;

		lock_kernel();
Loading