From: Chuck Lever <cel@kernel.org>
To: Al Viro <viro@zeniv.linux.org.uk>,
Christian Brauner <brauner@kernel.org>, Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org,
linux-xfs@vger.kernel.org, linux-cifs@vger.kernel.org,
linux-nfs@vger.kernel.org, linux-api@vger.kernel.org,
linux-f2fs-devel@lists.sourceforge.net,
hirofumi@mail.parknet.co.jp, linkinjeon@kernel.org,
sj1557.seo@samsung.com, yuezhang.mo@sony.com,
almaz.alexandrovich@paragon-software.com, slava@dubeyko.com,
glaubitz@physik.fu-berlin.de, frank.li@vivo.com, tytso@mit.edu,
adilger.kernel@dilger.ca, cem@kernel.org, sfrench@samba.org,
pc@manguebit.org, ronniesahlberg@gmail.com,
sprasad@microsoft.com, trondmy@kernel.org, anna@kernel.org,
jaegeuk@kernel.org, chao@kernel.org, hansg@kernel.org,
senozhatsky@chromium.org, Chuck Lever <chuck.lever@oracle.com>,
Roland Mainz <roland.mainz@nrubsig.org>
Subject: [PATCH v12 13/15] nfsd: Report export case-folding via NFSv3 PATHCONF
Date: Wed, 29 Apr 2026 14:07:24 -0400 [thread overview]
Message-ID: <20260429-case-sensitivity-v12-13-8057123bebe0@oracle.com> (raw)
In-Reply-To: <20260429-case-sensitivity-v12-0-8057123bebe0@oracle.com>
From: Chuck Lever <chuck.lever@oracle.com>
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.
Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs3proc.c | 36 +++++++++++++++++++++------
fs/nfsd/vfs.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/nfsd/vfs.h | 3 +++
fs/nfsd/xdr3.h | 4 +--
4 files changed, 105 insertions(+), 10 deletions(-)
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 42adc5461db0..62ebc65b8af2 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -710,23 +710,43 @@ nfsd3_proc_pathconf(struct svc_rqst *rqstp)
resp->p_name_max = 255; /* at least */
resp->p_no_trunc = 0;
resp->p_chown_restricted = 1;
- resp->p_case_insensitive = 0;
- resp->p_case_preserving = 1;
+ resp->p_case_insensitive = false;
+ resp->p_case_preserving = true;
resp->status = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
if (resp->status == nfs_ok) {
struct super_block *sb = argp->fh.fh_dentry->d_sb;
+ int err;
- /* Note that we don't care for remote fs's here */
- switch (sb->s_magic) {
- case EXT2_SUPER_MAGIC:
+ if (sb->s_magic == EXT2_SUPER_MAGIC) {
resp->p_link_max = EXT2_LINK_MAX;
resp->p_name_max = EXT2_NAME_LEN;
+ }
+
+ err = nfsd_get_case_info(argp->fh.fh_dentry,
+ &resp->p_case_insensitive,
+ &resp->p_case_preserving);
+ /*
+ * RFC 1813 lists NFS3ERR_STALE, NFS3ERR_BADHANDLE, and
+ * NFS3ERR_SERVERFAULT as the only PATHCONF errors.
+ */
+ switch (err) {
+ case 0:
+ case -EOPNOTSUPP:
+ /* Both arms leave the output booleans valid. */
break;
- case MSDOS_SUPER_MAGIC:
- resp->p_case_insensitive = 1;
- resp->p_case_preserving = 0;
+ case -EACCES:
+ case -EPERM:
+ /*
+ * Policy denied the query. Report STALE so the
+ * handle is unusable without implying a server
+ * malfunction.
+ */
+ resp->status = nfserr_stale;
+ break;
+ default:
+ resp->status = nfserr_serverfault;
break;
}
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index eafdf7b7890f..4bd63d8efbf7 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -32,6 +32,7 @@
#include <linux/writeback.h>
#include <linux/security.h>
#include <linux/sunrpc/xdr.h>
+#include <linux/fileattr.h>
#include "xdr3.h"
@@ -2891,3 +2892,74 @@ nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
return err? nfserrno(err) : 0;
}
+
+/**
+ * nfsd_get_case_info - get case sensitivity info for a dentry
+ * @dentry: dentry to query
+ * @case_insensitive: set to true if the filesystem is case-insensitive
+ * @case_preserving: set to true if the filesystem preserves case
+ *
+ * On casefold-capable filesystems the flag lives on the directory,
+ * not on its entries, so for a non-directory @dentry the parent is
+ * queried instead. A directory (including an export root, whose
+ * parent lies outside the export) is queried as-is so its own
+ * contents' lookup behavior is reported.
+ *
+ * When the filesystem does not expose case-folding state (no
+ * ->fileattr_get, or the callback returns -EOPNOTSUPP /
+ * -ENOIOCTLCMD / -ENOTTY / -EINVAL), the outputs are filled with
+ * POSIX defaults (case-sensitive, case-preserving) on the premise
+ * that a filesystem with case-folding support wires up
+ * fileattr_get.
+ *
+ * Other errors propagate unmodified (-EACCES, -EPERM from LSM
+ * hooks; -EIO, -ESTALE, ... from the filesystem). Case-folding
+ * behavior is a property of the exported filesystem, not of the
+ * caller's credentials, so silently substituting defaults would
+ * let the same dentry report POSIX while LSM denies and report
+ * casefolding once LSM allows -- a client could race against
+ * silent name collisions on a case-insensitive export.
+ *
+ * Return: 0 with outputs filled, -EOPNOTSUPP with outputs filled
+ * to POSIX defaults, or a negative errno with outputs
+ * unmodified.
+ */
+int
+nfsd_get_case_info(struct dentry *dentry, bool *case_insensitive,
+ bool *case_preserving)
+{
+ struct file_kattr fa = {};
+ struct dentry *cd;
+ bool put = false;
+ int err;
+
+ if (d_is_dir(dentry)) {
+ cd = dentry;
+ } else {
+ cd = dget_parent(dentry);
+ put = true;
+ }
+ err = vfs_fileattr_get(cd, &fa);
+ if (put)
+ dput(cd);
+ switch (err) {
+ case 0:
+ *case_insensitive = fa.fsx_xflags & FS_XFLAG_CASEFOLD;
+ *case_preserving =
+ !(fa.fsx_xflags & FS_XFLAG_CASENONPRESERVING);
+ return 0;
+ case -EINVAL:
+ case -ENOTTY:
+ case -ENOIOCTLCMD:
+ case -EOPNOTSUPP:
+ /*
+ * Filesystem does not expose case state.
+ * Report POSIX defaults.
+ */
+ *case_insensitive = false;
+ *case_preserving = true;
+ return -EOPNOTSUPP;
+ default:
+ return err;
+ }
+}
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 702a844f2106..e09ea04a51b9 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -156,6 +156,9 @@ __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *,
loff_t *, struct readdir_cd *, nfsd_filldir_t);
__be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *,
struct kstatfs *, int access);
+int nfsd_get_case_info(struct dentry *dentry,
+ bool *case_insensitive,
+ bool *case_preserving);
__be32 nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
struct dentry *dentry, int acc);
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h
index 522067b7fd75..a7c9714b0b0e 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -209,8 +209,8 @@ struct nfsd3_pathconfres {
__u32 p_name_max;
__u32 p_no_trunc;
__u32 p_chown_restricted;
- __u32 p_case_insensitive;
- __u32 p_case_preserving;
+ bool p_case_insensitive;
+ bool p_case_preserving;
};
struct nfsd3_commitres {
--
2.53.0
next prev parent reply other threads:[~2026-04-29 18:08 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-29 18:07 [PATCH v12 00/15] Exposing case folding behavior Chuck Lever
2026-04-29 18:07 ` [PATCH v12 01/15] fs: Move file_kattr initialization to callers Chuck Lever
2026-04-29 18:07 ` [PATCH v12 02/15] fs: Add case sensitivity flags to file_kattr Chuck Lever
2026-04-29 18:07 ` [PATCH v12 03/15] fat: Implement fileattr_get for case sensitivity Chuck Lever
2026-04-29 18:07 ` [PATCH v12 04/15] exfat: " Chuck Lever
2026-04-29 22:00 ` David Timber
2026-04-29 18:07 ` [PATCH v12 05/15] ntfs3: " Chuck Lever
2026-04-29 18:07 ` [PATCH v12 06/15] hfs: " Chuck Lever
2026-04-29 18:07 ` [PATCH v12 07/15] hfsplus: Report case sensitivity in fileattr_get Chuck Lever
2026-04-29 18:07 ` [PATCH v12 08/15] xfs: " Chuck Lever
2026-04-29 18:07 ` [PATCH v12 09/15] cifs: Implement fileattr_get for case sensitivity Chuck Lever
2026-04-29 18:07 ` [PATCH v12 10/15] nfs: " Chuck Lever
2026-04-29 18:07 ` [PATCH v12 11/15] vboxsf: " Chuck Lever
2026-04-29 18:07 ` [PATCH v12 12/15] isofs: " Chuck Lever
2026-04-29 18:07 ` Chuck Lever [this message]
2026-04-29 18:07 ` [PATCH v12 14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING Chuck Lever
2026-04-29 18:07 ` [PATCH v12 15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION Chuck Lever
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260429-case-sensitivity-v12-13-8057123bebe0@oracle.com \
--to=cel@kernel.org \
--cc=adilger.kernel@dilger.ca \
--cc=almaz.alexandrovich@paragon-software.com \
--cc=anna@kernel.org \
--cc=brauner@kernel.org \
--cc=cem@kernel.org \
--cc=chao@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=frank.li@vivo.com \
--cc=glaubitz@physik.fu-berlin.de \
--cc=hansg@kernel.org \
--cc=hirofumi@mail.parknet.co.jp \
--cc=jack@suse.cz \
--cc=jaegeuk@kernel.org \
--cc=linkinjeon@kernel.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
--cc=pc@manguebit.org \
--cc=roland.mainz@nrubsig.org \
--cc=ronniesahlberg@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=sfrench@samba.org \
--cc=sj1557.seo@samsung.com \
--cc=slava@dubeyko.com \
--cc=sprasad@microsoft.com \
--cc=trondmy@kernel.org \
--cc=tytso@mit.edu \
--cc=viro@zeniv.linux.org.uk \
--cc=yuezhang.mo@sony.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox