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

lockd: Use xdrgen XDR functions for the NLMv4 NM_LOCK procedure



Now that nlm4svc_do_lock() has been introduced to handle both
monitored and non-monitored lock requests, the NLMv4 NM_LOCK
procedure can be converted to use xdrgen-generated XDR
functions. This conversion allows the removal of
__nlm4svc_proc_lock(), a helper function that was previously
shared between the LOCK and NM_LOCK procedures.

Replace the NLMPROC4_NM_LOCK entry in the nlm_procedures4
array with an entry that uses xdrgen-built XDR decoders and
encoders. The procedure handler is updated to call
nlm4svc_do_lock() directly and access arguments through the
argp->xdrgen hierarchy.

The .pc_argzero field is set to zero because xdrgen decoders
fully initialize all fields in argp->xdrgen, making the early
defensive memset unnecessary. The remaining argp fields that
fall outside the xdrgen structures are cleared explicitly as
needed.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 985d022d
Loading
Loading
Loading
Loading
+44 −57
Original line number Diff line number Diff line
@@ -358,44 +358,6 @@ static __be32 nlm4svc_proc_test(struct svc_rqst *rqstp)
		rpc_drop_reply : rpc_success;
}

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

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

	resp->cookie = argp->cookie;

	/* 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;

	/* Now try to lock the file */
	resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock,
					argp->block, &argp->cookie,
					argp->reclaim);
	switch (resp->status) {
	case nlm__int__drop_reply:
		rc = rpc_drop_reply;
		break;
	case nlm__int__deadlock:
		resp->status = nlm4_deadlock;
		fallthrough;
	default:
		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
	}

	nlmsvc_release_lockowner(&argp->lock);
	nlmsvc_release_host(host);
	nlm_release_file(file);
	return rc;
}

static __be32
nlm4svc_do_lock(struct svc_rqst *rqstp, bool monitored)
{
@@ -1190,18 +1152,43 @@ static __be32 nlm4svc_proc_unshare(struct svc_rqst *rqstp)
		rpc_drop_reply : rpc_success;
}

/*
 * NM_LOCK: Create an unmonitored lock
/**
 * nlm4svc_proc_nm_lock - NM_LOCK: Establish a non-monitored lock
 * @rqstp: RPC transaction context
 *
 * Returns:
 *   %rpc_success:		RPC executed successfully.
 *   %rpc_drop_reply:		Do not send an RPC reply.
 *
 * RPC synopsis:
 *   nlm4_res NLMPROC4_NM_LOCK(nlm4_lockargs) = 22;
 *
 * Permissible procedure status codes:
 *   %NLM4_GRANTED:		The requested lock was granted.
 *   %NLM4_DENIED:		The requested lock conflicted with existing
 *				lock reservations for the file.
 *   %NLM4_DENIED_NOLOCKS:	The server could not allocate the resources
 *				needed to process the request.
 *   %NLM4_BLOCKED:		The blocking request cannot be granted
 *				immediately. The server will send an
 *				NLMPROC4_GRANTED callback to the client when
 *				the lock can be granted.
 *   %NLM4_DENIED_GRACE_PERIOD:	The server has recently restarted and is
 *				re-establishing existing locks, and is not
 *				yet ready to accept normal service requests.
 *
 * The Linux NLM server implementation also returns:
 *   %NLM4_DEADLCK:		The request could not be granted and
 *				blocking would cause a deadlock.
 *   %NLM4_STALE_FH:		The request specified an invalid file handle.
 *   %NLM4_FBIG:		The request specified a length or offset
 *				that exceeds the range supported by the
 *				server.
 *   %NLM4_FAILED:		The request failed for an unspecified reason.
 */
static __be32
nlm4svc_proc_nm_lock(struct svc_rqst *rqstp)
static __be32 nlm4svc_proc_nm_lock(struct svc_rqst *rqstp)
{
	struct nlm_args *argp = rqstp->rq_argp;

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

	argp->monitor = 0;		/* just clean the monitor flag */
	return __nlm4svc_proc_lock(rqstp, rqstp->rq_resp);
	return nlm4svc_do_lock(rqstp, false);
}

/*
@@ -1455,14 +1442,14 @@ static const struct svc_procedure nlm4svc_procedures[24] = {
		.pc_xdrressize	= NLM4_nlm4_shareres_sz,
		.pc_name	= "UNSHARE",
	},
	[NLMPROC_NM_LOCK] = {
	[NLMPROC4_NM_LOCK] = {
		.pc_func	= nlm4svc_proc_nm_lock,
		.pc_decode = nlm4svc_decode_lockargs,
		.pc_encode = nlm4svc_encode_res,
		.pc_argsize = sizeof(struct nlm_args),
		.pc_argzero = sizeof(struct nlm_args),
		.pc_ressize = sizeof(struct nlm_res),
		.pc_xdrressize = Ck+St,
		.pc_decode	= nlm4_svc_decode_nlm4_lockargs,
		.pc_encode	= nlm4_svc_encode_nlm4_res,
		.pc_argsize	= sizeof(struct nlm4_lockargs_wrapper),
		.pc_argzero	= 0,
		.pc_ressize	= sizeof(struct nlm4_res_wrapper),
		.pc_xdrressize	= NLM4_nlm4_res_sz,
		.pc_name	= "NM_LOCK",
	},
	[NLMPROC_FREE_ALL] = {