summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-03-29SUNRPC: Optimize rq_respages allocation in svc_alloc_argChuck Lever
svc_alloc_arg() invokes alloc_pages_bulk() with the full rq_maxpages count (~259 for 1MB messages) for the rq_respages array, causing a full-array scan despite most slots holding valid pages. svc_rqst_release_pages() NULLs only the range [rq_respages, rq_next_page) after each RPC, so only that range contains NULL entries. Limit the rq_respages fill in svc_alloc_arg() to that range instead of scanning the full array. svc_init_buffer() initializes rq_next_page to span the entire rq_respages array, so the first svc_alloc_arg() call fills all slots. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29SUNRPC: Track consumed rq_pages entriesChuck Lever
The rq_pages array holds pages allocated for incoming RPC requests. Two transport receive paths NULL entries in rq_pages to prevent svc_rqst_release_pages() from freeing pages that the transport has taken ownership of: - svc_tcp_save_pages() moves partial request data pages to svsk->sk_pages during multi-fragment TCP reassembly. - svc_rdma_clear_rqst_pages() moves request data pages to head->rc_pages because they are targets of active RDMA Read WRs. A new rq_pages_nfree field in struct svc_rqst records how many entries were NULLed. svc_alloc_arg() uses it to refill only those entries rather than scanning the full rq_pages array. In steady state, the transport NULLs a handful of entries per RPC, so the allocator visits only those entries instead of the full ~259 slots (for 1MB messages). Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29svcrdma: preserve rq_next_page in svc_rdma_save_io_pagesChuck Lever
svc_rdma_save_io_pages() transfers response pages to the send context and sets those slots to NULL. It then resets rq_next_page to equal rq_respages, hiding the NULL region from svc_rqst_release_pages(). Now that svc_rqst_release_pages() handles NULL entries, this reset is no longer necessary. Removing it preserves the invariant that the range [rq_respages, rq_next_page) accurately describes how many response pages were consumed, enabling a subsequent optimization in svc_alloc_arg() that refills only the consumed range. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29SUNRPC: Handle NULL entries in svc_rqst_release_pagesChuck Lever
svc_rqst_release_pages() releases response pages between rq_respages and rq_next_page. It currently passes the entire range to release_pages(), which does not expect NULL entries. A subsequent patch preserves the rq_next_page pointer in svc_rdma_save_io_pages() so that it accurately records how many response pages were consumed. After that change, the range [rq_respages, rq_next_page) can contain NULL entries where pages have already been transferred to a send context. Iterate through the range entry by entry, skipping NULLs, to handle this case correctly. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29SUNRPC: Allocate a separate Reply page arrayChuck Lever
struct svc_rqst uses a single dynamically-allocated page array (rq_pages) for both the incoming RPC Call message and the outgoing RPC Reply message. rq_respages is a sliding pointer into rq_pages that each transport receive path must compute based on how many pages the Call consumed. This boundary tracking is a source of confusion and bugs, and prevents an RPC transaction from having both a large Call and a large Reply simultaneously. Allocate rq_respages as its own page array, eliminating the boundary arithmetic. This decouples Call and Reply buffer lifetimes, following the precedent set by rq_bvec (a separate dynamically- allocated array for I/O vectors). Each svc_rqst now pins twice as many pages as before. For a server running 16 threads with a 1MB maximum payload, the additional cost is roughly 16MB of pinned memory. The new dynamic svc thread count facility keeps this overhead minimal on an idle server. A subsequent patch in this series limits per-request repopulation to only the pages released during the previous RPC, avoiding a full-array scan on each call to svc_alloc_arg(). Note: We've considered several alternatives to maintaining a full second array. Each alternative reintroduces either boundary logic complexity or I/O-path allocation pressure. rq_next_page is initialized in svc_alloc_arg() and svc_process() during Reply construction, and in svc_rdma_recvfrom() as a precaution on error paths. Transport receive paths no longer compute it from the Call size. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29SUNRPC: Tighten bounds checking in svc_rqst_replace_pageChuck Lever
svc_rqst_replace_page() builds the Reply buffer by advancing rq_next_page through the response page range. The bounds check validates rq_next_page against the full rq_pages array, but the valid range for rq_next_page is [rq_respages, rq_page_end]. Use those bounds instead. This is correct today because rq_respages and rq_page_end both point into rq_pages, and it prepares for a subsequent change that separates the Reply page array from rq_pages. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29NFSD: Sign filehandlesBenjamin Coddington
NFS clients may bypass restrictive directory permissions by using open_by_handle() (or other available OS system call) to guess the filehandles for files below that directory. In order to harden knfsd servers against this attack, create a method to sign and verify filehandles using SipHash-2-4 as a MAC (Message Authentication Code). According to https://cr.yp.to/siphash/siphash-20120918.pdf, SipHash can be used as a MAC, and our use of SipHash-2-4 provides a low 1 in 2^64 chance of forgery. Filehandles that have been signed cannot be tampered with, nor can clients reasonably guess correct filehandles and hashes that may exist in parts of the filesystem they cannot access due to directory permissions. Append the 8 byte SipHash to encoded filehandles for exports that have set the "sign_fh" export option. Filehandles received from clients are verified by comparing the appended hash to the expected hash. If the MAC does not match the server responds with NFS error _STALE. If unsigned filehandles are received for an export with "sign_fh" they are rejected with NFS error _STALE. Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29NFSD/export: Add sign_fh export optionBenjamin Coddington
In order to signal that filehandles on this export should be signed, add a "sign_fh" export option. Filehandle signing can help the server defend against certain filehandle guessing attacks. Setting the "sign_fh" export option sets NFSEXP_SIGN_FH. In a future patch NFSD uses this signal to append a MAC onto filehandles for that export. While we're in here, tidy a few stray expflags to more closely align to the export flag order. Link: https://lore.kernel.org/linux-nfs/cover.1772022373.git.bcodding@hammerspace.com Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29NFSD: Add a key for signing filehandlesBenjamin Coddington
A future patch will enable NFSD to sign filehandles by appending a Message Authentication Code(MAC). To do this, NFSD requires a secret 128-bit key that can persist across reboots. A persisted key allows the server to accept filehandles after a restart. Enable NFSD to be configured with this key via the netlink interface. Link: https://lore.kernel.org/linux-nfs/cover.1772022373.git.bcodding@hammerspace.com Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29nfsd: use dynamic allocation for oversized NFSv4.0 replay cacheChuck Lever
Commit 1e8e9913672a ("nfsd: fix heap overflow in NFSv4.0 LOCK replay cache") capped the replay cache copy at NFSD4_REPLAY_ISIZE to prevent a heap overflow, but set rp_buflen to zero when the encoded response exceeded the inline buffer. A retransmitted LOCK reaching the replay path then produced only a status code with no operation body, resulting in a malformed XDR response. When the encoded response exceeds the 112-byte inline rp_ibuf, a buffer is kmalloc'd to hold it. If the allocation fails, rp_buflen remains zero, preserving the behavior from the capped-copy fix. The buffer is freed when the stateowner is released or when a subsequent operation's response fits in the inline buffer. Fixes: 1e8e9913672a ("nfsd: fix heap overflow in NFSv4.0 LOCK replay cache") Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29nfsd: convert global state_lock to per-net deleg_lockJeff Layton
Replace the global state_lock spinlock with a per-nfsd_net deleg_lock. The state_lock was only used to protect delegation lifecycle operations (the del_recall_lru list and delegation hash/unhash), all of which are scoped to a single network namespace. Making the lock per-net removes a source of unnecessary contention between containers. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: split cache_detail queue into request and reader listsJeff Layton
Replace the single interleaved queue (which mixed cache_request and cache_reader entries distinguished by a ->reader flag) with two dedicated lists: cd->requests for upcall requests and cd->readers for open file handles. Readers now track their position via a monotonically increasing sequence number (next_seqno) rather than by their position in the shared list. Each cache_request is assigned a seqno when enqueued, and a new cache_next_request() helper finds the next request at or after a given seqno. This eliminates the cache_queue wrapper struct entirely, simplifies the reader-skipping loops in cache_read/cache_poll/cache_ioctl/ cache_release, and makes the data flow easier to reason about. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: convert queue_wait from global to per-cache-detail waitqueueJeff Layton
The queue_wait waitqueue is currently a file-scoped global, so a wake_up for one cache_detail wakes pollers on all caches. Convert it to a per-cache-detail field so that only pollers on the relevant cache are woken. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: convert queue_lock from global spinlock to per-cache-detail lockJeff Layton
The global queue_lock serializes all upcall queue operations across every cache_detail instance. Convert it to a per-cache-detail spinlock so that different caches (e.g. auth.unix.ip vs nfsd.fh) no longer contend with each other on queue operations. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: Add XPT flags missing from SVC_XPRT_FLAG_LISTChuck Lever
Commit eccbbc7c00a5 ("nfsd: don't use sv_nrthreads in connection limiting calculations.") and commit 898374fdd7f0 ("nfsd: unregister with rpcbind when deleting a transport") added new XPT flags but neglected to update the show_svc_xprt_flags() macro. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Remove dead code from fs/lockd/xdr4.cChuck Lever
Now that all NLMv4 server-side procedures use XDR encoder and decoder functions generated by xdrgen, the hand-written code in fs/lockd/xdr4.c is no longer needed. This file contained the original XDR processing logic that has been systematically replaced throughout this series. Remove the file and its Makefile reference to eliminate the dead code. The helper function nlm4svc_set_file_lock_range() is still needed by the generated code, so move it to xdr4.h as an inline function where it remains accessible. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Remove C macros that are no longer usedChuck Lever
The conversion of all NLMv4 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 "NLMv4 Server procedures". Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Add LOCKD_SHARE_SVID constant for DOS sharing modeChuck Lever
Replace the magic value ~(u32)0 with a named constant. This value is used as a synthetic svid when looking up lockowners for DOS share operations, which have no real process ID associated with them. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 FREE_ALL procedureChuck Lever
With all other NLMv4 procedures now converted to xdrgen-generated XDR functions, the FREE_ALL procedure can be converted as well. This conversion allows the removal of nlm4svc_retrieve_args(), a 79-line helper function that was used only by FREE_ALL to retrieve client information from lockd's internal data structures. Replace the NLMPROC4_FREE_ALL entry in the nlm_procedures4 array with an entry that uses xdrgen-built XDR decoders and encoders. The procedure handler is updated to use the new wrapper structure (nlm4_notify_wrapper) and call nlm4svc_lookup_host() directly, eliminating the need for the now-removed helper function. The .pc_argzero field is set to zero because xdrgen decoders fully initialize all fields in argp->xdrgen, making the early defensive memset unnecessary. The remaining argp fields that fall outside the xdrgen structures are cleared explicitly as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 NM_LOCK procedureChuck Lever
Now that nlm4svc_do_lock() has been introduced to handle both monitored and non-monitored lock requests, the NLMv4 NM_LOCK procedure can be converted to use xdrgen-generated XDR functions. This conversion allows the removal of __nlm4svc_proc_lock(), a helper function that was previously shared between the LOCK and NM_LOCK procedures. Replace the NLMPROC4_NM_LOCK entry in the nlm_procedures4 array with an entry that uses xdrgen-built XDR decoders and encoders. The procedure handler is updated to call nlm4svc_do_lock() directly and access arguments through the argp->xdrgen hierarchy. The .pc_argzero field is set to zero because xdrgen decoders fully initialize all fields in argp->xdrgen, making the early defensive memset unnecessary. The remaining argp fields that fall outside the xdrgen structures are cleared explicitly as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 UNSHARE procedureChuck Lever
Now that the share helpers have been decoupled from the NLMv3-specific struct nlm_args and file_lock initialization has been hoisted into the procedure handler, the NLMv4 UNSHARE procedure can be converted to use xdrgen-generated XDR functions. Replace the NLMPROC4_UNSHARE entry in the nlm_procedures4 array with an entry that uses xdrgen-built XDR decoders and encoders. The procedure handler is updated to use the new wrapper structures (nlm4_shareargs_wrapper and nlm4_shareres_wrapper) and access arguments through the argp->xdrgen hierarchy. The .pc_argzero field is set to zero because xdrgen decoders fully initialize all fields in argp->xdrgen, making the early defensive memset unnecessary. The remaining argp fields that fall outside the xdrgen structures are cleared explicitly as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 SHARE procedureChuck Lever
Now that the share helpers have been decoupled from the NLMv3-specific struct nlm_args and file_lock initialization has been hoisted into the procedure handler, the NLMv4 SHARE procedure can be converted to use xdrgen-generated XDR functions. Replace the NLMPROC4_SHARE entry in the nlm_procedures4 array with an entry that uses xdrgen-built XDR decoders and encoders. The procedure handler is updated to use the new wrapper structures (nlm4_shareargs_wrapper and nlm4_shareres_wrapper) and access arguments through the argp->xdrgen hierarchy. The .pc_argzero field is set to zero because xdrgen decoders fully initialize all fields in argp->xdrgen, making the early defensive memset unnecessary. The remaining argp fields that fall outside the xdrgen structures are cleared explicitly as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Prepare share helpers for xdrgen conversionChuck Lever
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-29lockd: Hoist file_lock init out of nlm4svc_decode_shareargs()Chuck Lever
The xdrgen-generated XDR decoders cannot initialize the file_lock structure because it is an internal kernel type, not part of the wire protocol. To prepare for converting SHARE and UNSHARE procedures to use xdrgen, the file_lock initialization must be moved from nlm4svc_decode_shareargs() into the procedure handlers themselves. This change removes one more dependency on the "struct nlm_lock::fl" field in fs/lockd/xdr4.c, allowing the XDR decoder to focus solely on unmarshalling wire data. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Convert server-side undefined procedures to xdrgenChuck Lever
The NLMv4 protocol defines several procedure slots that are not implemented. These undefined procedures need proper handling to return rpc_proc_unavail to clients that mistakenly invoke them. This patch converts the three undefined procedure entries (slots 17, 18, and 19) to use xdrgen functions nlm4_svc_decode_void and nlm4_svc_encode_void. The nlm4svc_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 correctly set to zero since no arguments or results are processed. The pc_xdrressize field is updated to XDR_void to accurately reflect the response size. This conversion completes the migration of all NLMv4 server-side procedures to use xdrgen-generated XDR functions, improving type safety and eliminating hand-written XDR code. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 SM_NOTIFY procedureChuck Lever
Convert the SM_NOTIFY procedure to use xdrgen functions nlm4_svc_decode_nlm4_notifyargs and nlm4_svc_encode_void. SM_NOTIFY is a private callback from statd to notify lockd when a remote host has rebooted. This patch introduces struct nlm4_notifyargs_wrapper to bridge between the xdrgen-generated nlm4_notifyargs and the nlm_reboot structure expected by nlm_host_rebooted(). The wrapper contains both the xdrgen-decoded arguments and a reboot field for the existing API. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. This change also corrects the pc_xdrressize field, which previously contained a placeholder value. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 GRANTED_RES procedureChuck Lever
Convert the GRANTED_RES procedure to use xdrgen functions nlm4_svc_decode_nlm4_res and nlm4_svc_encode_void. GRANTED_RES is a callback procedure where the client sends granted lock results back to the server after an async GRANTED request. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. This change also corrects the pc_xdrressize field, which previously contained a placeholder value. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 UNLOCK_RES procedureChuck Lever
Update the NLMPROC4_UNLOCK_RES entry in nlm_procedures4 to invoke xdrgen-generated XDR functions. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 CANCEL_RES procedureChuck Lever
Convert the CANCEL_RES procedure to use xdrgen functions nlm4_svc_decode_nlm4_res and nlm4_svc_encode_void. CANCEL_RES is a callback procedure where the client sends cancel results back to the server after an async CANCEL request. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. This change also corrects the pc_xdrressize field, which previously contained a placeholder value. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 LOCK_RES procedureChuck Lever
Convert the LOCK_RES procedure to use xdrgen functions nlm4_svc_decode_nlm4_res and nlm4_svc_encode_void. LOCK_RES is a callback procedure where the client sends lock results back to the server after an async LOCK request. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. This change also corrects the pc_xdrressize field, which previously contained a placeholder value. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 TEST_RES procedureChuck Lever
Convert the TEST_RES procedure to use xdrgen functions nlm4_svc_decode_nlm4_testres and nlm4_svc_encode_void. TEST_RES is a callback procedure where the client sends test lock results back to the server after an async TEST request. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. This change also corrects the pc_xdrressize field, which previously contained a placeholder value. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 GRANTED_MSG procedureChuck Lever
Convert the GRANTED_MSG procedure to use xdrgen functions nlm4_svc_decode_nlm4_testargs and nlm4_svc_encode_void. The procedure handler uses the nlm4_testargs_wrapper structure that bridges between xdrgen types and the legacy nlm_lock representation. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. The NLM async callback mechanism uses client-side functions which continue to take legacy struct nlm_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-03-29lockd: Use xdrgen XDR functions for the NLMv4 UNLOCK_MSG procedureChuck Lever
Convert the UNLOCK_MSG procedure to use xdrgen functions nlm4_svc_decode_nlm4_unlockargs and nlm4_svc_encode_void. The procedure handler uses the nlm4_unlockargs_wrapper structure that bridges between xdrgen types and the legacy nlm_lock representation. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments, making the early defensive memset unnecessary. The NLM async callback mechanism uses client-side functions which continue to take legacy struct nlm_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-03-29lockd: Use xdrgen XDR functions for the NLMv4 CANCEL_MSG procedureChuck Lever
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 nlm4_svc_decode_nlm4_cancargs and nlm4_svc_encode_void generated from the NLM version 4 protocol specification. The procedure handler uses xdrgen types through the nlm4_cancargs_wrapper structure that bridges between generated code and the legacy nlm_lock representation. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. The NLM async callback mechanism uses client-side functions which continue to take legacy results like struct nlm_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-03-29lockd: Use xdrgen XDR functions for the NLMv4 LOCK_MSG procedureChuck Lever
The LOCK_MSG procedure is part of NLM's asynchronous lock request flow, where clients send LOCK_MSG to request locks that may block. This patch continues the xdrgen migration by converting LOCK_MSG to use generated XDR functions. This patch converts the LOCK_MSG procedure to use xdrgen functions nlm4_svc_decode_nlm4_lockargs and nlm4_svc_encode_void generated from the NLM version 4 protocol specification. The procedure handler uses xdrgen types through the nlm4_lockargs_wrapper structure that bridges between generated code and the legacy nlm_lock representation. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. The NLM async callback mechanism uses client-side functions which continue to take legacy results like struct nlm_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-03-29lockd: Use xdrgen XDR functions for the NLMv4 TEST_MSG procedureChuck Lever
The TEST_MSG procedure is part of NLM's asynchronous lock request flow, where clients send TEST_MSG to check lock availability without blocking. This patch continues the xdrgen migration by converting TEST_MSG to use generated XDR functions. This patch converts the TEST_MSG procedure to use xdrgen functions nlm4_svc_decode_nlm4_testargs and nlm4_svc_encode_void generated from the NLM version 4 protocol specification. The procedure handler uses xdrgen types through the nlm4_testargs_wrapper structure that bridges between generated code and the legacy nlm_lock representation. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. The NLM async callback mechanism uses client-side functions which continue to take legacy results like struct nlm_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-03-29lockd: Refactor nlm4svc_callback()Chuck Lever
The xdrgen-based XDR conversion requires each RPC procedure to handle its own argument extraction, since xdrgen generates distinct argument structures for each procedure rather than using a single shared type. This patch moves the host lookup logic from nlm4svc_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 nlm4svc_callback(), which is reduced to a simpler helper that only dispatches the callback. This refactoring enables the subsequent xdrgen conversion patches by establishing the pattern where each procedure handles its own argument extraction, while preserving existing callback behavior unchanged. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 GRANTED procedureChuck Lever
The NLM GRANTED procedure provides server-to-client notification when a previously blocked lock request has been granted, completing the asynchronous lock request flow. This patch completes the xdrgen migration for basic NLMv4 procedures by converting the GRANTED procedure, the final one in this conversion series. This patch converts the GRANTED procedure to use xdrgen functions nlm4_svc_decode_nlm4_testargs and nlm4_svc_encode_nlm4_res generated from the NLM version 4 protocol specification. The procedure handler uses xdrgen types through a wrapper structure that bridges between generated code and the legacy nlm_lock representation still used by the core lockd logic. A new helper function nlm4_lock_to_nlm_lock() is introduced to convert xdrgen nlm4_lock structures to the legacy nlm_lock format. This helper complements the existing nlm4svc_lookup_host() and nlm4svc_lookup_file() functions used throughout this series. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 UNLOCK procedureChuck Lever
UNLOCK releases locks acquired via the LOCK procedure. Conversion of TEST, LOCK, CANCEL, and UNLOCK provides the complete set of lock lifecycle operations required by the NLM protocol, enabling clients to test for conflicts, acquire locks, abort pending lock requests, and release held locks. The procedure handler converts arguments from the xdrgen-generated nlm4_unlockargs structure to the legacy nlm_lock representation through nlm4_unlockargs_wrapper. This maintains compatibility with core lockd logic while using XDR decoders and encoders generated from the NLMv4 protocol specification. The original __nlm4svc_proc_unlock function is retained because the asynchronous callback path invokes it directly, bypassing the RPC dispatch mechanism. The pc_argzero field is zero because nlm4_svc_decode_nlm4_unlockargs initializes all fields in argp->xdrgen, eliminating the need for early memset of the argument buffer. Remaining argp fields outside the xdrgen structure are cleared explicitly where needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 CANCEL procedureChuck Lever
The NLM CANCEL procedure allows clients to cancel outstanding blocked lock requests, completing the set of lock-related operations that share common lookup patterns. This patch continues the xdrgen migration by converting the CANCEL procedure, leveraging the same nlm4svc_lookup_host() and nlm4svc_lookup_file() helpers established in the TEST procedure conversion to maintain consistency across the series. This patch converts the CANCEL procedure to use xdrgen functions nlm4_svc_decode_nlm4_cancargs and nlm4_svc_encode_nlm4_res generated from the NLM version 4 protocol specification. The procedure handler uses xdrgen types through a wrapper structure that bridges between generated code and the legacy nlm_lock representation still used by the core lockd logic. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 LOCK procedureChuck Lever
Replace legacy XDR handling in the LOCK procedure with xdrgen- generated functions nlm4_svc_decode_lockargs and nlm4_svc_encode_res. The new nlm4svc_do_lock() handler replaces __nlm4svc_proc_lock() at the NLMPROC4_LOCK entry point. Wrapper structures bridge xdrgen types to the legacy nlm_lock representation used by core lockd. The nlm4svc_lookup_host() and nlm4svc_lookup_file() helpers from the TEST conversion handle host and file lookup. The pc_argzero field is set to zero: xdrgen-generated decoders initialize all fields in argp->xdrgen, so a defensive memset is unnecessary. The wrapper's cookie and lock fields are cleared by nlm4svc_do_lock() before use. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 TEST procedureChuck Lever
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. By introducing the helper functions nlm4svc_lookup_host() and nlm4svc_lookup_file() now, we establish reusable patterns for subsequent conversions in this series. This patch converts the TEST procedure to use xdrgen functions nlm4_svc_decode_testargs and nlm4_svc_encode_testres generated from the NLM version 4 protocol specification. The procedure handler is rewritten to use xdrgen types through wrapper structures that bridge between generated code and the legacy nlm_lock representation still used by the core lockd logic. TEST_MSG is to be converted in a subsequent patch. The pc_argzero field is set to zero because xdrgen decoders reliably initialize all arguments in the argp->xdrgen field, making the early defensive memset unnecessary. Remaining argp fields are cleared as needed. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Use xdrgen XDR functions for the NLMv4 NULL procedureChuck Lever
Hand-written XDR encoders and decoders are difficult to maintain and can inadvertently diverge from protocol specifications. By migrating to xdrgen-generated code, we improve type safety and ensure the implementation exactly matches the NLM version 4 protocol specification. This patch begins the migration by converting the NULL procedure to use nlm4_svc_decode_void and nlm4_svc_encode_void generated from Documentation/sunrpc/xdr/nlm4.x. The NULL procedure is straightforward as it has no arguments or results, making it an ideal starting point for this series. The pc_xdrressize field is set to XDR_void (zero) to reflect that this procedure returns no XDR-encoded data. The argzero field is also set to zero since xdrgen decoders reliably initialize all decoded values. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29Documentation: Add the RPC language description of NLM version 4Chuck Lever
In order to generate source code to encode and decode NLMv4 protocol elements, include a copy of the RPC language description of NLMv4 for xdrgen to process. The language description is an amalgam of RFC 1813 and the Open Group's XNFS specification: https://pubs.opengroup.org/onlinepubs/9629799/chap10.htm The C code committed here was generated from the new nlm4.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. 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>
2026-03-29NFSD: Enforce timeout on layout recall and integrate lease manager fencingDai Ngo
When a layout conflict triggers a recall, enforcing a timeout is necessary to prevent excessive nfsd threads from being blocked in __break_lease ensuring the server continues servicing incoming requests efficiently. This patch introduces a new function to lease_manager_operations: lm_breaker_timedout: Invoked when a lease recall times out and is about to be disposed of. This function enables the lease manager to inform the caller whether the file_lease should remain on the flc_list or be disposed of. For the NFSD lease manager, this function now handles layout recall timeouts. If the layout type supports fencing and the client has not been fenced, a fence operation is triggered to prevent the client from accessing the block device. While the fencing operation is in progress, the conflicting file_lease remains on the flc_list until fencing is complete. This guarantees that no other clients can access the file, and the client with exclusive access is properly blocked before disposal. Signed-off-by: Dai Ngo <dai.ngo@oracle.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29NFSD: fix nfs4_file access extra count in nfsd4_add_rdaccess_to_wrdelegDai Ngo
In nfsd4_add_rdaccess_to_wrdeleg, if fp->fi_fds[O_RDONLY] is already set by another thread, __nfs4_file_get_access should not be called to increment the nfs4_file access count since that was already done by the thread that added READ access to the file. The extra fi_access count in nfs4_file can prevent the corresponding nfsd_file from being freed. When stopping nfs-server service, these extra access counts trigger a BUG in kmem_cache_destroy() that shows nfsd_file object remaining on __kmem_cache_shutdown. This problem can be reproduced by running the Git project's test suite over NFS. Fixes: 8072e34e1387 ("nfsd: fix nfsd_file reference leak in nfsd4_add_rdaccess_to_wrdeleg()") Signed-off-by: Dai Ngo <dai.ngo@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: Fix compilation error (`make W=1`) when dprintk() is no-opAndy Shevchenko
Clang compiler is not happy about set but unused variables: .../flexfilelayout/flexfilelayoutdev.c:56:9: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable] .../flexfilelayout/flexfilelayout.c:1505:6: error: variable 'err' set but not used [-Werror,-Wunused-but-set-variable] .../nfs4proc.c:9244:12: error: variable 'ptr' set but not used [-Werror,-Wunused-but-set-variable] Fix these by forwarding parameters of dprintk() to no_printk(). The positive side-effect is a format-string checker enabled even for the cases when dprintk() is no-op. Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver") Fixes: fc931582c260 ("nfs41: create_session operation") Acked-by: Geert Uytterhoeven <geert+renesas@glider.be> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29sunrpc: Kill RPC_IFDEBUG()Andy Shevchenko
RPC_IFDEBUG() is used in only two places. In one the user of the definition is guarded by ifdeffery, in the second one it's implied due to dprintk() usage. Kill the macro and move the ifdeffery to the regular condition with the variable defined inside, while in the second case add the same conditional and move the respective code there. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29nfs/blocklayout: Fix compilation error (`make W=1`) in bl_write_pagelist()Andy Shevchenko
Clang compiler is not happy about set but unused variable (when dprintk() is no-op): .../blocklayout/blocklayout.c:384:9: error: variable 'count' set but not used [-Werror,-Wunused-but-set-variable] Remove a leftover from the previous cleanup. Fixes: 3a6fd1f004fc ("pnfs/blocklayout: remove read-modify-write handling in bl_write_pagelist") Acked-by: Anna Schumaker <anna.schumkaer@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-03-29lockd: Relocate svc_version definitions to XDR layerChuck Lever
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>