From e04d248b8a1e90df2bbb9c8a06fa34024ee9bdf0 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 12 May 2026 14:13:53 -0400 Subject: [PATCH] lockd: Use xdrgen XDR functions for the NLMv3 GRANTED procedure The NLM GRANTED procedure allows servers to notify clients when a previously blocked lock request has been granted, completing the asynchronous lock request flow. This patch converts the NLMv3 GRANTED procedure to use xdrgen-generated XDR functions. The conversion replaces the legacy decoder with the xdrgen functions nlm_svc_decode_nlm_testargs and nlm_svc_encode_nlm_res generated from the NLM version 3 protocol specification. The procedure handler accesses xdrgen types through a wrapper structure that bridges between generated code and the legacy lockd_lock representation still used by the core lockd logic. A new helper function nlm_lock_to_lockd_lock() converts an xdrgen nlm_lock into the legacy lockd_lock format. The helper complements the existing nlm3svc_lookup_host() and nlm3svc_lookup_file() functions used throughout this series. 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 helper populates each field of the wrapper's lock member that any downstream consumer reads: fh, oh, svid, and the file_lock byte range. Because pc_argzero no longer scrubs the rq_argp slot, the shared nlmclnt_lock_event tracepoint class is updated to source its byte-range fields from lock->fl.fl_start and lock->fl.fl_end, which both the client and server populate unconditionally; the old lock_start and lock_len fields are no longer required by the trace. Reviewed-by: Jeff Layton Signed-off-by: Chuck Lever --- fs/lockd/svcproc.c | 65 +++++++++++++++++++++++++++++++++++++++------- fs/lockd/trace.h | 12 ++++----- 2 files changed, 61 insertions(+), 16 deletions(-) diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index ccc6a633df7ba..264212e44ec5a 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -89,6 +89,20 @@ nlm_netobj_to_cookie(struct lockd_cookie *cookie, netobj *object) return nlm_granted; } +static __be32 +nlm_lock_to_lockd_lock(struct lockd_lock *lock, struct nlm_lock *alock) +{ + if (alock->fh.len != NLM3_FHSIZE) + 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->uppid; + lockd_set_file_lock_range3(&lock->fl, alock->l_offset, alock->l_len); + return nlm_granted; +} + static struct nlm_host * nlm3svc_lookup_host(struct svc_rqst *rqstp, string caller, bool monitored) { @@ -700,10 +714,41 @@ __nlmsvc_proc_granted(struct svc_rqst *rqstp, struct lockd_res *resp) return rpc_success; } +/** + * nlmsvc_proc_granted - GRANTED: Blocked lock has been granted + * @rqstp: RPC transaction context + * + * Returns: + * %rpc_success: RPC executed successfully. + * + * RPC synopsis: + * nlm_res NLM_GRANTED(nlm_testargs) = 5; + * + * Permissible procedure status codes: + * %LCK_GRANTED: The granted lock was accepted. + * %LCK_DENIED: The procedure failed, possibly due to + * internal resource constraints. + * %LCK_DENIED_GRACE_PERIOD: The client host recently restarted and + * its NLM is re-establishing existing locks, + * so it is not yet ready to accept callbacks. + */ static __be32 nlmsvc_proc_granted(struct svc_rqst *rqstp) { - return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp); + struct nlm_testargs_wrapper *argp = rqstp->rq_argp; + struct nlm_res_wrapper *resp = rqstp->rq_resp; + + resp->xdrgen.cookie = argp->xdrgen.cookie; + + resp->xdrgen.stat.stat = nlm_lock_to_lockd_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; } /* @@ -1012,15 +1057,15 @@ static const struct svc_procedure nlmsvc_procedures[24] = { .pc_xdrressize = NLM3_nlm_res_sz, .pc_name = "UNLOCK", }, - [NLMPROC_GRANTED] = { - .pc_func = nlmsvc_proc_granted, - .pc_decode = nlmsvc_decode_testargs, - .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 = "GRANTED", + [NLM_GRANTED] = { + .pc_func = nlmsvc_proc_granted, + .pc_decode = nlm_svc_decode_nlm_testargs, + .pc_encode = nlm_svc_encode_nlm_res, + .pc_argsize = sizeof(struct nlm_testargs_wrapper), + .pc_argzero = 0, + .pc_ressize = sizeof(struct nlm_res_wrapper), + .pc_xdrressize = NLM3_nlm_res_sz, + .pc_name = "GRANTED", }, [NLMPROC_TEST_MSG] = { .pc_func = nlmsvc_proc_test_msg, diff --git a/fs/lockd/trace.h b/fs/lockd/trace.h index aa858d9d406dd..a11d04e8c835e 100644 --- a/fs/lockd/trace.h +++ b/fs/lockd/trace.h @@ -61,8 +61,8 @@ DECLARE_EVENT_CLASS(nlmclnt_lock_event, __field(u32, svid) __field(u32, fh) __field(unsigned long, status) - __field(u64, start) - __field(u64, len) + __field(loff_t, start) + __field(loff_t, end) __sockaddr(addr, addrlen) ), @@ -70,16 +70,16 @@ DECLARE_EVENT_CLASS(nlmclnt_lock_event, __entry->oh = ~crc32_le(0xffffffff, lock->oh.data, lock->oh.len); __entry->svid = lock->svid; __entry->fh = nfs_fhandle_hash(&lock->fh); - __entry->start = lock->lock_start; - __entry->len = lock->lock_len; + __entry->start = lock->fl.fl_start; + __entry->end = lock->fl.fl_end; __entry->status = be32_to_cpu(status); __assign_sockaddr(addr, addr, addrlen); ), TP_printk( - "addr=%pISpc oh=0x%08x svid=0x%08x fh=0x%08x start=%llu len=%llu status=%s", + "addr=%pISpc oh=0x%08x svid=0x%08x fh=0x%08x start=%lld end=%lld status=%s", __get_sockaddr(addr), __entry->oh, __entry->svid, - __entry->fh, __entry->start, __entry->len, + __entry->fh, __entry->start, __entry->end, show_nlm_status(__entry->status) ) ); -- 2.47.3