]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
lockd: Use xdrgen XDR functions for the NLMv4 GRANTED procedure
authorChuck Lever <chuck.lever@oracle.com>
Tue, 17 Feb 2026 22:06:59 +0000 (17:06 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 30 Mar 2026 01:25:09 +0000 (21:25 -0400)
The NLM GRANTED procedure provides server-to-client notification
when a previously blocked lock request has been granted,
completing the asynchronous lock request flow. This patch
completes the xdrgen migration for basic NLMv4 procedures by
converting the GRANTED procedure, the final one in this
conversion series.

This patch converts the GRANTED procedure to use xdrgen
functions nlm4_svc_decode_nlm4_testargs and
nlm4_svc_encode_nlm4_res generated from the NLM version 4
protocol specification. The procedure handler uses xdrgen types
through a wrapper structure that bridges between generated code
and the legacy nlm_lock representation still used by the core
lockd logic.

A new helper function nlm4_lock_to_nlm_lock() is introduced to
convert xdrgen nlm4_lock structures to the legacy nlm_lock
format. This helper complements the existing
nlm4svc_lookup_host() and nlm4svc_lookup_file() functions used
throughout this series.

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.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svc4proc.c

index de1a9cf416ec63ce0d9bf6214763ef715053c967..2e1a0392d68ac245909f22242d6f1e172ec230c5 100644 (file)
@@ -85,6 +85,21 @@ nlm4_netobj_to_cookie(struct nlm_cookie *cookie, netobj *object)
        return nlm_granted;
 }
 
+static __be32
+nlm4_lock_to_nlm_lock(struct nlm_lock *lock, struct nlm4_lock *alock)
+{
+       if (alock->fh.len > NFS_MAXFHSIZE)
+               return nlm_lck_denied;
+       lock->fh.size = alock->fh.len;
+       memcpy(lock->fh.data, alock->fh.data, alock->fh.len);
+       lock->oh.len = alock->oh.len;
+       lock->oh.data = alock->oh.data;
+       lock->svid = alock->svid;
+       locks_init_lock(&lock->fl);
+       lockd_set_file_lock_range4(&lock->fl, alock->l_offset, alock->l_len);
+       return nlm_granted;
+}
+
 static struct nlm_host *
 nlm4svc_lookup_host(struct svc_rqst *rqstp, string caller, bool monitored)
 {
@@ -687,10 +702,41 @@ __nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp)
        return rpc_success;
 }
 
+/**
+ * nlm4svc_proc_granted - GRANTED: Server grants a previously blocked lock
+ * @rqstp: RPC transaction context
+ *
+ * Returns:
+ *   %rpc_success:             RPC executed successfully.
+ *
+ * RPC synopsis:
+ *   nlm4_res NLMPROC4_GRANTED(nlm4_testargs) = 5;
+ *
+ * Permissible procedure status codes:
+ *   %NLM4_GRANTED:            The requested lock was granted.
+ *   %NLM4_DENIED:             The server could not allocate the resources
+ *                             needed to process the request.
+ *   %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.
+ */
 static __be32
 nlm4svc_proc_granted(struct svc_rqst *rqstp)
 {
-       return __nlm4svc_proc_granted(rqstp, rqstp->rq_resp);
+       struct nlm4_testargs_wrapper *argp = rqstp->rq_argp;
+       struct nlm4_res_wrapper *resp = rqstp->rq_resp;
+
+       resp->xdrgen.cookie = argp->xdrgen.cookie;
+
+       resp->xdrgen.stat.stat = nlm4_lock_to_nlm_lock(&argp->lock,
+                                                      &argp->xdrgen.alock);
+       if (resp->xdrgen.stat.stat)
+               goto out;
+
+       resp->xdrgen.stat.stat = nlmclnt_grant(svc_addr(rqstp), &argp->lock);
+
+out:
+       return rpc_success;
 }
 
 /*
@@ -987,15 +1033,15 @@ static const struct svc_procedure nlm4svc_procedures[24] = {
                .pc_xdrressize  = NLM4_nlm4_res_sz,
                .pc_name        = "UNLOCK",
        },
-       [NLMPROC_GRANTED] = {
-               .pc_func = nlm4svc_proc_granted,
-               .pc_decode = nlm4svc_decode_testargs,
-               .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_name = "GRANTED",
+       [NLMPROC4_GRANTED] = {
+               .pc_func        = nlm4svc_proc_granted,
+               .pc_decode      = nlm4_svc_decode_nlm4_testargs,
+               .pc_encode      = nlm4_svc_encode_nlm4_res,
+               .pc_argsize     = sizeof(struct nlm4_testargs_wrapper),
+               .pc_argzero     = 0,
+               .pc_ressize     = sizeof(struct nlm4_res_wrapper),
+               .pc_xdrressize  = NLM4_nlm4_res_sz,
+               .pc_name        = "GRANTED",
        },
        [NLMPROC_TEST_MSG] = {
                .pc_func = nlm4svc_proc_test_msg,