summaryrefslogtreecommitdiff
path: root/fs/nfsd
AgeCommit message (Collapse)Author
2026-06-18Merge tag 'nfsd-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linuxLinus Torvalds
Pull nfsd updates from Chuck Lever: "Jeff Layton wired up netlink upcalls for the auth.unix.ip and auth.unix.gid caches in SunRPC and the svc_export and nfsd.fh caches in NFSD. The new kernel-user API is more extensible and lays the groundwork for retiring the old pipe interface. The default NFS r/w block size rises to 4MB on hosts with at least 16GB of RAM, reducing per-RPC overhead on fast networks. Smaller machines keep their previously computed default, and the value remains tunable through /proc/fs/nfsd/max_block_size. Chuck Lever converted the server's RPCSEC GSS Kerberos code to the kernel's shared crypto/krb5 library. The conversion retires and removes SunRPC's bespoke implementation of Kerberos v5, but keeps RPCSEC GSS-API. Continuing the xdrgen migration that converted the NLMv4 server XDR layer in v7.1, Chuck Lever converted the NLM version 3 server-side XDR layer from hand-written C to xdrgen-generated code. As with the NLMv4 conversion in v7.1, the goals are improved memory safety, lower maintenance burden, and groundwork for generation of Rust code for this layer instead of C. Chuck Lever fixed an issue where lingering NFSv4 state pins a mounted file system after it is unexported. A new netlink-based mechanism can now release NLM locks and NFSv4 state by client address, by filesystem, and by export. Now an administrator can quiesce an export cleanly before unmounting it. The remaining patches are bug fixes, clean-ups, and minor optimizations, including a batch of memory-leak and use-after-free fixes in the ACL, lockd, and TLS handshake paths, many of them reported by Chris Mason. Sincere thanks to all contributors, reviewers, testers, and bug reporters who participated in the v7.2 NFSD development cycle" * tag 'nfsd-7.2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: (106 commits) svcrdma: wake sq waiters when the transport closes nfsd: reset write verifier on deferred writeback errors nfsd: avoid leaking pre-allocated openowner on unconfirmed retry race sunrpc: wait for in-flight TLS handshake callback when cancel loses race sunrpc: pin svc_xprt across the asynchronous TLS handshake callback nfsd: fix posix_acl leak on SETACL decode failure nfsd: fix posix_acl leak and ignored error in nfsd4_create_file nfsd: check get_user() return when reading princhashlen nfsd: fix inverted cp_ttl check in async copy reaper nfsd: fix dead ACL conflict guard in nfsd4_create NFSD: Fix SECINFO_NO_NAME decode error cleanup sunrpc: harden rq_procinfo lifecycle to prevent double-free SUNRPC: Return an error from xdr_buf_to_bvec() on overflow SUNRPC: Bound-check xdr_buf_to_bvec() stores before writing nfsd: release layout stid on setlease failure lockd: Avoid hashing uninitialized bytes in nlm4svc_lookup_file() lockd: Plug nlm_file refcount leak on cached nlm_do_fopen() failure lockd: Plug nlm_file leak when nlm_do_fopen() fails Revert "NFSD: Defer sub-object cleanup in export put callbacks" Revert "svcrdma: Use contiguous pages for RDMA Read sink buffers" ...
2026-06-15Merge tag 'vfs-7.2-rc1.misc' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull misc vfs updates from Christian Brauner: "Features: - Reduce pipe->mutex contention by pre-allocating pages outside the lock in anon_pipe_write(). anon_pipe_write() called alloc_page() once per page while holding pipe->mutex. The allocation can sleep doing direct reclaim and runs memcg charging, which extends the critical section and stalls any concurrent reader on the same mutex. Now up to 8 pages are pre-allocated before the mutex is taken, leftovers are recycled into the per-pipe tmp_page[] cache before unlock, and any remainder is released after unlock, keeping the allocator out of the critical section on both sides. On a writers x readers sweep with 64KB writes against a 1 MB pipe throughput improves 6-28% and average write latency drops 5-22%; under memory pressure - when the cost of holding the mutex across reclaim is highest - throughput improves 21-48% and latency drops 17-33%. The microbenchmark is added to selftests. - uaccess/sockptr: fix the ignored_trailing logic in copy_struct_to_user() to behave as documented and the usize check in copy_struct_from_sockptr() for user pointers, and add copy_struct_{from,to}_bounce_buffer() and copy_struct_to_sockptr() helpers for upcoming users (IPPROTO_SMBDIRECT, IPPROTO_QUIC). - bpf: add a sleepable bpf_real_inode() kfunc that resolves the real inode backing a dentry via d_real_inode(). On overlayfs the inode attached to the dentry doesn't carry the underlying device information; this is used by the filesystem restriction BPF program that was merged into systemd. - docs: add guidelines for submitting new filesystems, motivated by the maintenance burden abandoned and untestable filesystems impose on VFS developers, blocking infrastructure work like folio conversions and iomap migration. Fixes: - libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() and drop the now-redundant assignments in callers. This began as a one-line dma-buf fix for a path_noexec() warning; a pseudo filesystem has no reason not to set SB_I_NOEXEC. All init_pseudo() callers were audited: the only visible effect is on dma-buf where SB_I_NOEXEC silences the warning. - Handle set_blocksize() failures in legacy filesystems (bfs, hpfs, qnx4, jfs, befs, affs, isofs, minix, ntfs3, omfs). Mounting a device with a sector size > PAGE_SIZE crashed roughly half of them; the rest had the same missing error handling pattern. Plus a follow-up releasing the superblock buffer_head when setting the minix v3 block size fails. - mount: honour SB_NOUSER in the new mount API. - fs/fcntl: fix a SOFTIRQ-unsafe lock order in fasync signaling by switching the process-group paths of send_sigio() and send_sigurg() from read_lock(&tasklist_lock) to RCU, matching the single-PID path. - vfs: add an FS_USERNS_DELEGATABLE flag and set it for NFS, fixing delegated NFS mounts (fsopen() in a container with the mount performed by a privileged daemon) that broke when non-init s_user_ns was tied to FS_USERNS_MOUNT. - selftests/namespaces: fix a hang in nsid_test where an unreaped grandchild kept the TAP pipe write-end open, a waitpid(-1) race in listns_efault_test, and a false FAIL on kernels without listns() where the tests should SKIP. - filelock: fix the break_lease() stub signature for CONFIG_FILE_LOCKING=n. - init/initramfs_test: wait for the async initramfs unpacking before running; the test and do_populate_rootfs() share the parser state. - fs/coredump: reduce redundant log noise in validate_coredump_safety(). - iomap: pass the correct length to fserror_report_io() in __iomap_write_begin(). - backing-file: fix the backing_file_open() kerneldoc. Cleanups: - initramfs: refactor the cpio hex header parsing to use hex2bin() instead of the hand-rolled simple_strntoul() which is reverted, and extend the initramfs KUnit tests to cover header fields with 0x prefixes. - Replace __get_free_pages() and friends with kmalloc()/kzalloc() across quota, proc, ocfs2/dlm, nilfs2, nfs, nfsd, libfs, jfs, jbd2, isofs, fuse, select, namespace, configfs, binfmt_misc, bfs, and the do_mounts init code - part of the larger work of replacing page allocator calls with kmalloc(). - Use clear_and_wake_up_bit() in unlock_buffer() and journal_end_buffer_io_sync() instead of open-coding the sequence. - Drop unused VFS exports: unexport drop_super_exclusive(), remove start_removing_user_path_at(), and fold __start_removing_path() into start_removing_path(). - fs/read_write: narrow the __kernel_write() export with EXPORT_SYMBOL_FOR_MODULES(). - vfs: uapi: retire octal and hex constants in favor of (1 << n) for the O_ flags. Finding a free bit for a new flag across the architectures was needlessly hard with the mixed bases. - dcache: add extra sanity checks of dead dentries in dentry_free() via a new DENTRY_WARN_ONCE() that also prints d_flags. - iov_iter: use kmemdup_array() in dup_iter() to harden the allocation against multiplication overflow. - fs/pipe: write to ->poll_usage only once. - vfs: remove an always-taken if-branch in find_next_fd(). - dcache: use kmalloc_flex() for struct external_name in __d_alloc(). - namei: use QSTR() instead of QSTR_INIT() in path_pts(). - sync_file_range: delete dead S_ISLNK code. - Comment fixes: retire a stale comment in fget_task_next() and fix assorted spelling mistakes" * tag 'vfs-7.2-rc1.misc' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (73 commits) backing-file: fix backing_file_open() kerneldoc parameter iomap: pass the correct len to fserror_report_io in __iomap_write_begin vfs: add FS_USERNS_DELEGATABLE flag and set it for NFS filelock: fix break_lease() stub signature for CONFIG_FILE_LOCKING=n vfs: uapi: retire octal and hex numbers in favor of (1 << n) for O_ flags bpf: add bpf_real_inode() kfunc fs/read_write: Do not export __kernel_write() to the entire world libfs: drop redundant SB_I_NOEXEC/SB_I_NODEV in init_pseudo() callers libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() mount: honour SB_NOUSER in the new mount API fs/fcntl: fix SOFTIRQ-unsafe lock order in fasync signaling selftests/pipe: add pipe_bench microbenchmark fs/pipe: pre-allocate pages outside pipe->mutex in anon_pipe_write fs: retire stale comment in fget_task_next() fs: fix spelling mistakes in comment bfs: replace get_zeroed_page() with kzalloc() binfmt_misc: replace __get_free_page() with kmalloc() configfs: replace __get_free_pages() with kzalloc() fs/namespace: use __getname() to allocate mntpath buffer fs/select: replace __get_free_page() with kmalloc() ...
2026-06-15Merge tag 'vfs-7.2-rc1.casefold' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs casefolding updates from Christian Brauner: "This exposes the case folding behavior of local filesystems so that file servers - nfsd, ksmbd, and user space file servers - can report the actual behavior to clients instead of guessing. Filesystems report case-insensitive and case-nonpreserving behavior via new file_kattr flags in their fileattr_get implementations. fat, exfat, ntfs3, hfs, hfsplus, xfs, cifs, nfs, vboxsf, and isofs are wired up. Local filesystems that are not explicitly handled default to the usual POSIX behavior of case-sensitive and case-preserving. nfsd uses this to report case folding via NFSv3 PATHCONF and to implement the NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING attributes - both have been part of the NFS protocols for decades to support clients on non-POSIX systems - and ksmbd reports it via FS_ATTRIBUTE_INFORMATION. Exposing the information through the fileattr uapi covers user space file servers. The immediate motivation is interoperability: Windows NFS clients hard-require servers to report case-insensitivity for Win32 applications to work correctly, and a client that knows the server is case-insensitive can avoid issuing multiple LOOKUP/READDIR requests searching for case variants. The Linux NFS client already grew support for case-insensitive shares years ago in support of the Hammerspace NFS server - negative dentry caching must be disabled (a lookup for "FILE.TXT" failing must not cache a negative entry when "file.txt" exists) and directory change invalidation must drop cached case-folded name variants. Such servers often operate in multi-protocol environments where a single file service instance caters to both NFS and SMB clients, and nfsd needs to report case folding properly to participate as a first-class citizen there. A follow-up series brings fixes for the initial work: the nfsd case-info probe now uses kernel credentials, maps -ESTALE to NFS3ERR_STALE, and has its cost capped across READDIR entries; the nfs client avoids transiently zeroed case capability bits during the probe and skips the pathconf probe when neither field is consumed; the FS_CASEFOLD_FL semantics are clarified in the UAPI header; and the tools UAPI headers are synced" * tag 'vfs-7.2-rc1.casefold' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: (22 commits) nfsd: Cap case-folding probe cost across READDIR entries nfsd: Map -ESTALE from case probe to NFS3ERR_STALE nfsd: Use kernel credentials for case-info probe fs: Clarify FS_CASEFOLD_FL semantics in UAPI header nfs: Skip pathconf probe when neither field is consumed nfs: Avoid transient zeroed case capability bits during probe tools headers UAPI: Sync case-sensitivity flags from linux/fs.h ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING nfsd: Report export case-folding via NFSv3 PATHCONF isofs: Implement fileattr_get for case sensitivity vboxsf: Implement fileattr_get for case sensitivity nfs: Implement fileattr_get for case sensitivity cifs: Implement fileattr_get for case sensitivity xfs: Report case sensitivity in fileattr_get hfsplus: Report case sensitivity in fileattr_get hfs: Implement fileattr_get for case sensitivity ntfs3: Implement fileattr_get for case sensitivity exfat: Implement fileattr_get for case sensitivity fat: Implement fileattr_get for case sensitivity ...
2026-06-15Merge tag 'vfs-7.2-rc1.exportfs' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull exportfs updates from Christian Brauner: "This cleans up the exportfs support for block-style layouts that provide direct block device access: the operations for layout-based block device access are split out of struct export_operations into a separate header, ->commit_blocks() no longer takes a struct iattr argument, and the way support for layout-based block device access is detected is reworked. nfsd's blocklayout code also stops honoring loca_time_modify. This is preparation for supporting export of more than a single device per file system" * tag 'vfs-7.2-rc1.exportfs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: exportfs,nfsd: rework checking for layout-based block device access support exportfs: don't pass struct iattr to ->commit_blocks exportfs: split out the ops for layout-based block device access nfsd/blocklayout: always ignore loca_time_modify
2026-06-09nfsd: reset write verifier on deferred writeback errorsJeff Layton
nfsd_vfs_write() and nfsd_commit() both call filemap_check_wb_err() to detect deferred writeback errors, but neither rotates the server's write verifier (nn->writeverf) when this check fails. Every other durable-storage-failure path in these functions calls commit_reset_write_verifier() before returning an error. The missing rotation means clients holding UNSTABLE write data under the current verifier will COMMIT, receive the unchanged verifier back, and conclude their data is durable — silently dropping data that failed writeback. This violates the UNSTABLE+COMMIT durability contract (RFC 1813 §3.3.7, RFC 8881 §18.32). Add commit_reset_write_verifier() calls at both filemap_check_wb_err() error sites, matching the pattern used by adjacent error paths in the same functions. The helper already filters -EAGAIN and -ESTALE internally, so the calls are unconditionally safe. Reported-by: Chris Mason <clm@meta.com> Fixes: 555dbf1a9aac ("nfsd: Replace use of rwsem with errseq_t") Cc: stable@vger.kernel.org Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: avoid leaking pre-allocated openowner on unconfirmed retry raceJeff Layton
When find_or_alloc_open_stateowner() encounters an unconfirmed owner, it calls release_openowner() and sets oo = NULL. Control then falls through past the `if (oo)` guard -- which would have freed any pre-allocated `new` -- and unconditionally executes `new = alloc_stateowner(...)`. If `new` was already allocated on a prior iteration, the pointer is silently overwritten and the previous allocation (slab object + owner name buffer) is leaked. This requires a race: two NFSv4.0 OPEN threads with the same owner string, where a concurrent thread inserts a new unconfirmed owner into the hash between retry iterations. The window is narrow but repeatable under adversarial conditions. Fix by adding `goto retry` after `oo = NULL` so the already-allocated `new` is reused on the next iteration rather than overwritten. Reported-by: Chris Mason <clm@meta.com> Fixes: 23df17788c62 ("nfsd: perform all find_openstateowner_str calls in the one place.") Cc: stable@vger.kernel.org Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: fix posix_acl leak on SETACL decode failureJeff Layton
nfsaclsvc_decode_setaclargs() and nfs3svc_decode_setaclargs() each call nfs_stream_decode_acl() twice, first for NFS_ACL and then for NFS_DFACL. Each successful call transfers ownership of a freshly allocated posix_acl into argp->acl_access or argp->acl_default. If the first call succeeds but the second fails, the decoder returns false and argp->acl_access is left dangling. ACLPROC2_SETACL.pc_release was wired to nfssvc_release_attrstat and ACLPROC3_SETACL.pc_release was wired to nfs3svc_release_fhandle. Both only call fh_put() and have no knowledge of the ACL fields on argp. The posix_acl_release() pairs sat at the out: labels inside nfsacld_proc_setacl() and nfsd3_proc_setacl(), but svc_process() skips pc_func when pc_decode returns false, so that cleanup is unreachable on decode failure: svc_process_common() pc_decode() /* decode_setaclargs: false */ /* pc_func skipped */ pc_release() /* fh_put only -- ACLs leaked */ The orphaned posix_acl is leaked for the lifetime of the server. Fix by adding nfsaclsvc_release_setacl() and nfs3svc_release_setacl(), which release both argp->acl_access and argp->acl_default in addition to fh_put(), and wiring them as pc_release for their respective SETACL procedures. pc_release runs on every path svc_process() takes after decode, including decode failure, so the posix_acl_release() pairs are removed from the proc functions' out: labels to keep ownership in one place. This matches the existing release_getacl() pattern used by the sibling GETACL procedures. Fixes: a257cdd0e217 ("[PATCH] NFSD: Add server support for NFSv3 ACLs.") Cc: stable@vger.kernel.org Assisted-by: kres:claude-opus-4-7 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: fix posix_acl leak and ignored error in nfsd4_create_fileJeff Layton
nfsd4_create_file() has two bugs in its ACL handling: The return value of nfsd4_acl_to_attr() is silently discarded. When the NFSv4-to-POSIX ACL conversion fails (e.g., -EINVAL for unsupported ACE types), the file is created without any ACL and the client receives NFS4_OK. This violates RFC 7530/8881 which require the server to reject unsupported attributes on CREATE. When start_creating() fails after ACL attributes have been populated in attrs (either via nfsd4_acl_to_attr or via ownership transfer from open->op_dpacl/op_pacl), the function jumps to out_write which skips nfsd_attrs_free(). The posix_acl allocations are leaked. A client can trigger this repeatedly with OPEN(CREATE), ACL attributes, and an invalid filename (e.g., longer than NAME_MAX). Fix both by capturing the nfsd4_acl_to_attr() return value and by changing the early error paths to jump to out instead of out_write. Initialize child to ERR_PTR(-EINVAL) so that end_creating() is safe to call even if start_creating() was never reached. Reported-by: Chris Mason <clm@meta.com> Fixes: 7ab96df840e6 ("VFS/nfsd/cachefiles/ovl: add start_creating() and end_creating()") Cc: stable@vger.kernel.org Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: check get_user() return when reading princhashlenDominik Woźniak
In __cld_pipe_inprogress_downcall(), the get_user() that reads princhashlen from the userspace cld_msg_v2 buffer does not check its return value. A failing copy leaves princhashlen with uninitialised stack contents, which are then used to drive memdup_user() and stored as princhash.len on the resulting reclaim record. The other get_user() calls in this function all check the return; only this one is missed, which is most likely a copy-paste oversight from when v2 upcalls were introduced. Mirror the existing pattern used a few lines above for namelen. namecopy is declared with __free(kfree) so the early return cleans up the already-allocated buffer automatically. Fixes: 6ee95d1c8991 ("nfsd: add support for upcall version 2") Cc: stable@vger.kernel.org Signed-off-by: Dominik Woźniak <stalion@gmail.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: fix inverted cp_ttl check in async copy reaperJeff Layton
nfsd4_async_copy_reaper() is supposed to keep completed async copy state around for NFSD_COPY_INITIAL_TTL (10) laundromat ticks so that OFFLOAD_STATUS can report the result, then reap the state once the countdown expires. The TTL predicate is inverted: `if (--copy->cp_ttl)` is true while ticks remain and false when the counter reaches zero. This causes the copy to be reaped on the very first tick (cp_ttl goes from 10 to 9, which is non-zero) instead of after all 10 ticks elapse. Once reaped, OFFLOAD_STATUS returns NFS4ERR_BAD_STATEID because the copy state has already been freed. Fix by negating the test so that cleanup runs when the TTL expires. Fixes: aa0ebd21df9c ("NFSD: Add nfsd4_copy time-to-live") Cc: stable@vger.kernel.org Reported-by: Chris Mason <clm@meta.com> Assisted-by: kres:claude-opus-4-6 Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: fix dead ACL conflict guard in nfsd4_createJeff Layton
nfsd4_create() steals create->cr_dpacl/cr_pacl into the local nfsd_attrs via the designated initializer, then immediately sets the source pointers to NULL. The subsequent conflict guard tests the already-nilled source fields, making it permanently dead code: if (create->cr_acl) { if (create->cr_dpacl || create->cr_pacl) /* always false */ When a client encodes both FATTR4_WORD0_ACL and FATTR4_WORD2_POSIX_{DEFAULT,ACCESS}_ACL in the same CREATE fattr bitmap, nfsd4_acl_to_attr() overwrites attrs.na_pacl/na_dpacl without releasing the originals, leaking two posix_acl slab objects per request. Repeated requests cause unbounded slab exhaustion. Fix by checking attrs.na_dpacl/na_pacl (the stolen values) instead of the nilled create->cr_dpacl/cr_pacl, matching the correct pattern already used in nfsd4_setattr(). Reported-by: Chris Mason <clm@meta.com> Assisted-by: kres:claude-opus-4-6 Fixes: d2ca50606f5f ("NFSD: Add support for POSIX draft ACLs for file creation") Cc: stable@vger.kernel.org Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09NFSD: Fix SECINFO_NO_NAME decode error cleanupGuannan Wang
nfsd4_decode_secinfo_no_name() currently initializes sin_exp after decoding sin_style. If the XDR stream is truncated, the decoder returns nfserr_bad_xdr before sin_exp is initialized. Since commit 3fdc54646234 ("NFSD: Reduce amount of struct nfsd4_compoundargs that needs clearing"), the inline iops array is not cleared between RPC calls. A failed SECINFO_NO_NAME decode can therefore leave sin_exp holding stale union contents from a previous operation. The error response path still invokes nfsd4_secinfo_no_name_release(), which calls exp_put() on a non-NULL sin_exp. Initialize sin_exp before the first failable decode step, matching nfsd4_decode_secinfo(). Fixes: 3fdc54646234 ("NFSD: Reduce amount of struct nfsd4_compoundargs that needs clearing") Cc: stable@vger.kernel.org Signed-off-by: Guannan Wang <wgnbuaa@gmail.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09SUNRPC: Return an error from xdr_buf_to_bvec() on overflowChuck Lever
xdr_buf_to_bvec() returns a slot count even when the caller's bvec budget is exhausted partway through the xdr_buf. Callers feed that count into iov_iter_bvec() and continue as if the conversion had succeeded, silently sending or writing fewer bytes than the data length declares. For an NFS WRITE the server reports the truncated transfer to the client as full success. The overflow represents an internal invariant violation: a higher layer reserved a bvec budget too small for the xdr_buf it then asked the encoder to convert. That is a server-side fault, not a media I/O failure and not a malformed client argument. Change xdr_buf_to_bvec() to return a signed int and have the overflow label return -ESERVERFAULT. Update the three callers to detect the negative return and fail the request: nfsd_vfs_write() folds the error into host_err, which nfserrno() translates to nfserr_serverfault for the WRITE reply; svc_udp_sendto() and svc_tcp_sendmsg() propagate the error out of the send path. Reported-by: Chris Mason <clm@meta.com> Fixes: 2eb2b9358181 ("SUNRPC: Convert svc_tcp_sendmsg to use bio_vecs directly") Cc: stable@vger.kernel.org Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09nfsd: release layout stid on setlease failureChris Mason
nfs4_alloc_stid() publishes the new stid into cl->cl_stateids via idr_alloc_cyclic() under cl_lock before returning to nfsd4_alloc_layout_stateid(). When nfsd4_layout_setlease() then fails, the error path frees the layout stateid directly with kmem_cache_free() without ever calling idr_remove(), leaving the IDR slot pointing at freed slab memory. Any subsequent IDR walker (states_show, client teardown) dereferences the dangling pointer. The correct teardown for an IDR-published stid is nfs4_put_stid(), which removes the IDR slot under cl_lock, dispatches sc_free (nfsd4_free_layout_stateid) to release ls->ls_file via nfsd4_close_layout(), and drops the nfs4_file reference in its tail. A second issue blocks that switch: nfsd4_free_layout_stateid() unconditionally inspects ls->ls_fence_work via delayed_work_pending() under ls_lock, but INIT_DELAYED_WORK(&ls->ls_fence_work, ...) currently runs only after the setlease call. On the setlease-failure path the destructor would touch an uninitialized delayed_work. nfsd4_alloc_layout_stateid() nfs4_alloc_stid() /* idr_alloc_cyclic under cl_lock */ nfsd4_layout_setlease() /* fails */ nfs4_put_stid() nfsd4_free_layout_stateid() delayed_work_pending(&ls->ls_fence_work) /* needs INIT */ nfsd4_close_layout() /* nfsd_file_put(ls->ls_file) */ put_nfs4_file() Fix by hoisting the ls_fenced / ls_fence_delay / INIT_DELAYED_WORK initialization above the nfsd4_layout_setlease() call, and replace the manual nfsd_file_put + put_nfs4_file + kmem_cache_free cleanup with a single nfs4_put_stid(stp). Fixes: c5c707f96fc9 ("nfsd: implement pNFS layout recalls") Cc: stable@vger.kernel.org Assisted-by: kres (claude-opus-4-7) Signed-off-by: Chris Mason <clm@meta.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-09Revert "NFSD: Defer sub-object cleanup in export put callbacks"Yang Erkun
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>
2026-06-09NFSD: Increase the default max_block_size to 4MBChuck Lever
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>
2026-06-09NFSD: Close cached file handles when revoking export stateChuck Lever
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>
2026-06-09NFSD: Add NFSD_CMD_UNLOCK_EXPORT netlink commandChuck Lever
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>
2026-06-09NFSD: Track svc_export in nfs4_stidChuck Lever
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>
2026-06-09NFSD: Replace idr_for_each_entry_ul in find_one_sb_stid()Chuck Lever
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>
2026-06-09NFSD: Add NFSD_CMD_UNLOCK_FILESYSTEM netlink commandChuck Lever
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>
2026-06-09NFSD: Add NFSD_CMD_UNLOCK_IP netlink commandChuck Lever
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>
2026-06-09NFSD: Extract revoke_one_stid() utility functionChuck Lever
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>
2026-06-09NFSD: Handle layout stid in nfsd4_drop_revoked_stid()Chuck Lever
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>
2026-06-01NFSD: Put cache get-reqs dump attrs under replyChuck Lever
The new get-reqs dump operations added to sunrpc_cache.yaml and nfsd.yaml place the "requests" nested attribute under dump.request. A netlink dump carries an empty request; its payload travels back in the reply. Because the spec names no reply attributes, the YNL C code generator synthesizes a forward reference to a <op>_rsp struct that is never defined, breaking any consumer of these specs. This first surfaced when Thorsten Leemhuis built tools/net/ynl against -next: nfsd-user.h:746: error: field 'obj' has incomplete type struct nfsd_svc_export_get_reqs_rsp obj ... nfsd-user.h:826: error: field 'obj' has incomplete type struct nfsd_expkey_get_reqs_rsp obj ... nfsd-user.c:1211: error: 'nfsd_svc_export_get_reqs_rsp_parse' undeclared sunrpc_cache.yaml has the same defect in ip-map-get-reqs and unix-gid-get-reqs, but nfsd.yaml errors out first in the Makefile's alphabetical build order and hides the sunrpc failures. These bugs were introduced by incorrect merge conflict resolution. Reported-by: Thorsten Leemhuis <linux@leemhuis.info> Closes: https://lore.kernel.org/linux-nfs/f6a3ca6d-e5cb-4a5c-9af2-8d2b1ce33ef0@leemhuis.info/ Fixes: 1045ccf519ce30 ("sunrpc: add netlink upcall for the auth.unix.ip cache") Tested-by: Thorsten Leemhuis <linux@leemhuis.info> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01nfsd: add NFSD_CMD_CACHE_FLUSH netlink commandJeff Layton
Add a new NFSD_CMD_CACHE_FLUSH generic netlink command that allows userspace to flush the nfsd export caches (svc_export and expkey) without writing to /proc/net/rpc/*/flush. An optional NFSD_A_CACHE_FLUSH_MASK u32 attribute selects which caches to flush (bit 1 = svc_export, bit 2 = expkey). If the attribute is omitted, all nfsd caches are flushed. This is used by exportfs to replace its /proc-based cache_flush() with a netlink equivalent, with /proc fallback for older kernels. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01nfsd: add netlink upcall for the nfsd.fh cacheJeff Layton
Add netlink-based cache upcall support for the expkey (nfsd.fh) cache, following the same pattern as the existing svc_export netlink support. Add expkey to the cache-type enum, a new expkey attribute-set with client, fsidtype, fsid, negative, expiry, and path fields, and the expkey-get-reqs / expkey-set-reqs operations to the nfsd YAML spec and generated headers. Implement nfsd_nl_expkey_get_reqs_dumpit() which snapshots pending expkey cache requests and sends each entry's seqno, client name, fsidtype, and fsid over netlink. Implement nfsd_nl_expkey_set_reqs_doit() which parses expkey cache responses from userspace (client, fsidtype, fsid, expiry, and path or negative flag) and updates the cache via svc_expkey_lookup() / svc_expkey_update(). Wire up the expkey_notify() callback in svc_expkey_cache_template so cache misses trigger NFSD_CMD_CACHE_NOTIFY multicast events with NFSD_CACHE_TYPE_EXPKEY. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01nfsd: add netlink upcall for the svc_export cacheJeff Layton
Add netlink-based cache upcall support for the svc_export (nfsd.export) cache to Documentation/netlink/specs/nfsd.yaml and regenerate the resulting files. Implement nfsd_cache_notify() which sends a NFSD_CMD_CACHE_NOTIFY multicast event to the "exportd" group, carrying the cache type so userspace knows which cache has pending requests. Implement nfsd_nl_svc_export_get_reqs_dumpit() which snapshots pending svc_export cache requests and sends each entry's seqno, client name, and path over netlink. Implement nfsd_nl_svc_export_set_reqs_doit() which parses svc_export cache responses from userspace (client, path, expiry, flags, anon uid/gid, fslocations, uuid, secinfo, xprtsec, fsid, or negative flag) and updates the cache via svc_export_lookup() / svc_export_update(). Wire up the svc_export_notify() callback in svc_export_cache_template so cache misses trigger NFSD_CMD_CACHE_NOTIFY multicast events with NFSD_CACHE_TYPE_SVC_EXPORT. Note that the export-flags and xprtsec-mode enums are organized to match their counterparts in include/uapi/linux/nfsd/export.h. The intent is that future export options will only be added to the netlink headers, which should eliminate the need to keep so much in sync. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01sunrpc: rename sunrpc_cache_pipe_upcall_timeout()Jeff Layton
This function doesn't have anything to do with a timeout. The only difference is that it warns if there are no listeners. Rename it to sunrpc_cache_upcall_warn(). Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01sunrpc: rename sunrpc_cache_pipe_upcall() to sunrpc_cache_upcall()Jeff Layton
Since it will soon also send an upcall via netlink, if configured. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01nfsd: move struct nfsd_genl_rqstp to nfsctl.cJeff Layton
It's not used outside of that file. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01NFSD: Fix delegation reference leak in nfsd4_revoke_statesChuck Lever
When revoking delegation state, nfsd4_revoke_states() takes an extra reference on the stid before calling unhash_delegation_locked(). If unhash_delegation_locked() returns false (the delegation was already unhashed by a concurrent path), dp is set to NULL and revoke_delegation() is skipped, but the extra reference is never released. Each occurrence permanently pins the stid in memory. The leaked reference also prevents nfs4_put_stid() from decrementing cl_admin_revoked, leaving the counter permanently inflated. Drop the extra reference in the failure path. Fixes: 8dd91e8d31fe ("nfsd: fix race between laundromat and free_stateid") Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-06-01Merge remote-tracking branches 'vfs/vfs-7.2.casefold', ↵Chuck Lever
'vfs/vfs-7.2.directory.delegations' and 'vfs/vfs-7.2.exportfs' into vfs-7.2-merge
2026-05-27NFSD: replace __get_free_page() with kmalloc() in nfsd_buffered_readdir()Mike Rapoport (Microsoft)
nfsd_buffered_readdir() allocates a staging buffer with __get_free_page(). kmalloc() is a better API for such use and it also provides better scalability and more debugging possibilities. Replace use of __get_free_page() with kmalloc(). Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Link: https://patch.msgid.link/20260523-b4-fs-v1-7-275e36a83f0e@kernel.org Acked-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-05-26Merge tag 'nfsd-7.1-2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux Pull nfsd fixes from Chuck Lever: "Regressions: - Tighten bounds checking for sunrpc cache hash tables - Don't report key material in the ftrace log Stable fix: - Fix lockd's implementation of the NLM TEST procedure" * tag 'nfsd-7.1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: lockd: fix TEST handling when not all permissions are available. NFSD: Report whether fh_key was actually updated sunrpc: prevent out-of-bounds read in __cache_seq_start()
2026-05-21NFSD: Report whether fh_key was actually updatedChuck Lever
The nfsd_ctl_fh_key_set tracepoint was introduced to capture operator activity on the filehandle signing key. Earlier revisions logged the key bytes verbatim; the version that landed hashes the 16 key bytes through crc32_le and stores the result. CRC32 is a linear projection of its input rather than a one-way function, and truncating any hash of fixed-size secret material leaves the key recoverable under offline brute force when the threat model includes an attacker with access to the trace ring. The operational question the fingerprint was meant to answer is whether a NFSD_CMD_THREADS_SET call that carries an NFSD_A_SERVER_FH_KEY attribute actually replaced the active key or re-installed the value already in place. Answer that question directly: compare the incoming key bytes against the current nn->fh_key inside nfsd_nl_fh_key_set() and surface a single bit to the tracepoint. The event now prints "updated" when the stored key changed and "unmodified" otherwise. A first set that fails kmalloc reports "unmodified" because no key was installed. Reported-by: jaeyeong <fin@spl.team> Fixes: 62346217fd72 ("NFSD: Add a key for signing filehandles") Cc: Benjamin Coddington <bcodding@hammerspace.com> Reviewed-by: Benjamin Coddington <bcodding@hammerspace.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-05-15Merge tag 'nfsd-7.1-1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux Pull nfsd fixes from Chuck Lever: "Fixes for this release: - Correctness fix for the new sunrpc cache netlink protocol Marked for stable: - Correctness fixes for delegated attributes - Prevent an infinite loop when revoking layouts" * tag 'nfsd-7.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux: NFSD: Fix infinite loop in layout state revocation sunrpc: start cache request seqno at 1 to fix netlink GET_REQS nfsd: update mtime/ctime on COPY in presence of delegated attributes nfsd: update mtime/ctime on CLONE in presense of delegated attributes nfsd: fix file change detection in CB_GETATTR nfsd: fix GET_DIR_DELEGATION when VFS leases are disabled
2026-05-15nfsd: Cap case-folding probe cost across READDIR entriesChuck Lever
NFSv4 READDIR carries a per-entry attrmask. When the attrmask includes FATTR4_CASE_INSENSITIVE or FATTR4_CASE_PRESERVING, nfsd4_encode_fattr4() resolves each non-directory child's case attributes by calling nfsd_get_case_info(), which dget_parent()s back to the directory being read and re-runs the cred swap and LSM probe per child. The encoder amplifies a single answer into one prepare_kernel_cred() allocation, two LSM hooks, and one put_cred() RCU callback for every non-directory entry. No mainstream NFSv4 client has been observed to populate a READDIR attrmask with these attributes; the Linux client queries them only via SERVER_CAPS at mount time. The exposure is therefore to test clients exploring corner cases and to hostile clients that submit an attrmask designed to multiply server work by rd_dircount. Probe the directory being read once and cache the result on struct nfsd4_readdir for use by every non-directory child. The probe targets the readdir filehandle's dentry, which is held for the duration of the request, rather than dget_parent() of a child's locklessly-acquired dentry; the latter could be moved out of the directory by a concurrent rename and report attributes from an unrelated parent. Directory entries continue to be queried individually, because casefold-capable filesystems (ext4, f2fs) report case state per directory. The other callers of nfsd4_encode_fattr4() (single GETATTR, the buffer wrapper) pass NULL for the cache pointer and behave as before. Reported-by: sashiko-bot <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com?part=14 Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260515153515.362266-8-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-15nfsd: Map -ESTALE from case probe to NFS3ERR_STALEChuck Lever
The PATHCONF switch in nfsd3_proc_pathconf() recognizes -EOPNOTSUPP (filesystem does not expose case state) and maps -EACCES / -EPERM to nfserr_stale, but lets every other errno fall through to nfserr_serverfault. -ESTALE escapes the same way even though RFC 1813 lists NFS3ERR_STALE as a permitted PATHCONF status, so a probe of an NFS-backed re-export whose parent dentry has been invalidated returns SERVERFAULT and tells the client the server is broken when the handle itself simply went stale. Add an explicit -ESTALE arm that maps to nfserr_stale. Fixes: a8de9c3b40e4 ("nfsd: Report export case-folding via NFSv3 PATHCONF") Reported-by: sashiko-bot <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com?part=13 Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260515153515.362266-7-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-15nfsd: Use kernel credentials for case-info probeChuck Lever
nfsd_get_case_info() takes prepare_creds() and overrides fsuid/fsgid to GLOBAL_ROOT, intending to escape per-client policy on the parent directory. prepare_creds() copies the calling task's full credential, including the LSM security label, so only the DAC identity is neutralized. With labeled NFS, where the active LSM context has been mapped to the client, security_inode_file_getattr() can still deny the probe with -EACCES even though the case-folding property the caller wants is structural and identical for every client. The docblock already states the intent ("the probe runs with kernel credentials"), which the implementation does not deliver. prepare_kernel_cred(&init_task) constructs a credential from init_task's identity and security label, the kernel's own unconfined context. Use it instead and drop the redundant fsuid/fsgid overrides that init_task already supplies. The probe now matches the docblock, LSM denials on the parent disappear, and the call sites that map an unexpected error to NFS3ERR_SERVERFAULT or fail an NFSv4 GETATTR outright stop seeing -EACCES from this path. Reported-by: sashiko-bot <sashiko-bot@kernel.org> Closes: https://sashiko.dev/#/patchset/20260507-case-sensitivity-v14-0-e62cc8200435@oracle.com?part=14 Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260515153515.362266-6-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVINGChuck Lever
NFSD currently provides NFSv4 clients with hard-coded responses indicating all exported filesystems are case-sensitive and case-preserving. This is incorrect for case-insensitive filesystems and ext4 directories with casefold enabled. Query the underlying filesystem's actual case sensitivity via nfsd_get_case_info() and return accurate values to clients. This supports per-directory settings for filesystems that allow mixing case-sensitive and case-insensitive directories within an export. The helper queries the parent dentry for non-directory filehandles because case-folding is a per-directory property. That resolution has the same corner cases here as for NFSv3 PATHCONF: single-file exports query an unexported parent, disconnected dentries report defaults until reconnected, and hardlinked files track whichever alias the dcache currently holds. Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260507-case-sensitivity-v14-14-e62cc8200435@oracle.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11nfsd: Report export case-folding via NFSv3 PATHCONFChuck Lever
The hard-coded MSDOS_SUPER_MAGIC check in nfsd3_proc_pathconf() only recognizes FAT filesystems as case-insensitive. Modern filesystems like F2FS, exFAT, and CIFS support case-insensitive directories, but NFSv3 clients cannot discover this capability. Query the export's actual case behavior through ->fileattr_get instead. This allows NFSv3 clients to correctly handle case sensitivity for any filesystem that implements the fileattr interface. Filesystems without ->fileattr_get continue to report the default POSIX behavior (case-sensitive, case-preserving). This change depends on the earlier "fat: Implement fileattr_get for case sensitivity" patch in this series, which ensures FAT filesystems report their case behavior correctly via the fileattr interface. Case-folding is a per-directory property, so nfsd_get_case_info() queries the parent dentry for non-directory filehandles. Three inherent corner cases follow: a single-file export's parent lies outside the exported subtree, so the LSM hook evaluates against an unexported directory; a disconnected dentry from fh_verify() has d_parent == itself, so the file's own attributes are reported until the dentry connects; and a hardlinked file resolves through the alias the dcache currently holds, so when the inode is linked into both case-folded and case-sensitive directories the reported value tracks whichever parent is active. These limitations are not addressable without redefining the protocol attribute as per-parent rather than per-object. RFC 1813 restricts PATHCONF errors to NFS3ERR_STALE, NFS3ERR_BADHANDLE, and NFS3ERR_SERVERFAULT. When an LSM hook denies the case-folding query on the parent, NFS3ERR_STALE is the only correct mapping: NFS3ERR_SERVERFAULT misrepresents a working server as broken, and NFS3ERR_BADHANDLE implies a decoding failure that did not occur. A client purging the filehandle on receipt is the desired outcome, since the server has refused to read attributes through it. Substituting POSIX defaults instead would let the same handle report casefold=false now and casefold=true once policy permits, opening a silent name-collision window on case-insensitive exports. Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260507-case-sensitivity-v14-13-e62cc8200435@oracle.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11exportfs,nfsd: rework checking for layout-based block device access supportChristoph Hellwig
Currently NFSD hard codes checking support for block-style layouts. Lift the checks into a file system-helper and provide a exportfs-level helper to implement the typical checks. This prepares for supporting block layout export of multiple devices per file system. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260423181854.743150-5-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11exportfs: don't pass struct iattr to ->commit_blocksChristoph Hellwig
The only thing ->commit_blocks really needs is the new size, with a magic -1 placeholder 0 for "do not change the size" because it only ever extends the size. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260423181854.743150-4-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11exportfs: split out the ops for layout-based block device accessChristoph Hellwig
The support to grant layouts for direct block device access works at a very different layer than the rest of exports. Split the methods for it into a separate struct, and move that into a separate header to better split things out. The pointer to the new operation vector is kept in export_operations to avoid bloating the super_block. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260423181854.743150-3-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-11nfsd/blocklayout: always ignore loca_time_modifyChristoph Hellwig
RFC 8881 Section 18.42 makes it clear that the client provided timestamp is a "may" condition, and clients that want to force a specific timestamp should send a separate SETATTR in the compound. Since commit b82f92d5dd1a ("fs: have setattr_copy handle multigrain timestamps appropriately") the ia_mtime value is ignored by file systems using multi-grain timestamps like XFS, which is the only file system supporting blocklayout exports right now, so make that explicit in NFSD as well. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Link: https://patch.msgid.link/20260423181854.743150-2-cel@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
2026-05-10NFSD: Fix infinite loop in layout state revocationChuck Lever
find_one_sb_stid() skips stids whose sc_status is non-zero, but the SC_TYPE_LAYOUT case in nfsd4_revoke_states() never sets sc_status before calling nfsd4_close_layout(). The retry loop therefore finds the same layout stid on every iteration, hanging the revoker indefinitely. Fixes: 1e33e1414bec ("nfsd: allow layout state to be admin-revoked.") Reported-by: Dai Ngo <dai.ngo@oracle.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Tested-by: Dai Ngo <dai.ngo@oracle.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-05-10nfsd: update mtime/ctime on COPY in presence of delegated attributesOlga Kornievskaia
When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for COPY operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries. Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation") Cc: stable@vger.kernel.org Signed-off-by: Olga Kornievskaia <okorniev@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-05-10nfsd: update mtime/ctime on CLONE in presense of delegated attributesOlga Kornievskaia
When delegated attributes are given on open, the file is opened with NOCMTIME and modifying operations do not update mtime/ctime as to not get out-of-sync with the client's delegated view. However, for CLONE operation, the server should update its view of mtime/ctime and reflect that in any GETATTR queries. Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation") Cc: stable@vger.kernel.org Signed-off-by: Olga Kornievskaia <okorniev@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
2026-05-10nfsd: fix file change detection in CB_GETATTRScott Mayhew
RFC 8881, section 10.4.3 doesn't say anything about caching the file size in the delegation record, nor does it say anything about comparing a cached file size with the size reported by the client in the CB_GETATTR reply for the purpose of determining if the client holds modified data for the file. What section 10.4.3 of RFC 8881 does say is that the server should compare the *current* file size with the size reported by the client holding the delegation in the CB_GETATTR reply, and if they differ to treat it as a modification regardless of the change attribute retrieved via the CB_GETATTR. Doing otherwise would cause the server to believe the client holding the delegation has a modified version of the file, even if the client flushed the modifications to the server prior to the CB_GETATTR. This would have the added side effect of subsequent CB_GETATTRs causing updates to the mtime, ctime, and change attribute even if the client holding the delegation makes no further updates to the file. Modify nfsd4_deleg_getattr_conflict() to obtain the current file size via i_size_read(). Retain the ncf_cur_fsize field, since it's a convenient way to return the file size back to nfsd4_encode_fattr4(), but don't use it for the purpose of detecting file changes. Remove the unnecessary initialization of ncf_cur_fsize in nfs4_open_delegation(). Also, if we recall the delegation (because the client didn't respond to the CB_GETATTR), then skip the logic that checks the nfs4_cb_fattr fields. Fixes: c5967721e106 ("NFSD: handle GETATTR conflict with write delegation") Cc: stable@vger.kernel.org Signed-off-by: Scott Mayhew <smayhew@redhat.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>