]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lockd: Use xdrgen XDR functions for the NLMv4 NM_LOCK procedure
authorChuck Lever <chuck.lever@oracle.com>
Tue, 17 Feb 2026 22:07:17 +0000 (17:07 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 30 Mar 2026 01:25:09 +0000 (21:25 -0400)
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: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/lockd/svc4proc.c

index 5d85f888fdf402e2920b8401f8f629000b04fc54..62c90827dfae97b71b2e28f571710af2d9bd4e86 100644 (file)
@@ -358,44 +358,6 @@ out:
                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 @@ out:
                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,15 +1442,15 @@ static const struct svc_procedure nlm4svc_procedures[24] = {
                .pc_xdrressize  = NLM4_nlm4_shareres_sz,
                .pc_name        = "UNSHARE",
        },
-       [NLMPROC_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_name = "NM_LOCK",
+       [NLMPROC4_NM_LOCK] = {
+               .pc_func        = nlm4svc_proc_nm_lock,
+               .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] = {
                .pc_func = nlm4svc_proc_free_all,