Commit dea5b7ac authored by Chuck Lever's avatar Chuck Lever
Browse files

lockd: Use xdrgen XDR functions for the NLMv4 CANCEL_MSG procedure



The CANCEL_MSG procedure is part of NLM's asynchronous lock
request flow, where clients send CANCEL_MSG to cancel pending
lock requests. This patch continues the xdrgen migration by
converting CANCEL_MSG to use generated XDR functions.

This patch converts the CANCEL_MSG procedure to use xdrgen
functions nlm4_svc_decode_nlm4_cancargs and
nlm4_svc_encode_void generated from the NLM version 4 protocol
specification. The procedure handler uses xdrgen types through
the nlm4_cancargs_wrapper structure that bridges between
generated code and the legacy nlm_lock representation.

The pc_argzero field is set to zero because xdrgen decoders
reliably initialize all arguments in the argp->xdrgen field,
making the early defensive memset unnecessary. Remaining argp
fields are cleared as needed.

The NLM async callback mechanism uses client-side functions
which continue to take legacy results like struct nlm_res,
preventing CANCEL and CANCEL_MSG from sharing code for now.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent b2be4e28
Loading
Loading
Loading
Loading
+65 −48
Original line number Diff line number Diff line
@@ -459,38 +459,6 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp)
	return nlm4svc_do_lock(rqstp, true);
}

static __be32
__nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
{
	struct nlm_args *argp = rqstp->rq_argp;
	struct nlm_host	*host;
	struct nlm_file	*file;

	dprintk("lockd: CANCEL        called\n");

	resp->cookie = argp->cookie;

	/* Don't accept requests during grace period */
	if (locks_in_grace(SVC_NET(rqstp))) {
		resp->status = nlm_lck_denied_grace_period;
		return rpc_success;
	}

	/* Obtain client and file */
	if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file)))
		return resp->status == nlm__int__drop_reply ?
			rpc_drop_reply : rpc_success;

	/* Try to cancel request. */
	resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock);

	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
	nlmsvc_release_lockowner(&argp->lock);
	nlmsvc_release_host(host);
	nlm_release_file(file);
	return rpc_success;
}

/**
 * nlm4svc_proc_cancel - CANCEL: Cancel an outstanding blocked lock request
 * @rqstp: RPC transaction context
@@ -872,19 +840,68 @@ static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp)
				__nlm4svc_proc_lock_msg);
}

static __be32
__nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_res *resp)
{
	struct nlm4_cancargs_wrapper *argp = rqstp->rq_argp;
	unsigned char type = argp->xdrgen.exclusive ? F_WRLCK : F_RDLCK;
	struct net *net = SVC_NET(rqstp);
	struct nlm_file	*file = NULL;
	struct nlm_host	*host = NULL;

	resp->status = nlm_lck_denied_nolocks;
	if (nlm4_netobj_to_cookie(&resp->cookie, &argp->xdrgen.cookie))
		goto out;

	resp->status = nlm_lck_denied_grace_period;
	if (locks_in_grace(net))
		goto out;

	resp->status = nlm_lck_denied_nolocks;
	host = nlm4svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, false);
	if (!host)
		goto out;

	resp->status = nlm4svc_lookup_file(rqstp, host, &argp->lock,
					   &file, &argp->xdrgen.alock, type);
	if (resp->status)
		goto out;

	resp->status = nlmsvc_cancel_blocked(net, file, &argp->lock);
	nlmsvc_release_lockowner(&argp->lock);

out:
	if (file)
		nlm_release_file(file);
	nlmsvc_release_host(host);
	return resp->status == nlm__int__drop_reply ?
		rpc_drop_reply : rpc_success;
}

/**
 * nlm4svc_proc_cancel_msg - CANCEL_MSG: Cancel an outstanding lock request
 * @rqstp: RPC transaction context
 *
 * Returns:
 *   %rpc_success:		RPC executed successfully.
 *   %rpc_system_err:		RPC execution failed.
 *
 * RPC synopsis:
 *   void NLMPROC4_CANCEL_MSG(nlm4_cancargs) = 8;
 *
 * The response to this request is delivered via the CANCEL_RES procedure.
 */
static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp)
{
	struct nlm_args *argp = rqstp->rq_argp;
	struct nlm4_cancargs_wrapper *argp = rqstp->rq_argp;
	struct nlm_host *host;

	dprintk("lockd: CANCEL_MSG    called\n");

	host = nlmsvc_lookup_host(rqstp, argp->lock.caller, argp->lock.len);
	host = nlm4svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, false);
	if (!host)
		return rpc_system_err;

	return nlm4svc_callback(rqstp, host, NLMPROC_CANCEL_RES,
				__nlm4svc_proc_cancel);
	return nlm4svc_callback(rqstp, host, NLMPROC4_CANCEL_RES,
				__nlm4svc_proc_cancel_msg);
}

static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp)
@@ -1158,14 +1175,14 @@ static const struct svc_procedure nlm4svc_procedures[24] = {
		.pc_xdrressize	= XDR_void,
		.pc_name	= "LOCK_MSG",
	},
	[NLMPROC_CANCEL_MSG] = {
	[NLMPROC4_CANCEL_MSG] = {
		.pc_func	= nlm4svc_proc_cancel_msg,
		.pc_decode = nlm4svc_decode_cancargs,
		.pc_encode = nlm4svc_encode_void,
		.pc_argsize = sizeof(struct nlm_args),
		.pc_argzero = sizeof(struct nlm_args),
		.pc_ressize = sizeof(struct nlm_void),
		.pc_xdrressize = St,
		.pc_decode	= nlm4_svc_decode_nlm4_cancargs,
		.pc_encode	= nlm4_svc_encode_void,
		.pc_argsize	= sizeof(struct nlm4_cancargs_wrapper),
		.pc_argzero	= 0,
		.pc_ressize	= 0,
		.pc_xdrressize	= XDR_void,
		.pc_name	= "CANCEL_MSG",
	},
	[NLMPROC_UNLOCK_MSG] = {