| Age | Commit message (Collapse) | Author |
|
A client can repeatedly drive nlm_do_fopen() failures by presenting
file handles that the underlying export rejects. After kzalloc_obj()
succeeds in nlm_lookup_file(), the freshly allocated nlm_file is not
yet inserted into nlm_files[]. The nlm_do_fopen() failure path jumps
to out_unlock, which releases nlm_file_mutex and returns without
freeing the allocation, so each failure leaks one nlm_file.
Route the failure through out_free so kfree() runs before the
function returns.
Fixes: 7f024fcd5c97 ("Keep read and write fds with each nlm_file")
Cc: stable@vger.kernel.org
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
This reverts commit 48db892356d6cb80f6942885545de4a6dd8d2a29.
Commit 48db892356d6 ("NFSD: Defer sub-object cleanup in export
put callbacks") moved path_put() and auth_domain_put() out of
svc_export_put() and expkey_put() and behind queue_rcu_work() to
close a claimed use-after-free in e_show() and c_show() against
ex_path and ex_client->name. Discussion in [1] shows neither
the diagnosis nor the remedy survives review.
The downstream teardown of both sub-objects is already RCU-deferred.
auth_domain_put() reaches svcauth_unix_domain_release(), which frees
the unix_domain and its ->name through call_rcu(). path_put()
reaches dentry_free(), which frees the dentry through call_rcu(),
and prepend_path() is already structured to tolerate concurrent
dentry teardown. A reader in cache_seq_start_rcu() therefore
observes both sub-objects through the next grace period regardless
of whether svc_export_put() runs synchronously, so the synchronous
form was never unsafe.
The crash signature in the report cited by commit 48db892356d6
("NFSD: Defer sub-object cleanup in export put callbacks") has a
different root cause: a /proc/net/rpc cache file held open across
network-namespace exit lets cache_destroy_net() free cd->hash_table
while a reader is still walking it. The correct fix pins cd->net for
the open fd's lifetime and does not require any deferral inside
svc_export_put().
Meanwhile, deferring path_put() out of svc_export_put() reintroduces
the regression that commit 69d803c40ede ("nfsd: Revert "nfsd:
release svc_expkey/svc_export with rcu_work"") repaired: after
"exportfs -r" drops the last cache reference, the mount reference
held through ex_path lingers in the workqueue, so a subsequent
umount fails with EBUSY.
Restore the synchronous path_put() and auth_domain_put() in
svc_export_put() and expkey_put() and the call_rcu()/kfree_rcu()
free of the containing structures. The unrelated fix for
ex_uuid/ex_stats from commit 2530766492ec ("nfsd: fix UAF when
access ex_uuid or ex_stats") is preserved.
Link: https://lore.kernel.org/all/10019b42-4589-4f9f-8d5b-d8197db1ce3c@huawei.com/ [1]
Fixes: 48db892356d6 ("NFSD: Defer sub-object cleanup in export put callbacks")
Cc: stable@vger.kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Alexandr Alexandrov <alexandr.alexandrov@oracle.com>
Signed-off-by: Yang Erkun <yangerkun@huawei.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
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>
|
|
All NLMv3 server-side procedures now dispatch through
xdrgen-generated encoder and decoder functions, leaving the
hand-written XDR processing in fs/lockd/xdr.c with no remaining
callers.
Remove fs/lockd/xdr.c, the fs/lockd/svcxdr.h header it included,
the Makefile entry, and the now-unused nlmsvc_decode_* /
nlmsvc_encode_* prototypes from fs/lockd/xdr.h. The structure
definitions and status code macros in xdr.h are retained as they
are still used by the client-side code.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
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_share to struct lockd_share 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>
|
|
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>
|
|
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>
|
|
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>
|
|
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>
|
|
Machine-generated XDR types derived from the NLM specification
use names that match the protocol. Internal lockd types with
identical names cause compilation failures when machine-generated
encoders replace hand-coded ones.
Rename the internal struct nlm_cookie type to lockd_cookie to
prevent such collisions. The "lockd_" prefix distinguishes
implementation-specific types from specified NLM protocol types.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
In order to generate source code to encode and decode NLMv3 protocol
elements, include a copy of the RPC language description of NLMv3
for xdrgen to process. The language description is derived from the
Open Group's XNFS specification:
https://pubs.opengroup.org/onlinepubs/9629799/chap10.htm#tagcjh_11_03
The C code committed here was generated from the new nlm3.x file
using tools/net/sunrpc/xdrgen/xdrgen.
The goals of replacing hand-written XDR functions with ones that
are tool-generated are to improve memory safety and make XDR
encoding and decoding less brittle to maintain. Parts of the
NFSv4 protocol are still being extended actively. Tool-generated
XDR code reduces the time it takes to get a working implementation
of new protocol elements.
The xdrgen utility derives both the type definitions and the
encode/decode functions directly from protocol specifications,
using names and symbols familiar to anyone who knows those specs.
Unlike hand-written code that can inadvertently diverge from the
specification, xdrgen guarantees that the generated code matches
the specification exactly.
We would eventually like xdrgen to generate Rust code as well,
making the conversion of the kernel's NFS stacks to use Rust just
a little easier for us.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
A LOCK_MSG handler that fails to obtain a host returns
rpc_system_err, which causes the dispatcher to send an RPC-level
error rather than an NLM LOCK_RES denial. Before the xdrgen
conversion, the outer host lookup was unmonitored, so an NSM
upcall failure was reported back to the client through LOCK_RES
with status nlm_lck_denied_nolocks generated by the inner helper.
The xdrgen conversion replaced the unmonitored lookup with
nlm4svc_lookup_host(..., true). When nsm_monitor() fails, the
outer lookup now returns NULL, so the procedure short-circuits to
rpc_system_err and __nlm4svc_proc_lock_msg() never runs. The
client therefore receives no LOCK_RES, regressing the legacy
behavior.
The inner helper still performs a monitored lookup while building
the LOCK_RES, so the outer call only needs an unmonitored host
reference for the callback path. Pass false here to restore the
previous semantics.
Fixes: b2be4e28c23a ("lockd: Use xdrgen XDR functions for the NLMv4 LOCK_MSG procedure")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
When nlmsvc_lock() detects a deadlock it returns the internal
sentinel nlm__int__deadlock (30001), which version-specific
handlers must translate to a wire-valid status before the reply
is encoded. The xdrgen LOCK_MSG handler stores the sentinel
unmodified in resp->status; the LOCK_RES callback then places
30001 on the v4 wire, where the client rejects the reply.
Commit 9e0d0c619407 ("lockd: Introduce nlm__int__deadlock")
established the translation boundary and updated the synchronous
v4 path nlm4svc_do_lock(), but the xdrgen LOCK_MSG handler added
later in commit b2be4e28c23a ("lockd: Use xdrgen XDR functions
for the NLMv4 LOCK_MSG procedure") missed the corresponding
remap. Apply the same translation in __nlm4svc_proc_lock_msg()
so deadlock results are reported as nlm4_deadlock on LOCK_RES.
Fixes: b2be4e28c23a ("lockd: Use xdrgen XDR functions for the NLMv4 LOCK_MSG procedure")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
The NLMv4 GRANTED helper passes the wrapper's lock to
nlmclnt_grant(), which compares only fl_start, fl_end, svid, and
fh, and the shared nlmclnt_lock_event tracepoint now sources its
byte-range fields from fl_start and fl_end as well. Both fl_start
and fl_end are set unconditionally by lockd_set_file_lock_range4()
on the line below, so the locks_init_lock() call left no observable
effect: every other field of struct file_lock is unread on the
GRANTED path.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
NLM_GRANTED is a server-to-client callback; the local node
responds in the role of the client. The kernel-doc for
nlm4svc_proc_granted attributes NLM4_DENIED and
NLM4_DENIED_GRACE_PERIOD to "the server", but per the Open
Group XNFS specification the responder for this procedure is
the client host, and NLM4_DENIED_GRACE_PERIOD identifies the
client's own grace period after a reboot, not the server's.
Rewrite the descriptions to match the spec: NLM4_DENIED
reflects the generic internal-resource-constraint failure, and
NLM4_DENIED_GRACE_PERIOD attributes the grace period to the
client host that received the callback.
Fixes: 7a9f7c8f934e ("lockd: Use xdrgen XDR functions for the NLMv4 GRANTED procedure")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
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: d343fce148a4 ("[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>
|
|
Commit 8a81f16de64f ("NFSD: Add a "default" block size") introduced
NFSSVC_DEFBLKSIZE at 1MB, well below the 4MB NFSSVC_MAXBLKSIZE
ceiling, with the stated intent that a later change would raise the
default.
Raising the default reduces per-RPC overhead on fast networks by
amortizing header processing and scheduling costs across larger
payloads. The halving loop in nfsd_get_default_max_blksize()
constrains the returned value to 1/4096 of available RAM, so the
new 4MB default takes effect only on systems with at least 16GB of
RAM. Smaller machines continue to receive the same computed value
as before. Administrators can still override the computed value
through /proc/fs/nfsd/max_block_size.
On systems where the new default takes effect,
svc_sock_setbufsize() sizes each service socket's send and receive
buffers as nreqs * max_mesg * 2. Quadrupling max_mesg therefore
quadruples the per-socket buffer reservation at a fixed thread
count, which operators tuning large thread pools should account
for.
Note well: Your NFS client implementation must support large read
and write size settings to benefit from this change.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
When NFSD_CMD_UNLOCK_EXPORT revokes NFSv4 state for an export path,
GC-managed nfsd_file entries for files under that path may remain
in the file cache. These cached handles hold the underlying
filesystem busy, preventing a subsequent unmount.
Add nfsd_file_close_export(), which walks the nfsd_file hash table
and closes GC-eligible entries whose underlying file resides on the
same filesystem and is a descendant of the export path. Because
nfsd_file entries do not carry an export reference, the ancestry
check uses is_subdir() on the file's dentry. False positives --
closing a cached handle that did not originate from the target
export -- are harmless; the handle is simply reopened on the next
access.
The handler calls nfsd_file_close_export() before revoking NFSv4
state, mirroring the order used by NFSD_CMD_UNLOCK_FILESYSTEM
(which cancels copies and releases NLM locks before revoking
state). Both calls run under nfsd_mutex.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
When a filesystem is exported to NFS clients, NFSv4 state
(opens, locks, delegations, layouts) holds references that
prevent the underlying filesystem from being unmounted.
NFSD_CMD_UNLOCK_FILESYSTEM addresses this at superblock
granularity, but administrators unexporting a single path on a
shared filesystem (e.g., one of several exports on the same device)
need finer control.
Add NFSD_CMD_UNLOCK_EXPORT, which revokes NFSv4 state acquired
through exports of a specific path. Matching is by path identity
(dentry + vfsmount) via the sc_export field on each nfs4_stid,
so multiple svc_export objects for the same path -- one per
auth_domain -- are handled correctly without requiring the caller
to name a specific client.
The command takes a single "path" attribute. Userspace (exportfs
-u) sends this after removing the last client for a given path,
enabling the underlying filesystem to be unmounted. When multiple
clients share an export path, individual unexports do not trigger
state revocation; only the final one does.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
Add an sc_export field to struct nfs4_stid so that each stateid
records the export under which it was acquired. The export
reference is taken via exp_get() at stateid creation and released
via exp_put() in nfs4_put_stid().
Open stateids record the export from current_fh->fh_export.
Lock stateids and delegations inherit the export from their
parent open stateid. Layout stateids inherit from their
parent stateid. Directory delegations record the export from
cstate->current_fh.
A subsequent commit uses sc_export to scope state revocation to a
specific export, avoiding the need to walk inode dentry aliases at
revocation time.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
Replace idr_for_each_entry_ul() with a while loop over
idr_get_next_ul() for consistency with find_one_export_stid(),
added in a subsequent commit.
No change in behavior.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
Add NFSD_CMD_UNLOCK_FILESYSTEM as a dedicated netlink command for
revoking NFS state under a filesystem path, providing a netlink
equivalent of /proc/fs/nfsd/unlock_fs.
The command requires a "path" string attribute containing the
filesystem path whose state should be released. The handler
resolves the path to its superblock, then cancels async copies,
releases NLM locks, and revokes NFSv4 state on that superblock.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
The existing write_unlock_ip procfs interface releases NLM file
locks held by a specific client IP address, but procfs provides
no structured way to extend that operation to other scopes such as
revoking NFSv4 state.
Add NFSD_CMD_UNLOCK_IP as a dedicated netlink command for
releasing NLM locks by client address. The command accepts a
binary sockaddr_in or sockaddr_in6 in its address attribute.
The handler validates the address family and length, then calls
nlmsvc_unlock_all_by_ip() to release matching NLM locks. Because
lockd is a single global instance, that call operates across
all network namespaces regardless of which namespace the caller
inhabits.
A separate netlink command for filesystem-scoped unlock is added in
a subsequent commit.
The nfsd_ctl_unlock_ip tracepoint is updated from string-based
address logging to __sockaddr, which stores the binary sockaddr
and formats it with %pISpc. This affects both the new netlink path
and the existing procfs write_unlock_ip path, giving consistent
structured output in both cases.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
The per-stateid revocation logic in nfsd4_revoke_states() handles
four stateid types in a deeply nested switch. Extract two helpers:
revoke_ol_stid() performs admin-revocation of an open or lock
stateid with st_mutex already held: marks the stateid as
SC_STATUS_ADMIN_REVOKED, closes POSIX locks for lock stateids,
and releases file access.
revoke_one_stid() dispatches by sc_type, acquires st_mutex with
the appropriate lockdep class for open and lock stateids, and
handles delegation unhash and layout close inline.
No functional change. Preparation for adding export-scoped state
revocation which reuses revoke_one_stid().
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
nfsd4_drop_revoked_stid() has no SC_TYPE_LAYOUT case, so when a
client sends FREE_STATEID for an admin-revoked layout stid, the
default branch releases cl_lock and returns without unhashing or
releasing the stid. The stid remains in the IDR and on the
per-client list until the client is destroyed.
Remove the layout stid from the per-client list and call
nfs4_put_stid() to drop the creation reference. When the
refcount reaches zero, nfsd4_free_layout_stateid() handles the
remaining cleanup: cancelling the fence worker, removing from
the per-file list, and freeing the slab object.
Fixes: 1e33e1414bec ("nfsd: allow layout state to be admin-revoked.")
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Tested-by: Dai Ngo <dai.ngo@oracle.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
A comment in fs/nfs/dir.c incorrectly refers to CONFIG_NFSV4 instead of
CONFIG_NFS_V4. Correct it.
Discovered while searching for CONFIG_* symbols referenced in code but
not defined in any Kconfig file.
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
|