From: Chuck Lever Date: Tue, 12 May 2026 18:13:51 +0000 (-0400) Subject: lockd: Use xdrgen XDR functions for the NLMv3 CANCEL procedure X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=954a3f3f6cff4144f9bfafb676089250f57b9b00;p=thirdparty%2Flinux.git lockd: Use xdrgen XDR functions for the NLMv3 CANCEL procedure The NLM CANCEL procedure allows clients to cancel outstanding blocked lock requests. This patch continues the xdrgen migration by converting the CANCEL procedure. CANCEL reuses the nlm3svc_lookup_host() and nlm3svc_lookup_file() helpers established in the TEST procedure conversion. This patch converts the CANCEL procedure to use xdrgen functions nlm_svc_decode_nlm_cancargs and nlm_svc_encode_nlm_res generated from the NLM version 3 protocol specification. The procedure handler uses xdrgen types through a wrapper structure that bridges between generated code and the legacy lockd_lock representation still used by the core lockd logic. Setting pc_argzero to zero is safe because the generated decoder fills the argp->xdrgen subfields before the procedure runs, so the zeroing memset performed by the dispatch layer is not needed. The lock member of the wrapper is populated explicitly in nlm3svc_lookup_file() rather than relying on zero-initialization. Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 66bc9a2efddb8..a5e40ca3f1094 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -65,6 +65,13 @@ struct nlm_res_wrapper { static_assert(offsetof(struct nlm_res_wrapper, xdrgen) == 0); +struct nlm_cancargs_wrapper { + struct nlm_cancargs xdrgen; + struct lockd_lock lock; +}; + +static_assert(offsetof(struct nlm_cancargs_wrapper, xdrgen) == 0); + static __be32 nlm_netobj_to_cookie(struct lockd_cookie *cookie, netobj *object) { @@ -517,10 +524,63 @@ __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct lockd_res *resp) return rpc_success; } +/** + * nlmsvc_proc_cancel - CANCEL: Cancel an outstanding blocked lock request + * @rqstp: RPC transaction context + * + * Returns: + * %rpc_success: RPC executed successfully. + * %rpc_drop_reply: Do not send an RPC reply. + * + * RPC synopsis: + * nlm_res NLM_CANCEL(nlm_cancargs) = 3; + * + * Permissible procedure status codes: + * %LCK_GRANTED: The requested lock was canceled. + * %LCK_DENIED: There was no lock to cancel. + * %LCK_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: + * %LCK_DENIED_NOLOCKS: A needed resource could not be allocated. + */ static __be32 nlmsvc_proc_cancel(struct svc_rqst *rqstp) { - return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp); + struct nlm_cancargs_wrapper *argp = rqstp->rq_argp; + unsigned char type = argp->xdrgen.exclusive ? F_WRLCK : F_RDLCK; + struct nlm_res_wrapper *resp = rqstp->rq_resp; + struct net *net = SVC_NET(rqstp); + struct nlm_host *host = NULL; + struct nlm_file *file = NULL; + + resp->xdrgen.cookie = argp->xdrgen.cookie; + + resp->xdrgen.stat.stat = nlm_lck_denied_grace_period; + if (locks_in_grace(net)) + goto out; + + resp->xdrgen.stat.stat = nlm_lck_denied_nolocks; + host = nlm3svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, false); + if (!host) + goto out; + + resp->xdrgen.stat.stat = nlm3svc_lookup_file(rqstp, host, &argp->lock, + &file, &argp->xdrgen.alock, + type); + if (resp->xdrgen.stat.stat) + goto out; + + resp->xdrgen.stat.stat = 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->xdrgen.stat.stat == nlm__int__drop_reply ? + rpc_drop_reply : rpc_success; } /* @@ -874,15 +934,15 @@ static const struct svc_procedure nlmsvc_procedures[24] = { .pc_xdrressize = NLM3_nlm_res_sz, .pc_name = "LOCK", }, - [NLMPROC_CANCEL] = { - .pc_func = nlmsvc_proc_cancel, - .pc_decode = nlmsvc_decode_cancargs, - .pc_encode = nlmsvc_encode_res, - .pc_argsize = sizeof(struct lockd_args), - .pc_argzero = sizeof(struct lockd_args), - .pc_ressize = sizeof(struct lockd_res), - .pc_xdrressize = Ck+St, - .pc_name = "CANCEL", + [NLM_CANCEL] = { + .pc_func = nlmsvc_proc_cancel, + .pc_decode = nlm_svc_decode_nlm_cancargs, + .pc_encode = nlm_svc_encode_nlm_res, + .pc_argsize = sizeof(struct nlm_cancargs_wrapper), + .pc_argzero = 0, + .pc_ressize = sizeof(struct nlm_res_wrapper), + .pc_xdrressize = NLM3_nlm_res_sz, + .pc_name = "CANCEL", }, [NLMPROC_UNLOCK] = { .pc_func = nlmsvc_proc_unlock, @@ -1092,6 +1152,7 @@ static const struct svc_procedure nlmsvc_procedures[24] = { union nlmsvc_xdrstore { struct nlm_testargs_wrapper testargs; struct nlm_lockargs_wrapper lockargs; + struct nlm_cancargs_wrapper cancargs; struct nlm_testres_wrapper testres; struct nlm_res_wrapper res; struct lockd_args args;