Commit Graph

107 Commits

Author SHA1 Message Date
Olga Kornievskaia
5c4851e4cd lockd: fix NLMv3 GRANTED_MSG handling
GRANTED_MSG is a server-to-client callback, so it runs on the client,
where nfsd never registers nlmsvc_ops. The nlm3svc_lookup_host()
helper is for the server-side request handlers
(TEST/LOCK/CANCEL/UNLOCK), which reach nlmsvc_ops->fopen and must
reject requests when nfsd isn't running. GRANTED_MSG only calls
nlmclnt_grant(). Instead, of calling nlm3svc_lookup_host(), which
results in a client failing a GRANTED_MSG call, call
nlmsvc_lookup_host().

Fixes: 6c534ad999 ("lockd: Use xdrgen XDR functions for the NLMv3 GRANTED_MSG procedure")
Cc: stable@vger.kernel.org
Signed-off-by: Olga Kornievskaia <okorniev@redhat.com>
Reviewed-by: NeilBrown <neil@brown.name>
Link: https://patch.msgid.link/20260625211852.31972-1-okorniev@redhat.com
Signed-off-by: Chuck Lever <cel@kernel.org>
2026-07-17 09:31:50 -04:00
Chuck Lever
1b8d52328e lockd: Unify cast_status
cast_status folds internal lock-daemon sentinels into NLMv1/v3
wire status codes for the v3 reply path.  Two variants have
existed since the original kernel import: a strict allowlist
under CONFIG_LOCKD_V4 and a sentinel-translation form for the
!CONFIG_LOCKD_V4 build.  The split was never grounded in a
behavioural difference -- nlmsvc_testlock and nlmsvc_lock,
which feed cast_status, return the same set of values in both
configurations -- and recent xdrgen conversions have narrowed
the caller set further: nlm__int__stale_fh and nlm__int__failed
are now translated at their point of origin in nlm3svc_lookup_file,
and the cast_status wraps around nlmsvc_cancel_blocked and
nlmsvc_unlock have been dropped because those functions return
only wire codes.

Collapse the two variants into one.  The unified form keeps the
CONFIG_LOCKD_V4 arm's allowlist, retains the nlm__int__deadlock
translation, and folds anything else to nlm_lck_denied_nolocks
after a pr_warn_once so an unexpected sentinel from a future
refactor remains visible in the kernel log instead of being
silently passed to the wire encoder.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
5c0d3a859b lockd: Remove C macros that are no longer used
The conversion of all NLMv3 procedures to xdrgen-generated
XDR functions is complete. The hand-rolled XDR size
calculation macros (Ck, No, St, Rg) and the nlm_void
structure definition served only the older implementations
and are now unused.

Also removes NLMDBG_FACILITY, which was set to the client
debug flag in server-side code but never referenced, and
corrects a comment to specify "NLMv3 Server procedures".

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
a5239c8d5d lockd: Use xdrgen XDR functions for the NLMv3 FREE_ALL procedure
With all other NLMv3 procedures now converted to xdrgen-generated
XDR functions, the FREE_ALL procedure can be converted as well.
This conversion allows the removal of nlmsvc_retrieve_args(),
a 52-line helper function that was used only by FREE_ALL to
retrieve client information from lockd's internal data
structures.

Replace the NLMPROC_FREE_ALL entry in the nlmsvc_procedures
array with an entry that uses xdrgen-built XDR decoders and
encoders. The procedure handler is updated to use the new
wrapper structure (nlm_notify_wrapper) and call
nlm3svc_lookup_host() directly, eliminating the need for the
now-removed helper function.

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
nlm_notify_wrapper structure has no members beyond the xdrgen
substructure, so no further initialization is required.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
92f689d5fa lockd: Use xdrgen XDR functions for the NLMv3 NM_LOCK procedure
Now that nlmsvc_do_lock() has been introduced to handle both
monitored and non-monitored lock requests, the NLMv3 NM_LOCK
procedure can be converted to use xdrgen-generated XDR
functions. This conversion allows the removal of
__nlmsvc_proc_lock(), a helper function that was previously
shared between the LOCK and NM_LOCK procedures.

Replace the NLMPROC_NM_LOCK entry in the nlmsvc_procedures
array with an entry that uses xdrgen-built XDR decoders and
encoders. The procedure handler is reduced to a thin wrapper
around nlmsvc_do_lock() with the monitored flag set to false.

The pc_argzero=0 choice was justified for the LOCK conversion
and applies unchanged here, since both procedures share the
same nlm_lockargs_wrapper layout and decoder.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
ac3d7a8ca4 lockd: Use xdrgen XDR functions for the NLMv3 UNSHARE procedure
Convert the NLMv3 UNSHARE procedure to use xdrgen-generated XDR
functions nlm_svc_decode_nlm_shareargs and
nlm_svc_encode_nlm_shareres.

The procedure handler is updated to use the wrapper structures
(nlm_shareargs_wrapper and nlm_shareres_wrapper) introduced by
the SHARE conversion patch and accesses arguments through the
argp->xdrgen hierarchy.

The .pc_argzero field is set to zero because the generated
decoder fills argp->xdrgen before the procedure runs, so the
zeroing memset performed by the dispatch layer is no longer
needed.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
1a2bba073f lockd: Use xdrgen XDR functions for the NLMv3 SHARE procedure
Convert the NLMv3 SHARE procedure to use xdrgen-generated XDR
functions nlm_svc_decode_nlm_shareargs and
nlm_svc_encode_nlm_shareres.

This patch introduces struct nlm_shareargs_wrapper and struct
nlm_shareres_wrapper to bridge between the xdrgen-generated
structures and the internal lockd types. The procedure handler
is updated to access arguments through the argp->xdrgen
hierarchy and uses nlm3svc_lookup_host and nlm3svc_lookup_file
for host and file resolution.

The .pc_argzero field is set to zero because the generated
decoder fills argp->xdrgen before the procedure runs, so the
zeroing memset performed by the dispatch layer is no longer
needed.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
2403834551 lockd: Convert NLMv3 server-side undefined procedures to xdrgen
Complete the xdrgen migration of NLMv3 server-side
procedures by converting the three unused procedure slots
(17, 18, and 19). These slots already returned
rpc_proc_unavail; they are converted here only to retire
the last users of the hand-coded nlmsvc_decode_void and
nlmsvc_encode_void helpers.

The three undefined procedure entries now use the xdrgen
functions nlm_svc_decode_void and nlm_svc_encode_void. The
nlmsvc_proc_unused function is also moved earlier in the
file to follow the convention of placing procedure
implementations before the procedure table.

The pc_argsize, pc_ressize, and pc_argzero fields are now
set to zero since no arguments or results are processed.
Setting pc_xdrressize to XDR_void reflects that these
procedures return no reply payload; the previous value of
St over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
371275eeb0 lockd: Use xdrgen XDR functions for the NLMv3 SM_NOTIFY procedure
Continue the xdrgen migration by converting NLMv3 SM_NOTIFY,
a private callback from statd to notify lockd when a remote
host has rebooted.  The procedure now uses
nlm_svc_decode_nlm_notifyargs and nlm_svc_encode_void,
generated from the NLM version 3 protocol specification.

A new struct nlm_notifyargs_wrapper bridges between the
xdrgen-generated nlm_notifyargs and the lockd_reboot
structure expected by nlm_host_rebooted().  The wrapper
contains both the xdrgen-decoded arguments and a reboot
field for the existing API.

Setting pc_argzero to zero is safe because the generated
decoder fills argp->xdrgen before the procedure runs, so
the zeroing memset performed by the dispatch layer is no
longer needed.

Setting pc_xdrressize to XDR_void reflects that SM_NOTIFY
returns no data; the previous value of St over-reserved a
status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
e0018ec659 lockd: Use xdrgen XDR functions for the NLMv3 GRANTED_RES procedure
Continue the xdrgen migration by converting NLMv3 GRANTED_RES,
the callback that a remote NLM uses to return async GRANTED
results to this lockd.  The procedure now uses
nlm_svc_decode_nlm_res and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification.

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 no longer needed.

Setting pc_xdrressize to XDR_void reflects that GRANTED_RES, as
a callback, returns no data; the previous value of St
over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
0e20aa9491 lockd: Use xdrgen XDR functions for the NLMv3 UNLOCK_RES procedure
Continue the xdrgen migration by converting NLMv3 UNLOCK_RES,
the callback that a remote NLM uses to return async UNLOCK
results to this lockd.  The procedure now uses
nlm_svc_decode_nlm_res and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification.

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 no longer needed.

Setting pc_xdrressize to XDR_void reflects that UNLOCK_RES, as
a callback, returns no data; the previous value of St
over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
82452a0254 lockd: Use xdrgen XDR functions for the NLMv3 CANCEL_RES procedure
Continue the xdrgen migration by converting NLMv3 CANCEL_RES,
the callback that a remote NLM uses to return async CANCEL
results to this lockd.  The procedure now uses
nlm_svc_decode_nlm_res and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification.

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 no longer needed.

Setting pc_xdrressize to XDR_void reflects that CANCEL_RES, as
a callback, returns no data; the previous value of St
over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
9783a82b75 lockd: Use xdrgen XDR functions for the NLMv3 LOCK_RES procedure
Continue the xdrgen migration by converting NLMv3 LOCK_RES,
the callback that a remote NLM uses to return async LOCK
results to this lockd.  The procedure now uses
nlm_svc_decode_nlm_res and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification.

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 no longer needed.

Setting pc_xdrressize to XDR_void reflects that LOCK_RES, as
a callback, returns no data; the previous value of St
over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
386bed664e lockd: Use xdrgen XDR functions for the NLMv3 TEST_RES procedure
Continue the xdrgen migration by converting NLMv3 TEST_RES,
the callback that a remote NLM uses to return async TEST
results to this lockd. The procedure now uses
nlm_svc_decode_nlm_testres and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification.

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 no longer needed.

Setting pc_xdrressize to XDR_void reflects that TEST_RES, as
a callback, returns no data; the previous value of St
over-reserved a status word in the reply buffer.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
6c534ad999 lockd: Use xdrgen XDR functions for the NLMv3 GRANTED_MSG procedure
Continue the xdrgen migration by converting NLMv3 GRANTED_MSG,
the async counterpart to GRANTED that a remote NLM uses to tell
this lockd that a previously blocked client lock request has
become available. The procedure now uses
nlm_svc_decode_nlm_testargs and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification. The procedure
handler reaches the xdrgen types through the
nlm_testargs_wrapper structure, which bridges between generated
code and the legacy lockd_lock representation.

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 __nlmsvc_proc_granted_msg() by nlm_lock_to_lockd_lock()
rather than relying on zero-initialization.

The NLM async callback mechanism uses client-side functions
which continue to take legacy results like struct lockd_res,
preventing GRANTED and GRANTED_MSG from sharing code for now.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
6a2f89e49b lockd: Use xdrgen XDR functions for the NLMv3 UNLOCK_MSG procedure
Continue the xdrgen migration by converting NLMv3 UNLOCK_MSG, the
async counterpart to UNLOCK that clients use to release locks
without waiting for a reply. The procedure now uses
nlm_svc_decode_nlm_unlockargs and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification. The procedure
handler reaches the xdrgen types through the
nlm_unlockargs_wrapper structure, which bridges between generated
code and the legacy lockd_lock representation.

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.

The NLM async callback mechanism uses client-side functions which
continue to take legacy results like struct lockd_res, preventing
UNLOCK and UNLOCK_MSG from sharing code for now.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
02a47b6c5c lockd: Use xdrgen XDR functions for the NLMv3 CANCEL_MSG procedure
The CANCEL_MSG procedure is part of NLM's asynchronous lock
request flow, where clients send CANCEL_MSG to cancel pending
lock requests. This patch continues the xdrgen migration by
converting CANCEL_MSG to use generated XDR functions.

This patch converts the CANCEL_MSG procedure to use xdrgen
functions nlm_svc_decode_nlm_cancargs and nlm_svc_encode_void
generated from the NLM version 3 protocol specification. The
procedure handler uses xdrgen types through the
nlm_cancargs_wrapper structure that bridges between generated
code and the legacy lockd_lock representation.

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.

The previous hand-written decoder in svcxdr_decode_cookie()
rewrote a zero-length NLM cookie into a four-byte zero cookie,
with a comment attributing the substitution to HP-UX clients.
The xdrgen-generated netobj decoder performs no such rewrite, so
a zero-length request cookie now round-trips unchanged into the
CANCEL_RES reply. HP-UX has reached end of support, and CANCEL_MSG
is fire-and-forget with no client-side reply matching on the NLM
cookie, so the workaround is dropped intentionally here.

The NLM async callback mechanism uses client-side functions
which continue to take legacy results like struct lockd_res,
preventing CANCEL and CANCEL_MSG from sharing code for now.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
438c9af3b1 lockd: Use xdrgen XDR functions for the NLMv3 LOCK_MSG procedure
Continue the xdrgen migration by converting NLMv3 LOCK_MSG, the
async counterpart to LOCK that clients use to request locks that
may block. The procedure now uses nlm_svc_decode_nlm_lockargs and
nlm_svc_encode_void, generated from the NLM version 3 protocol
specification. The procedure handler reaches the xdrgen types
through the nlm_lockargs_wrapper structure, which bridges between
generated code and the legacy lockd_lock representation.

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.

The NLM async callback mechanism uses client-side functions which
continue to take legacy results like struct lockd_res, preventing
LOCK and LOCK_MSG from sharing code for now.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
ba4c62bb35 lockd: Use xdrgen XDR functions for the NLMv3 TEST_MSG procedure
Continue the xdrgen migration by converting NLMv3 TEST_MSG, the
async counterpart to TEST that clients use to check lock
availability without blocking. The procedure now uses
nlm_svc_decode_nlm_testargs and nlm_svc_encode_void, generated
from the NLM version 3 protocol specification. The procedure
handler reaches the xdrgen types through the
nlm_testargs_wrapper structure, which bridges between generated
code and the legacy lockd_lock representation.

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.

The NLM async callback mechanism uses client-side functions
which continue to take legacy results like struct lockd_res,
preventing TEST and TEST_MSG from sharing code for now.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
596401c14c lockd: Refactor nlmsvc_callback()
The xdrgen-based XDR conversion requires each RPC procedure to
extract its own arguments, since xdrgen generates distinct
argument structures for each procedure rather than using a
single shared type.

Move the host lookup logic from nlmsvc_callback() into each
of the five MSG procedure handlers (TEST_MSG, LOCK_MSG,
CANCEL_MSG, UNLOCK_MSG, and GRANTED_MSG). Each handler now
performs its own host lookup from rqstp->rq_argp and passes
the resulting host pointer to nlmsvc_callback(). This
establishes the per-procedure argument-handling pattern that
the subsequent xdrgen conversion patches require.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
e04d248b8a 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 <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
1b0490e6a0 lockd: Use xdrgen XDR functions for the NLMv3 UNLOCK procedure
The NLM UNLOCK procedure allows clients to release held locks,
completing the basic lock lifecycle alongside TEST, LOCK, and
CANCEL procedures already converted in this series.

Convert UNLOCK to use the xdrgen functions
nlm_svc_decode_nlm_unlockargs and nlm_svc_encode_nlm_res
generated from the NLM version 3 protocol specification, reusing
the nlm3svc_lookup_host() and nlm3svc_lookup_file() helpers
introduced earlier in the series. 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 <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
954a3f3f6c 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 <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
a77fec7b73 lockd: Use xdrgen XDR functions for the NLMv3 LOCK procedure
The NLM LOCK procedure requires the same host and file lookup
operations established in the TEST procedure conversion. This
patch extends the xdrgen migration to the LOCK procedure,
leveraging the shared nlm3svc_lookup_host() and
nlm3svc_lookup_file() helpers to establish consistent patterns
across the series.

This patch converts the LOCK procedure to use xdrgen functions
nlm_svc_decode_nlm_lockargs and nlm_svc_encode_nlm_res generated
from the NLM version 3 protocol specification. The procedure
handler uses xdrgen types through wrapper structures that bridge
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 cookie and lock members of the wrapper are populated
explicitly in nlm_netobj_to_cookie() and nlm3svc_lookup_file()
rather than relying on zero-initialization.

The hand-rolled svcxdr_decode_cookie() previously substituted a
four-byte zero cookie when a zero-length cookie arrived on the
wire, a compatibility shim for HP-UX clients that had been
carried in fs/lockd/ since the original import. The xdrgen
decoder reproduces the cookie verbatim, and
nlm_netobj_to_cookie() copies whatever length the peer sent. As
subsequent patches replace the remaining call sites of
svcxdr_decode_cookie(), this series retires that HP-UX compat
behavior on the server side.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
3031fd999e lockd: Use xdrgen XDR functions for the NLMv3 TEST procedure
The NLM TEST procedure requires host and file lookups to check
lock state, operations that will be common across multiple NLM
procedures being migrated to xdrgen. Introducing the
nlm3svc_lookup_host() and nlm3svc_lookup_file() helpers now keeps
these common patterns in one place for subsequent conversions in
this series.

This patch converts the TEST procedure to use xdrgen functions
nlm_svc_decode_nlm_testargs and nlm_svc_encode_nlm_testres
generated from the NLM version 3 protocol specification. The
procedure handler is rewritten to use xdrgen types through wrapper
structures that bridge 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.

The conflicting holder's offset and length are saturated to
NLM_OFFSET_MAX when constructing the reply. A conflicting lock
established by an NLMv4 client or by a local process can sit
beyond the NLMv3 signed 32-bit range, and copying fl_start and
fl_end straight into the unsigned 32-bit XDR fields would wrap
and report a bogus range. The previous hand-written encoder in
svcxdr_encode_holder() used loff_t_to_s32() for the same reason,
but this patch series intends to separate the concerns of data
conversion (XDR) from dealing with local byte range constraints,
so clamping is hoisted into the proc function.

The previous hand-written decoder in svcxdr_decode_cookie()
rewrote a zero-length NLM cookie into a four-byte zero cookie,
with a comment attributing the substitution to HP-UX clients.
The xdrgen-generated netobj decoder performs no such rewrite, so
a zero-length request cookie now round-trips unchanged into the
reply. HP-UX has reached end of support, and NLM_TEST reply
matching relies on the RPC XID rather than the NLM cookie, so
the workaround is dropped intentionally here.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
94c281d5e9 lockd: Use xdrgen XDR functions for the NLMv3 NULL procedure
Hand-written XDR encoders and decoders are difficult to maintain
and can diverge from protocol specifications. Migrating to
xdrgen-generated code improves type safety and ensures the
implementation matches the NLM version 3 protocol specification
exactly.

Convert the NULL procedure to use nlm_svc_decode_void and
nlm_svc_encode_void, generated from
Documentation/sunrpc/xdr/nlm3.x. NULL has no arguments or
results, so it is the first procedure converted.

NULL returns no XDR-encoded data, so pc_xdrressize is set to
XDR_void. The argzero field is also set to zero since xdrgen
decoders initialize all decoded values.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
c03ded750f lockd: Rename struct nlm_reboot to lockd_reboot
As part of the effort to enable lockd's server-side XDR functions to
be generated from the NLM protocol specification (using xdrgen), the
internal type names must be changed to avoid conflicts with the
machine-generated type names.

Rename struct nlm_reboot to struct lockd_reboot for consistency with
the other renamed internal types.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
86ed2898fa lockd: Rename struct nlm_res to lockd_res
As part of the effort to enable lockd's server-side XDR functions to
be generated from the NLM protocol specification (using xdrgen), the
internal type names must be changed to avoid conflicts with the
machine-generated type names.

Rename struct nlm_res to struct lockd_res to avoid conflicts with
the NLMv3 XDR type definitions that will be introduced when svcproc.c
is converted to use xdrgen.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
815778f88b lockd: Rename struct nlm_args to lockd_args
As part of the effort to enable lockd's server-side XDR functions to
be generated from the NLM protocol specification (using xdrgen), the
internal type names must be changed to avoid conflicts with the
machine-generated type names.

Rename struct nlm_args to struct lockd_args to avoid conflicts with
the NLMv3 XDR type definitions that will be introduced when
svcproc.c is converted to use xdrgen.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
ef66678dd4 lockd: Rename struct nlm_lock to lockd_lock
A subsequent patch will convert fs/lockd/svcproc.c to use
machine-generated XDR encoding and decoding functions in a
manner similar to fs/lockd/svc4proc.c. Machine-generated
types derived from the NLM specification will conflict with
the internal types of the same name.

Rename the internal struct nlm_lock type to lockd_lock to
avoid such naming conflicts.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
Chuck Lever
5cca6056f2 lockd: Stop warning on nlm__int__drop_reply in !V4 cast_status
cast_status folds internal lock-daemon sentinels into NLMv1/v3
wire status codes.  The !CONFIG_LOCKD_V4 variant warns when an
unrecognized status falls into the internal-sentinel range,
gated by be32_to_cpu(status) >= 30000.

nlm__int__drop_reply is defined as cpu_to_be32(30000), so it
sits at the lower edge of that range and trips pr_warn_once
("lockd: unhandled internal status %u").  The status is
returned unchanged so the reply is still dropped, but every
dropped reply on a !CONFIG_LOCKD_V4 build emits a spurious
warning.

Compare against nlm__int__drop_reply directly so the warning
still catches the genuinely unexpected sentinels deadlock,
stale_fh, and failed (30001 through 30003) but excludes the
legitimate dropped-reply marker.

Fixes: d343fce148 ("[PATCH] knfsd: Allow lockd to drop replies as appropriate")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09 16:32:59 -04:00
NeilBrown
0b47424032 lockd: fix TEST handling when not all permissions are available.
The F_GETLK fcntl can work with either read access or write access or
both.  It can query F_RDLCK and F_WRLCK locks in either case.

However lockd currently treats F_GETLK similar to F_SETLK in that read
access is required to query an F_RDLCK lock and write access is required
to query a F_WRLCK lock.

This is wrong and can cause problems - e.g.  when qemu accesses a
read-only (e.g. iso) filesystem image over NFS (though why it queries
if it can get a write lock - I don't know.  But it does, and this works
with local filesystems).

So we need TEST requests to be handled differently.  To do this:

- change nlm_do_fopen() to accept O_RDWR as a mode and in that case
  succeed if either a O_RDONLY or O_WRONLY file can be opened.
- change nlm_lookup_file() to accept a mode argument from caller,
  instead of deducing base on lock time, and pass that on to nlm_do_fopen()
- change nlm4svc_retrieve_args() and nlmsvc_retrieve_args() to detect
  TEST requests and pass O_RDWR as a mode to nlm_lookup_file, passing
  the same mode as before for other requests.  Also set
   lock->fl.c.flc_file to whichever file is available for TEST requests.
- change nlmsvc_testlock() to also not calculate the mode, but to use
  whatever was stored in lock->fl.c.flc_file.

This behaviour of lockd - requesting O_WRONLY access to TEST for
exclusive locks - has been present at least since git history began.
However it was hidden until recently because knfsd ignored the access
requested by lockd and required only READ access for all locking
requests (unless the underlying filesystem provided an f_op->open
function which checked access permissions).

The commit mentioned in Fixes: below changed nfsd_permission() to NOT
override the access request for LOCK requests and this exposed the bug
that we are now fixing.

Note that there is another issue that this patch does not address.
The flock(.., LOCK_EX) call is permitted on a read-only file descriptor.
Linux NFS maps this to NLM locking as whole-file byte-range locks.
nfsd will see this as though it were fcntl( F_SETLK (F_WRLCK)) and will
now require write access, which it might not be able to get.
It is not clear if this is a problem in practice, or what the best
solution might be.  So no attempt is made to address it.

Reported-by: Tj <tj.iam.tj@proton.me>
Link: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1128861
Fixes: 4cc9b9f2bf ("nfsd: refine and rename NFSD_MAY_LOCK")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: NeilBrown <neil@brown.name>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-05-21 17:08:47 -04:00
Chuck Lever
4e6814b175 lockd: Prepare share helpers for xdrgen conversion
In order to convert the NLMv4 server-side XDR functions to use
xdrgen, the internal share helpers need to be decoupled from the
NLMv3-specific struct nlm_args. NLMv4 procedures will use
different argument structures once they are converted.

Refactor nlmsvc_share_file() and nlmsvc_unshare_file() to accept
individual arguments (oh, access, mode) instead of the common
struct nlm_args. This allows both protocol versions to call these
helpers without forcing a common argument structure.

While here, add kdoc comments to both functions and fix a comment
typo in the unshare path.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
45cd458b57 lockd: Relocate svc_version definitions to XDR layer
Public RPC server interfaces become cluttered when internal
XDR implementation details leak into them. The procedure count,
maximum XDR buffer size, and per-CPU call counters serve no
purpose outside the code that encodes and decodes NLM protocol
messages. Exposing these values through global headers creates
unnecessary coupling between the RPC dispatch logic and the
XDR layer.

Relocating the svc_version structure definitions confines this
implementation information to the files where XDR encoding and
decoding occur. In svc.c, the buffer size computation now reads
vs_xdrsize from the version structures rather than relying on a
preprocessor constant. This calculation occurs at service
initialization, after the linker has resolved the version
structure definitions. The dispatch function becomes non-static
because both the version structures and the dispatcher reside in
different translation units.

The NLMSVC_XDRSIZE macro is removed from xdr.h because buffer
size is now computed from the union of XDR argument and result
structures, matching the pattern used in other RPC services.
Version 1 and 3 share the same procedure table but maintain
separate counter arrays. Version 4 remains separate due to its
distinct procedure definitions.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
2c562c6e67 lockd: Relocate include/linux/lockd/lockd.h
Headers placed in include/linux/ form part of the kernel's
internal API and signal to subsystem maintainers that other
parts of the kernel may depend on them. By moving lockd.h
into fs/lockd/, lockd becomes a more self-contained module
whose internal interfaces are clearly distinguished from its
public contract with the rest of the kernel. This relocation
addresses a long-standing XXX comment in the header itself
that acknowledged the file's misplacement. Future changes to
lockd internals can now proceed with confidence that external
consumers are not inadvertently coupled to implementation
details.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
4db2f8a016 lockd: Move share.h from include/linux/lockd/ to fs/lockd/
The share.h header defines struct nlm_share and declares the DOS
share management functions used by the NLM server to implement
NLM_SHARE and NLM_UNSHARE operations. These interfaces are used
exclusively within the lockd subsystem. A git grep search confirms
no external code references them.

Relocating this header from include/linux/lockd/ to fs/lockd/
narrows the public API surface of the lockd module. Out-of-tree
code cannot depend on these internal interfaces after this change.
Future refactoring of the share management implementation thus
requires no consideration of external consumers.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
7db001e03d lockd: Have nlm_fopen() return errno values
The nlm_fopen() function is part of the API between nfsd and lockd.

Currently its return value is an on-the-wire NLM status code. But
that forces NFSD to include NLM wire protocol definitions despite
having no other dependency on the NLM wire protocol.

In addition, a CONFIG_LOCKD_V4 Kconfig symbol appears in the middle
of NFSD source code.

Refactor: Let's not use on-the-wire values as part of a high-level
API between two Linux kernel modules. That's what we have errno for,
right?

And, instead of simply moving the CONFIG_LOCKD_V4 check, we can get
rid of it entirely and let the decision of what actual NLM status
code goes on the wire to be left up to NLM version-specific code.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
9e0d0c6194 lockd: Introduce nlm__int__deadlock
The use of CONFIG_LOCKD_V4 in combination with a later cast_status()
in the NLMv3 code is difficult to reason about. Instead, replace the
use of nlm_deadlock with an implementation-defined status value that
version-specific code translates appropriately.

The new approach establishes a translation boundary: generic lockd
code returns nlm__int__deadlock when posix_lock_file() yields
-EDEADLK. Version-specific handlers (svc4proc.c for NLMv4,
svcproc.c for NLMv3) translate this internal status to the
appropriate wire protocol value. NLMv4 maps to nlm4_deadlock;
NLMv3 maps to nlm_lck_denied (since NLMv3 lacks a deadlock-specific
status code).

Later this modification will also remove the need to include NLMv4
headers in NLMv3 and generic code.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
153b9e0253 lockd: Relocate and rename nlm_drop_reply
The nlm_drop_reply status code is internal to the kernel's lockd
implementation and must never appear on the wire. Its previous
location in xdr.h grouped it with legitimate NLM protocol status
codes, obscuring this critical distinction.

Relocate the definition to lockd.h with a comment block for internal
status codes, and rename to nlm__int__drop_reply to make its
internal-only nature explicit. This prepares for adding additional
internal status codes in subsequent patches.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
Chuck Lever
aa772bcc40 lockd: Simplify cast_status() in svcproc.c
Clean up: The svcproc.c file handles only NLM v1 and v3 requests.
NLMv4 requests are routed to a separate procedure table in
svc4proc.c, so rqstp->rq_vers can never be 4 in this context.

Remove the unused vers parameter and the dead "vers != 4" check from
cast_to_nlm(). This eliminates the need for the macro wrapper.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29 21:25:09 -04:00
NeilBrown
a49a2a1baa lockd: fix vfs_test_lock() calls
Usage of vfs_test_lock() is somewhat confused.  Documentation suggests
it is given a "lock" but this is not the case.  It is given a struct
file_lock which contains some details of the sort of lock it should be
looking for.

In particular passing a "file_lock" containing fl_lmops or fl_ops is
meaningless and possibly confusing.

This is particularly problematic in lockd.  nlmsvc_testlock() receives
an initialised "file_lock" from xdr-decode, including manager ops and an
owner.  It then mistakenly passes this to vfs_test_lock() which might
replace the owner and the ops.  This can lead to confusion when freeing
the lock.

The primary role of the 'struct file_lock' passed to vfs_test_lock() is
to report a conflicting lock that was found, so it makes more sense for
nlmsvc_testlock() to pass "conflock", which it uses for returning the
conflicting lock.

With this change, freeing of the lock is not confused and code in
__nlm4svc_proc_test() and __nlmsvc_proc_test() can be simplified.

Documentation for vfs_test_lock() is improved to reflect its real
purpose, and a WARN_ON_ONCE() is added to avoid a similar problem in the
future.

Reported-by: Olga Kornievskaia <okorniev@redhat.com>
Closes: https://lore.kernel.org/all/20251021130506.45065-1-okorniev@redhat.com
Signed-off-by: NeilBrown <neil@brown.name>
Fixes: 20fa190272 ("nfs: add export operations")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2025-12-24 21:18:46 -05:00
Chuck Lever
8994a512e2 lockd: Remove unused parameter to nlmsvc_testlock()
The nlm_cookie parameter has been unused since commit 09802fd2a8
("lockd: rip out deferred lock handling from testlock codepath").

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18 20:23:04 -05:00
Chuck Lever
a872c7313e lockd: Remove some snippets of unfinished code
Clean up.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2024-11-18 20:23:04 -05:00
Jeff Layton
eb8ed7c6ab
lockd: adapt to breakup of struct file_lock
Most of the existing APIs have remained the same, but subsystems that
access file_lock fields directly need to reach into struct
file_lock_core now.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://lore.kernel.org/r/20240131-flsplit-v3-40-c6129007ee8d@kernel.org
Reviewed-by: NeilBrown <neilb@suse.de>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-02-05 13:11:43 +01:00
Jeff Layton
75c7940d2a lockd: set missing fl_flags field when retrieving args
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2022-12-10 11:01:11 -05:00
Chuck Lever
103cc1fafe SUNRPC: Parametrize how much of argsize should be zeroed
Currently, SUNRPC clears the whole of .pc_argsize before processing
each incoming RPC transaction. Add an extra parameter to struct
svc_procedure to enable upper layers to reduce the amount of each
operation's argument structure that is zeroed by SUNRPC.

The size of struct nfsd4_compoundargs, in particular, is a lot to
clear on each incoming RPC Call. A subsequent patch will cut this
down to something closer to what NFSv2 and NFSv3 uses.

This patch should cause no behavior changes.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2022-09-26 14:02:42 -04:00
Benjamin Coddington
184cefbe62 NLM: Defend against file_lock changes after vfs_test_lock()
Instead of trusting that struct file_lock returns completely unchanged
after vfs_test_lock() when there's no conflicting lock, stash away our
nlm_lockowner reference so we can properly release it for all cases.

This defends against another file_lock implementation overwriting fl_owner
when the return type is F_UNLCK.

Reported-by: Roberto Bergantinos Corpas <rbergant@redhat.com>
Tested-by: Roberto Bergantinos Corpas <rbergant@redhat.com>
Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2022-07-29 20:08:56 -04:00
Chuck Lever
b40887e10d SUNRPC: Trace calls to .rpc_call_done
Introduce a single tracepoint that can replace simple dprintk call
sites in upper layer "rpc_call_done" callbacks. Example:

   kworker/u24:2-1254  [001]   771.026677: rpc_stats_latency:    task:00000001@00000002 xid=0x16a6f3c0 rpcbindv2 GETPORT backlog=446 rtt=101 execute=555
   kworker/u24:2-1254  [001]   771.026677: rpc_task_call_done:   task:00000001@00000002 flags=ASYNC|DYNAMIC|SOFT|SOFTCONN|SENT runstate=RUNNING|ACTIVE status=0 action=rpcb_getport_done
   kworker/u24:2-1254  [001]   771.026678: rpcb_setport:         task:00000001@00000002 status=0 port=20048

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
2021-10-20 18:09:54 -04:00
J. Bruce Fields
7f024fcd5c Keep read and write fds with each nlm_file
We shouldn't really be using a read-only file descriptor to take a write
lock.

Most filesystems will put up with it.  But NFS, for example, won't.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2021-08-23 18:05:31 -04:00
J. Bruce Fields
2dc6f19e4f nlm: minor nlm_lookup_file argument change
It'll come in handy to get the whole nlm_lock.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2021-08-23 12:56:03 -04:00