* [PATCH v2 0/6] Exposing case folding behavior
@ 2025-12-11 15:21 Chuck Lever
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
` (6 more replies)
0 siblings, 7 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Following on from
https://lore.kernel.org/linux-nfs/20251021-zypressen-bazillus-545a44af57fd@brauner/T/#m0ba197d75b7921d994cf284f3cef3a62abb11aaa
I'm attempting to implement enough support in the Linux VFS to
enable file services like NFSD and ksmbd (and user space
equivalents) to provide the actual status of case folding support
in local file systems. The default behavior for local file systems
not explicitly supported in this series is to reflect the usual
POSIX behaviors:
case-insensitive = false
case-preserving = true
Changes since RFC:
- Use file_getattr instead of statx
- Postpone exposing Unicode version until later
- Support NTFS and ext4 in addition to FAT
- Support NFSv4 fattr4 in addition to NFSv3 PATHCONF
Chuck Lever (6):
fs: Add case sensitivity info to file_kattr
fat: Implement fileattr_get for case sensitivity
ntfs3: Implement fileattr_get for case sensitivity
ext4: Report case sensitivity in fileattr_get
nfsd: Report export case-folding via NFSv3 PATHCONF
nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and
FATTR4_CASE_PRESERVING
fs/ext4/ioctl.c | 12 ++++++++++++
fs/fat/fat.h | 3 +++
fs/fat/file.c | 18 ++++++++++++++++++
fs/fat/namei_msdos.c | 1 +
fs/fat/namei_vfat.c | 1 +
fs/file_attr.c | 31 +++++++++++++++++++++++++++++++
fs/nfsd/nfs3proc.c | 18 ++++++++++--------
fs/nfsd/nfs4xdr.c | 30 ++++++++++++++++++++++++++----
fs/nfsd/vfs.c | 25 +++++++++++++++++++++++++
fs/nfsd/vfs.h | 2 ++
fs/ntfs3/file.c | 27 +++++++++++++++++++++++++++
fs/ntfs3/inode.c | 1 +
fs/ntfs3/namei.c | 2 ++
fs/ntfs3/ntfs_fs.h | 1 +
include/linux/fileattr.h | 23 +++++++++++++++++++++++
15 files changed, 183 insertions(+), 12 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-11 23:41 ` Eric Biggers
2025-12-15 12:37 ` Christian Brauner
2025-12-11 15:21 ` [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity Chuck Lever
` (5 subsequent siblings)
6 siblings, 2 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Enable upper layers such as NFSD to retrieve case sensitivity
information from file systems by adding a case_info field to struct
file_kattr.
Add vfs_get_case_info() as a convenience helper for kernel
consumers. If a filesystem does not provide a fileattr_get hook, it
returns the default POSIX behavior (case-sensitive,
case-preserving), which is correct for the majority of Linux
file systems implementations.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/file_attr.c | 31 +++++++++++++++++++++++++++++++
include/linux/fileattr.h | 23 +++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/fs/file_attr.c b/fs/file_attr.c
index 1dcec88c0680..609e890b5101 100644
--- a/fs/file_attr.c
+++ b/fs/file_attr.c
@@ -94,6 +94,37 @@ int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
}
EXPORT_SYMBOL(vfs_fileattr_get);
+/**
+ * vfs_get_case_info - retrieve case sensitivity info for a filesystem
+ * @dentry: the object to retrieve from
+ * @case_info: pointer to store result
+ *
+ * Call i_op->fileattr_get() to retrieve case sensitivity information.
+ * If the filesystem does not provide a fileattr_get hook, return
+ * the default POSIX behavior (case-sensitive, case-preserving).
+ *
+ * Return: 0 on success, or a negative error on failure.
+ */
+int vfs_get_case_info(struct dentry *dentry, u32 *case_info)
+{
+ struct file_kattr fa = {};
+ int error;
+
+ /* Default: POSIX semantics (case-sensitive, case-preserving) */
+ *case_info = FILEATTR_CASEFOLD_NONE | FILEATTR_CASE_PRESERVING;
+
+ error = vfs_fileattr_get(dentry, &fa);
+ if (error == -ENOIOCTLCMD)
+ return 0;
+ if (error)
+ return error;
+
+ if (fa.case_info)
+ *case_info = fa.case_info;
+ return 0;
+}
+EXPORT_SYMBOL(vfs_get_case_info);
+
static void fileattr_to_file_attr(const struct file_kattr *fa,
struct file_attr *fattr)
{
diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
index f89dcfad3f8f..55674d14f697 100644
--- a/include/linux/fileattr.h
+++ b/include/linux/fileattr.h
@@ -48,11 +48,33 @@ struct file_kattr {
u32 fsx_nextents; /* nextents field value (get) */
u32 fsx_projid; /* project identifier (get/set) */
u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
+ u32 case_info; /* case sensitivity behavior */
/* selectors: */
bool flags_valid:1;
bool fsx_valid:1;
};
+/*
+ * Values for file_kattr.case_info.
+ */
+
+/* File name case is preserved at rest. */
+#define FILEATTR_CASE_PRESERVING 0x80000000
+
+/* Values stored in the low-order byte */
+enum fileattr_case_folding {
+ /* Code points are compared directly with no case folding. */
+ FILEATTR_CASEFOLD_NONE = 0,
+
+ /* ASCII case-insensitive: A-Z are treated as a-z. */
+ FILEATTR_CASEFOLD_ASCII,
+
+ /* Unicode case-insensitive matching. */
+ FILEATTR_CASEFOLD_UNICODE,
+};
+
+#define FILEATTR_CASEFOLD_TYPE 0x000000ff
+
int copy_fsxattr_to_user(const struct file_kattr *fa, struct fsxattr __user *ufa);
void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags);
@@ -75,6 +97,7 @@ static inline bool fileattr_has_fsx(const struct file_kattr *fa)
int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry,
struct file_kattr *fa);
+int vfs_get_case_info(struct dentry *dentry, u32 *case_info);
int ioctl_getflags(struct file *file, unsigned int __user *argp);
int ioctl_setflags(struct file *file, unsigned int __user *argp);
int ioctl_fsgetxattr(struct file *file, void __user *argp);
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-12 4:42 ` OGAWA Hirofumi
2025-12-11 15:21 ` [PATCH v2 3/6] ntfs3: " Chuck Lever
` (4 subsequent siblings)
6 siblings, 1 reply; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Report FAT's case sensitivity behavior via the new file_kattr
case_info field. FAT filesystems are case-insensitive and do not
preserve case at rest (stored names are uppercased).
The case folding type depends on the mount options: when utf8 is
enabled, Unicode case folding is used; otherwise ASCII case folding.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/fat/fat.h | 3 +++
fs/fat/file.c | 18 ++++++++++++++++++
fs/fat/namei_msdos.c | 1 +
fs/fat/namei_vfat.c | 1 +
4 files changed, 23 insertions(+)
diff --git a/fs/fat/fat.h b/fs/fat/fat.h
index d3e426de5f01..38da08d8fec4 100644
--- a/fs/fat/fat.h
+++ b/fs/fat/fat.h
@@ -10,6 +10,8 @@
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
+struct file_kattr;
+
/*
* vfat shortname flags
*/
@@ -407,6 +409,7 @@ extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
extern int fat_getattr(struct mnt_idmap *idmap,
const struct path *path, struct kstat *stat,
u32 request_mask, unsigned int flags);
+extern int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
int datasync);
diff --git a/fs/fat/file.c b/fs/fat/file.c
index 4fc49a614fb8..123f4c1efdf4 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -16,6 +16,7 @@
#include <linux/fsnotify.h>
#include <linux/security.h>
#include <linux/falloc.h>
+#include <linux/fileattr.h>
#include "fat.h"
static long fat_fallocate(struct file *file, int mode,
@@ -395,6 +396,22 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset)
fat_flush_inodes(inode->i_sb, inode, NULL);
}
+int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
+{
+ struct inode *inode = d_inode(dentry);
+ struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
+
+ /*
+ * FAT filesystems do not preserve case: stored names are
+ * uppercased. They are case-insensitive, using either ASCII
+ * or Unicode comparison depending on mount options.
+ */
+ fa->case_info = sbi->options.utf8 ?
+ FILEATTR_CASEFOLD_UNICODE : FILEATTR_CASEFOLD_ASCII;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fat_fileattr_get);
+
int fat_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask, unsigned int flags)
{
@@ -574,5 +591,6 @@ EXPORT_SYMBOL_GPL(fat_setattr);
const struct inode_operations fat_file_inode_operations = {
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .fileattr_get = fat_fileattr_get,
.update_time = fat_update_time,
};
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 0b920ee40a7f..380add5c6c66 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -640,6 +640,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
.rename = msdos_rename,
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .fileattr_get = fat_fileattr_get,
.update_time = fat_update_time,
};
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 5dbc4cbb8fce..6cf513f97afa 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -1180,6 +1180,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
.rename = vfat_rename2,
.setattr = fat_setattr,
.getattr = fat_getattr,
+ .fileattr_get = fat_fileattr_get,
.update_time = fat_update_time,
};
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 3/6] ntfs3: Implement fileattr_get for case sensitivity
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
2025-12-11 15:21 ` [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-11 15:21 ` [PATCH v2 4/6] ext4: Report case sensitivity in fileattr_get Chuck Lever
` (3 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Report NTFS case sensitivity behavior via the new file_kattr
case_info field. NTFS always preserves case at rest.
Case sensitivity depends on mount options: with "nocase", NTFS
performs Unicode case-insensitive matching; otherwise it is
case-sensitive.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/ntfs3/file.c | 27 +++++++++++++++++++++++++++
fs/ntfs3/inode.c | 1 +
fs/ntfs3/namei.c | 2 ++
fs/ntfs3/ntfs_fs.h | 1 +
4 files changed, 31 insertions(+)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index 4c90ec2fa2ea..35892988b788 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -104,6 +104,32 @@ long ntfs_compat_ioctl(struct file *filp, u32 cmd, unsigned long arg)
}
#endif
+/*
+ * ntfs_fileattr_get - inode_operations::fileattr_get
+ */
+int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
+{
+ struct inode *inode = d_inode(dentry);
+ struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
+
+ /* Avoid any operation if inode is bad. */
+ if (unlikely(is_bad_ni(ntfs_i(inode))))
+ return -EINVAL;
+
+ /*
+ * NTFS preserves case. Case sensitivity depends on mount options:
+ * with "nocase" mount option, NTFS is case-insensitive using
+ * Unicode case folding; otherwise it is case-sensitive.
+ */
+ if (sbi->options && sbi->options->nocase)
+ fa->case_info = FILEATTR_CASEFOLD_UNICODE |
+ FILEATTR_CASE_PRESERVING;
+ else
+ fa->case_info = FILEATTR_CASEFOLD_NONE |
+ FILEATTR_CASE_PRESERVING;
+ return 0;
+}
+
/*
* ntfs_getattr - inode_operations::getattr
*/
@@ -1383,6 +1409,7 @@ const struct inode_operations ntfs_file_inode_operations = {
.get_acl = ntfs_get_acl,
.set_acl = ntfs_set_acl,
.fiemap = ntfs_fiemap,
+ .fileattr_get = ntfs_fileattr_get,
};
const struct file_operations ntfs_file_operations = {
diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c
index 3959f23c487a..ecdea6d83980 100644
--- a/fs/ntfs3/inode.c
+++ b/fs/ntfs3/inode.c
@@ -2085,6 +2085,7 @@ const struct inode_operations ntfs_link_inode_operations = {
.get_link = ntfs_get_link,
.setattr = ntfs_setattr,
.listxattr = ntfs_listxattr,
+ .fileattr_get = ntfs_fileattr_get,
};
const struct address_space_operations ntfs_aops = {
diff --git a/fs/ntfs3/namei.c b/fs/ntfs3/namei.c
index 82c8ae56beee..2094e5409e43 100644
--- a/fs/ntfs3/namei.c
+++ b/fs/ntfs3/namei.c
@@ -519,6 +519,7 @@ const struct inode_operations ntfs_dir_inode_operations = {
.getattr = ntfs_getattr,
.listxattr = ntfs_listxattr,
.fiemap = ntfs_fiemap,
+ .fileattr_get = ntfs_fileattr_get,
};
const struct inode_operations ntfs_special_inode_operations = {
@@ -527,6 +528,7 @@ const struct inode_operations ntfs_special_inode_operations = {
.listxattr = ntfs_listxattr,
.get_acl = ntfs_get_acl,
.set_acl = ntfs_set_acl,
+ .fileattr_get = ntfs_fileattr_get,
};
const struct dentry_operations ntfs_dentry_ops = {
diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h
index 630128716ea7..a178ca66e2e0 100644
--- a/fs/ntfs3/ntfs_fs.h
+++ b/fs/ntfs3/ntfs_fs.h
@@ -503,6 +503,7 @@ extern const struct file_operations ntfs_dir_operations;
extern const struct file_operations ntfs_legacy_dir_operations;
/* Globals from file.c */
+int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
struct kstat *stat, u32 request_mask, u32 flags);
int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 4/6] ext4: Report case sensitivity in fileattr_get
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
` (2 preceding siblings ...)
2025-12-11 15:21 ` [PATCH v2 3/6] ntfs3: " Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-11 15:21 ` [PATCH v2 5/6] nfsd: Report export case-folding via NFSv3 PATHCONF Chuck Lever
` (2 subsequent siblings)
6 siblings, 0 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Report ext4's case sensitivity behavior via file_kattr.case_info.
ext4 always preserves case at rest.
Case sensitivity is a per-directory setting in ext4. If the queried
inode is a casefolded directory, report Unicode case-insensitive
matching; otherwise report case-sensitive (standard POSIX behavior).
This enables file_getattr to report the case sensitivity behavior of
individual directories within an ext4 filesystem.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/ext4/ioctl.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index a93a7baae990..d760657bb9e2 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -996,6 +996,18 @@ int ext4_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
if (ext4_has_feature_project(inode->i_sb))
fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid);
+ /*
+ * ext4 always preserves case. If this inode is a casefolded
+ * directory, report Unicode case-insensitive; otherwise
+ * report case-sensitive (standard POSIX behavior).
+ */
+ if (IS_CASEFOLDED(inode))
+ fa->case_info = FILEATTR_CASEFOLD_UNICODE |
+ FILEATTR_CASE_PRESERVING;
+ else
+ fa->case_info = FILEATTR_CASEFOLD_NONE |
+ FILEATTR_CASE_PRESERVING;
+
return 0;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 5/6] nfsd: Report export case-folding via NFSv3 PATHCONF
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
` (3 preceding siblings ...)
2025-12-11 15:21 ` [PATCH v2 4/6] ext4: Report case sensitivity in fileattr_get Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-11 15:21 ` [PATCH v2 6/6] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING Chuck Lever
2025-12-12 5:20 ` [PATCH v2 0/6] Exposing case folding behavior Christoph Hellwig
6 siblings, 0 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Replace the hard-coded MSDOS_SUPER_MAGIC check in
nfsd3_proc_pathconf() with a real check of the export's case
behavior settings. Filesystems that implement ->fileattr_get can
then report their case sensitivity behavior to NFSv3 clients. For
filesystems without ->fileattr_get, the default POSIX behavior
(case-sensitive, case-preserving) is reported to NFSv3 clients.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs3proc.c | 18 ++++++++++--------
fs/nfsd/vfs.c | 25 +++++++++++++++++++++++++
fs/nfsd/vfs.h | 2 ++
3 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index b6d03e1ef5f7..c8c76819cfbc 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -721,17 +721,19 @@ nfsd3_proc_pathconf(struct svc_rqst *rqstp)
if (resp->status == nfs_ok) {
struct super_block *sb = argp->fh.fh_dentry->d_sb;
+ bool case_insensitive, case_preserving;
- /* 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;
- break;
- case MSDOS_SUPER_MAGIC:
- resp->p_case_insensitive = 1;
- resp->p_case_preserving = 0;
- break;
+ }
+
+ resp->status = nfsd_get_case_info(&argp->fh,
+ &case_insensitive,
+ &case_preserving);
+ if (resp->status == nfs_ok) {
+ resp->p_case_insensitive = case_insensitive;
+ resp->p_case_preserving = case_preserving;
}
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 9cb20d4aeab1..157ddf405a5d 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"
@@ -2679,3 +2680,27 @@ 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 file handle
+ * @fhp: file handle that has already been verified
+ * @case_insensitive: output, true if the filesystem is case-insensitive
+ * @case_preserving: output, true if the filesystem preserves case
+ *
+ * Returns nfs_ok on success, or an nfserr on failure.
+ */
+__be32
+nfsd_get_case_info(struct svc_fh *fhp, bool *case_insensitive,
+ bool *case_preserving)
+{
+ u32 case_info;
+ int err;
+
+ err = vfs_get_case_info(fhp->fh_dentry, &case_info);
+ if (err)
+ return nfserrno(err);
+
+ *case_insensitive = (case_info & FILEATTR_CASEFOLD_TYPE) != 0;
+ *case_preserving = (case_info & FILEATTR_CASE_PRESERVING) != 0;
+ return nfs_ok;
+}
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index 0c0292611c6d..a80177744325 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -154,6 +154,8 @@ __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);
+__be32 nfsd_get_case_info(struct svc_fh *fhp, bool *case_insensitive,
+ bool *case_preserving);
__be32 nfsd_permission(struct svc_cred *cred, struct svc_export *exp,
struct dentry *dentry, int acc);
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v2 6/6] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
` (4 preceding siblings ...)
2025-12-11 15:21 ` [PATCH v2 5/6] nfsd: Report export case-folding via NFSv3 PATHCONF Chuck Lever
@ 2025-12-11 15:21 ` Chuck Lever
2025-12-12 5:20 ` [PATCH v2 0/6] Exposing case folding behavior Christoph Hellwig
6 siblings, 0 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-11 15:21 UTC (permalink / raw)
To: Al Viro, Christian Brauner
Cc: linux-fsdevel, linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, tytso, adilger.kernel, Volker.Lendecke,
Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Replace the hard-coded values for the NFSv4 case_insensitive and
case_preserving attributes with dynamic values retrieved from the
underlying filesystem via vfs_get_case_info().
This allows NFSv4 clients to discover the actual case sensitivity
behavior of exported filesystems, including per-directory settings
for filesystems like ext4 with casefold support.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs4xdr.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 67bb9c0b9fcb..0c51d390d995 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2933,6 +2933,8 @@ struct nfsd4_fattr_args {
u32 rdattr_err;
bool contextsupport;
bool ignore_crossmnt;
+ bool case_insensitive;
+ bool case_preserving;
};
typedef __be32(*nfsd4_enc_attr)(struct xdr_stream *xdr,
@@ -3131,6 +3133,18 @@ static __be32 nfsd4_encode_fattr4_acl(struct xdr_stream *xdr,
return nfs_ok;
}
+static __be32 nfsd4_encode_fattr4_case_insensitive(struct xdr_stream *xdr,
+ const struct nfsd4_fattr_args *args)
+{
+ return nfsd4_encode_bool(xdr, args->case_insensitive);
+}
+
+static __be32 nfsd4_encode_fattr4_case_preserving(struct xdr_stream *xdr,
+ const struct nfsd4_fattr_args *args)
+{
+ return nfsd4_encode_bool(xdr, args->case_preserving);
+}
+
static __be32 nfsd4_encode_fattr4_filehandle(struct xdr_stream *xdr,
const struct nfsd4_fattr_args *args)
{
@@ -3482,8 +3496,8 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = {
[FATTR4_ACLSUPPORT] = nfsd4_encode_fattr4_aclsupport,
[FATTR4_ARCHIVE] = nfsd4_encode_fattr4__noop,
[FATTR4_CANSETTIME] = nfsd4_encode_fattr4__true,
- [FATTR4_CASE_INSENSITIVE] = nfsd4_encode_fattr4__false,
- [FATTR4_CASE_PRESERVING] = nfsd4_encode_fattr4__true,
+ [FATTR4_CASE_INSENSITIVE] = nfsd4_encode_fattr4_case_insensitive,
+ [FATTR4_CASE_PRESERVING] = nfsd4_encode_fattr4_case_preserving,
[FATTR4_CHOWN_RESTRICTED] = nfsd4_encode_fattr4__true,
[FATTR4_FILEHANDLE] = nfsd4_encode_fattr4_filehandle,
[FATTR4_FILEID] = nfsd4_encode_fattr4_fileid,
@@ -3669,8 +3683,9 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
if (err)
goto out_nfserr;
}
- if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) &&
- !fhp) {
+ if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID |
+ FATTR4_WORD0_CASE_INSENSITIVE |
+ FATTR4_WORD0_CASE_PRESERVING)) && !fhp) {
tempfh = kmalloc(sizeof(struct svc_fh), GFP_KERNEL);
status = nfserr_jukebox;
if (!tempfh)
@@ -3682,6 +3697,13 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
args.fhp = tempfh;
} else
args.fhp = fhp;
+ if (attrmask[0] & (FATTR4_WORD0_CASE_INSENSITIVE |
+ FATTR4_WORD0_CASE_PRESERVING)) {
+ status = nfsd_get_case_info(args.fhp, &args.case_insensitive,
+ &args.case_preserving);
+ if (status != nfs_ok)
+ goto out;
+ }
if (attrmask[0] & FATTR4_WORD0_ACL) {
err = nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl);
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
@ 2025-12-11 23:41 ` Eric Biggers
2025-12-12 1:16 ` Chuck Lever
2025-12-15 12:37 ` Christian Brauner
1 sibling, 1 reply; 17+ messages in thread
From: Eric Biggers @ 2025-12-11 23:41 UTC (permalink / raw)
To: Chuck Lever
Cc: Al Viro, Christian Brauner, linux-fsdevel, linux-ext4, linux-nfs,
linux-kernel, hirofumi, almaz.alexandrovich, tytso,
adilger.kernel, Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025 at 10:21:11AM -0500, Chuck Lever wrote:
> +/* Values stored in the low-order byte */
> +enum fileattr_case_folding {
> + /* Code points are compared directly with no case folding. */
> + FILEATTR_CASEFOLD_NONE = 0,
> +
> + /* ASCII case-insensitive: A-Z are treated as a-z. */
> + FILEATTR_CASEFOLD_ASCII,
> +
> + /* Unicode case-insensitive matching. */
> + FILEATTR_CASEFOLD_UNICODE,
> +};
What does "Unicode case-insensitive matching" mean? There are many
different things it could mean: there are multiple types of Unicode
normalization, Unicode case-folding, NTFS's upper case table, etc.
There are also multiple versions of each.
I see you're proposing that ext4, fat, and ntfs3 all set
FILEATTR_CASEFOLD_UNICODE, at least in some cases.
That seems odd, since they don't do the matching the same way.
- Eric
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-11 23:41 ` Eric Biggers
@ 2025-12-12 1:16 ` Chuck Lever
2025-12-12 2:18 ` Theodore Tso
0 siblings, 1 reply; 17+ messages in thread
From: Chuck Lever @ 2025-12-12 1:16 UTC (permalink / raw)
To: Eric Biggers
Cc: Alexander Viro, Christian Brauner, linux-fsdevel, linux-ext4,
linux-nfs, linux-kernel, hirofumi, almaz.alexandrovich, tytso,
adilger.kernel, Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025, at 6:41 PM, Eric Biggers wrote:
> On Thu, Dec 11, 2025 at 10:21:11AM -0500, Chuck Lever wrote:
>> +/* Values stored in the low-order byte */
>> +enum fileattr_case_folding {
>> + /* Code points are compared directly with no case folding. */
>> + FILEATTR_CASEFOLD_NONE = 0,
>> +
>> + /* ASCII case-insensitive: A-Z are treated as a-z. */
>> + FILEATTR_CASEFOLD_ASCII,
>> +
>> + /* Unicode case-insensitive matching. */
>> + FILEATTR_CASEFOLD_UNICODE,
>> +};
>
> What does "Unicode case-insensitive matching" mean? There are many
> different things it could mean: there are multiple types of Unicode
> normalization, Unicode case-folding, NTFS's upper case table, etc.
> There are also multiple versions of each.
This is left over from the RFC version of the series, and can be removed.
> I see you're proposing that ext4, fat, and ntfs3 all set
> FILEATTR_CASEFOLD_UNICODE, at least in some cases.
>
> That seems odd, since they don't do the matching the same way.
The purpose of this series is to design the VFS infrastructure. Exactly what
it reports is up to folks who actually understand i18n.
--
Chuck Lever
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-12 1:16 ` Chuck Lever
@ 2025-12-12 2:18 ` Theodore Tso
2025-12-12 15:08 ` Chuck Lever
0 siblings, 1 reply; 17+ messages in thread
From: Theodore Tso @ 2025-12-12 2:18 UTC (permalink / raw)
To: Chuck Lever
Cc: Eric Biggers, Alexander Viro, Christian Brauner, linux-fsdevel,
linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, adilger.kernel, Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025 at 08:16:45PM -0500, Chuck Lever wrote:
>
> > I see you're proposing that ext4, fat, and ntfs3 all set
> > FILEATTR_CASEFOLD_UNICODE, at least in some cases.
> >
> > That seems odd, since they don't do the matching the same way.
>
> The purpose of this series is to design the VFS infrastructure. Exactly what
> it reports is up to folks who actually understand i18n.
Do we know who would be receiving this information and what their needs might be?
- Ted
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity
2025-12-11 15:21 ` [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity Chuck Lever
@ 2025-12-12 4:42 ` OGAWA Hirofumi
0 siblings, 0 replies; 17+ messages in thread
From: OGAWA Hirofumi @ 2025-12-12 4:42 UTC (permalink / raw)
To: Chuck Lever
Cc: Al Viro, Christian Brauner, linux-fsdevel, linux-ext4, linux-nfs,
linux-kernel, almaz.alexandrovich, tytso, adilger.kernel,
Volker.Lendecke, Chuck Lever
Chuck Lever <cel@kernel.org> writes:
> From: Chuck Lever <chuck.lever@oracle.com>
>
> Report FAT's case sensitivity behavior via the new file_kattr
> case_info field. FAT filesystems are case-insensitive and do not
> preserve case at rest (stored names are uppercased).
>
> The case folding type depends on the mount options: when utf8 is
> enabled, Unicode case folding is used; otherwise ASCII case folding.
>
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
I can't see the who and how to use this though, in msdos case, looks
like this should check "nocase" option.
Thanks.
> ---
> fs/fat/fat.h | 3 +++
> fs/fat/file.c | 18 ++++++++++++++++++
> fs/fat/namei_msdos.c | 1 +
> fs/fat/namei_vfat.c | 1 +
> 4 files changed, 23 insertions(+)
>
> diff --git a/fs/fat/fat.h b/fs/fat/fat.h
> index d3e426de5f01..38da08d8fec4 100644
> --- a/fs/fat/fat.h
> +++ b/fs/fat/fat.h
> @@ -10,6 +10,8 @@
> #include <linux/fs_context.h>
> #include <linux/fs_parser.h>
>
> +struct file_kattr;
> +
> /*
> * vfat shortname flags
> */
> @@ -407,6 +409,7 @@ extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
> extern int fat_getattr(struct mnt_idmap *idmap,
> const struct path *path, struct kstat *stat,
> u32 request_mask, unsigned int flags);
> +extern int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
> extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
> int datasync);
>
> diff --git a/fs/fat/file.c b/fs/fat/file.c
> index 4fc49a614fb8..123f4c1efdf4 100644
> --- a/fs/fat/file.c
> +++ b/fs/fat/file.c
> @@ -16,6 +16,7 @@
> #include <linux/fsnotify.h>
> #include <linux/security.h>
> #include <linux/falloc.h>
> +#include <linux/fileattr.h>
> #include "fat.h"
>
> static long fat_fallocate(struct file *file, int mode,
> @@ -395,6 +396,22 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset)
> fat_flush_inodes(inode->i_sb, inode, NULL);
> }
>
> +int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
> +{
> + struct inode *inode = d_inode(dentry);
> + struct msdos_sb_info *sbi = MSDOS_SB(inode->i_sb);
> +
> + /*
> + * FAT filesystems do not preserve case: stored names are
> + * uppercased. They are case-insensitive, using either ASCII
> + * or Unicode comparison depending on mount options.
> + */
> + fa->case_info = sbi->options.utf8 ?
> + FILEATTR_CASEFOLD_UNICODE : FILEATTR_CASEFOLD_ASCII;
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(fat_fileattr_get);
> +
> int fat_getattr(struct mnt_idmap *idmap, const struct path *path,
> struct kstat *stat, u32 request_mask, unsigned int flags)
> {
> @@ -574,5 +591,6 @@ EXPORT_SYMBOL_GPL(fat_setattr);
> const struct inode_operations fat_file_inode_operations = {
> .setattr = fat_setattr,
> .getattr = fat_getattr,
> + .fileattr_get = fat_fileattr_get,
> .update_time = fat_update_time,
> };
> diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
> index 0b920ee40a7f..380add5c6c66 100644
> --- a/fs/fat/namei_msdos.c
> +++ b/fs/fat/namei_msdos.c
> @@ -640,6 +640,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
> .rename = msdos_rename,
> .setattr = fat_setattr,
> .getattr = fat_getattr,
> + .fileattr_get = fat_fileattr_get,
> .update_time = fat_update_time,
> };
>
> diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
> index 5dbc4cbb8fce..6cf513f97afa 100644
> --- a/fs/fat/namei_vfat.c
> +++ b/fs/fat/namei_vfat.c
> @@ -1180,6 +1180,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
> .rename = vfat_rename2,
> .setattr = fat_setattr,
> .getattr = fat_getattr,
> + .fileattr_get = fat_fileattr_get,
> .update_time = fat_update_time,
> };
--
OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 0/6] Exposing case folding behavior
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
` (5 preceding siblings ...)
2025-12-11 15:21 ` [PATCH v2 6/6] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING Chuck Lever
@ 2025-12-12 5:20 ` Christoph Hellwig
6 siblings, 0 replies; 17+ messages in thread
From: Christoph Hellwig @ 2025-12-12 5:20 UTC (permalink / raw)
To: Chuck Lever
Cc: Al Viro, Christian Brauner, linux-fsdevel, linux-ext4, linux-nfs,
linux-kernel, hirofumi, almaz.alexandrovich, tytso,
adilger.kernel, Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025 at 10:21:10AM -0500, Chuck Lever wrote:
> - Support NTFS and ext4 in addition to FAT
Still missing at least xfs, hfs, hfsplus and exfat, nfs and cifs.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-12 2:18 ` Theodore Tso
@ 2025-12-12 15:08 ` Chuck Lever
2025-12-12 21:23 ` Theodore Tso
0 siblings, 1 reply; 17+ messages in thread
From: Chuck Lever @ 2025-12-12 15:08 UTC (permalink / raw)
To: Theodore Tso
Cc: Eric Biggers, Alexander Viro, Christian Brauner, linux-fsdevel,
linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, adilger.kernel, Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025, at 9:18 PM, Theodore Tso wrote:
> On Thu, Dec 11, 2025 at 08:16:45PM -0500, Chuck Lever wrote:
>>
>> > I see you're proposing that ext4, fat, and ntfs3 all set
>> > FILEATTR_CASEFOLD_UNICODE, at least in some cases.
>> >
>> > That seems odd, since they don't do the matching the same way.
>>
>> The purpose of this series is to design the VFS infrastructure. Exactly what
>> it reports is up to folks who actually understand i18n.
>
> Do we know who would be receiving this information and what their needs
> might be?
The unicode v. ascii case folding information was included just as
an example. I don't have any use case for that, and as I told Eric,
those specifics can be removed from the API.
The case-insensitivity and case-preserving booleans can be consumed
immediately by NFSD. These two booleans have been part of the NFSv3
and NFSv4 protocols for decades, in order to support NFS clients on
non-POSIX systems.
I'm told that Samba has to detect and expose file system case folding
behavior to its clients as well. Supporting Samba and other user
space file servers is why this series exposes case folding information
via a local user-space API. I don't know of any other category of
user-space application that requires access to case folding info.
The Linux NFS community has a growing interest in supporting NFS
clients on Windows and MacOS platforms, where file name behavior does
not align with traditional POSIX semantics.
One example of a Windows-based NFS client is [1]. This client
implementation explicitly requires servers to report
FATTR4_WORD0_CASE_INSENSITIVE = TRUE for proper operation, a hard
requirement for Windows client interoperability because Windows
applications expect case-insensitive behavior. When an NFS client
knows the server is case-insensitive, it can avoid issuing multiple
LOOKUP/READDIR requests to search for case variants, and applications
like Win32 programs work correctly without manual workarounds or
code changes.
Even the Linux client can take advantage of this information. Trond
merged patches 4 years ago [2] that introduce support for case
insensitivity, in support of the Hammerspace NFS server. In
particular, when a client detects a case-insensitive NFS share,
negative dentry caching must be disabled (a lookup for "FILE.TXT"
failing shouldn't cache a negative entry when "file.txt" exists)
and directory change invalidation must clear all cached case-folded
file name variants.
Hammerspace servers and several other NFS server implementations
operate in multi-protocol environments, where a single file service
instance caters to both NFS and SMB clients. In those cases, things
work more smoothly for everyone when the NFS client can see and adapt
to the case folding behavior that SMB users rely on and expect. NFSD
needs to support the case-insensitivity and case-preserving booleans
properly in order to participate as a first-class citizen in such
environments.
As a side note: I assumed these details were already well-known in
this community; otherwise I would have included it in the series
cover letter. I can include it when posting subsequent revisions.
--
Chuck Lever
[1] https://github.com/kofemann/ms-nfs41-client
[2] https://patchwork.kernel.org/project/linux-nfs/cover/20211217203658.439352-1-trondmy@kernel.org/
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-12 15:08 ` Chuck Lever
@ 2025-12-12 21:23 ` Theodore Tso
2025-12-12 22:49 ` Trond Myklebust
2025-12-13 16:43 ` Chuck Lever
0 siblings, 2 replies; 17+ messages in thread
From: Theodore Tso @ 2025-12-12 21:23 UTC (permalink / raw)
To: Chuck Lever
Cc: Eric Biggers, Alexander Viro, Christian Brauner, linux-fsdevel,
linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, adilger.kernel, Volker.Lendecke, Chuck Lever
On Fri, Dec 12, 2025 at 10:08:18AM -0500, Chuck Lever wrote:
> The unicode v. ascii case folding information was included just as
> an example. I don't have any use case for that, and as I told Eric,
> those specifics can be removed from the API.
>
> The case-insensitivity and case-preserving booleans can be consumed
> immediately by NFSD. These two booleans have been part of the NFSv3
> and NFSv4 protocols for decades, in order to support NFS clients on
> non-POSIX systems.
I was worried that some clients might be using this information so
they could do informed caching --- i,e., if they have "makefile"
cached locally because the user typed "more < makefile" into their
Windows Command.exe window, and then later on some program tries to
access "Makefile" the client OS might decide that they "know" that
"makefile" and "Makefile" are the same file. But if that's the case,
then it needs to have more details about whether it's ASCII versus
Unicode 1.0 vs Unicode 17.0 case folding that be in use, or there
might be "interesting" corner cases.
Which is why I've gotten increasingly more sympathetic to Linus's
position that case folding is Hot Trash. If it weren't for the fact
that I really wanted to get Android out of using wrapfs (which is an
even greater trash fire), I'd be regretting the fact that I helped to
add insensitive file name support to Linux...
- Ted
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-12 21:23 ` Theodore Tso
@ 2025-12-12 22:49 ` Trond Myklebust
2025-12-13 16:43 ` Chuck Lever
1 sibling, 0 replies; 17+ messages in thread
From: Trond Myklebust @ 2025-12-12 22:49 UTC (permalink / raw)
To: Theodore Tso, Chuck Lever
Cc: Eric Biggers, Alexander Viro, Christian Brauner, linux-fsdevel,
linux-ext4, linux-nfs, linux-kernel, hirofumi,
almaz.alexandrovich, adilger.kernel, Volker.Lendecke, Chuck Lever
On Sat, 2025-12-13 at 06:23 +0900, Theodore Tso wrote:
> On Fri, Dec 12, 2025 at 10:08:18AM -0500, Chuck Lever wrote:
> > The unicode v. ascii case folding information was included just as
> > an example. I don't have any use case for that, and as I told Eric,
> > those specifics can be removed from the API.
> >
> > The case-insensitivity and case-preserving booleans can be consumed
> > immediately by NFSD. These two booleans have been part of the NFSv3
> > and NFSv4 protocols for decades, in order to support NFS clients on
> > non-POSIX systems.
>
> I was worried that some clients might be using this information so
> they could do informed caching --- i,e., if they have "makefile"
> cached locally because the user typed "more < makefile" into their
> Windows Command.exe window, and then later on some program tries to
> access "Makefile" the client OS might decide that they "know" that
> "makefile" and "Makefile" are the same file. But if that's the case,
> then it needs to have more details about whether it's ASCII versus
> Unicode 1.0 vs Unicode 17.0 case folding that be in use, or there
> might be "interesting" corner cases.
The Linux NFSv4 client has no clue about how to fold cases so, as Chuck
indicated, it uses the case insensitivity flag only to know when to be
more aggressive about revalidating cached positive dentries and/or
evicting cached negative dentries after the directory contents are seen
to change.
As of now, I'm aware of no plans to try to implement anything like the
"informed caching" you describe above.
> Which is why I've gotten increasingly more sympathetic to Linus's
> position that case folding is Hot Trash. If it weren't for the fact
> that I really wanted to get Android out of using wrapfs (which is an
> even greater trash fire), I'd be regretting the fact that I helped to
> add insensitive file name support to Linux...
>
> - Ted
--
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trondmy@kernel.org, trond.myklebust@hammerspace.com
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-12 21:23 ` Theodore Tso
2025-12-12 22:49 ` Trond Myklebust
@ 2025-12-13 16:43 ` Chuck Lever
1 sibling, 0 replies; 17+ messages in thread
From: Chuck Lever @ 2025-12-13 16:43 UTC (permalink / raw)
To: Theodore Tso
Cc: Eric Biggers, Alexander Viro, Christian Brauner, linux-fsdevel,
linux-ext4, linux-nfs, linux-kernel, OGAWA Hirofumi,
almaz.alexandrovich, adilger.kernel, Volker Lendecke, Chuck Lever
On Fri, Dec 12, 2025, at 4:23 PM, Theodore Tso wrote:
> On Fri, Dec 12, 2025 at 10:08:18AM -0500, Chuck Lever wrote:
>> The unicode v. ascii case folding information was included just as
>> an example. I don't have any use case for that, and as I told Eric,
>> those specifics can be removed from the API.
>>
>> The case-insensitivity and case-preserving booleans can be consumed
>> immediately by NFSD. These two booleans have been part of the NFSv3
>> and NFSv4 protocols for decades, in order to support NFS clients on
>> non-POSIX systems.
>
> I was worried that some clients might be using this information so
> they could do informed caching --- i,e., if they have "makefile"
> cached locally because the user typed "more < makefile" into their
> Windows Command.exe window, and then later on some program tries to
> access "Makefile" the client OS might decide that they "know" that
> "makefile" and "Makefile" are the same file. But if that's the case,
> then it needs to have more details about whether it's ASCII versus
> Unicode 1.0 vs Unicode 17.0 case folding that be in use, or there
> might be "interesting" corner cases.
No current version of the NFS protocol can communicate any more than
whether or not filenames are case sensitive and case preserving. Thus
the unicode label idea is nothing NFSD can possibly take advantage of.
> Which is why I've gotten increasingly more sympathetic to Linus's
> position that case folding is Hot Trash. If it weren't for the fact
> that I really wanted to get Android out of using wrapfs (which is an
> even greater trash fire), I'd be regretting the fact that I helped to
> add insensitive file name support to Linux...
Well I think "Hot Trash" is the general consensus. I'm not thinking
of adding more than the NFS protocol can support. I'm only suggesting
that more /could/ be done if someone has a use case for it.
--
Chuck Lever
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
2025-12-11 23:41 ` Eric Biggers
@ 2025-12-15 12:37 ` Christian Brauner
1 sibling, 0 replies; 17+ messages in thread
From: Christian Brauner @ 2025-12-15 12:37 UTC (permalink / raw)
To: Chuck Lever
Cc: Al Viro, linux-fsdevel, linux-ext4, linux-nfs, linux-kernel,
hirofumi, almaz.alexandrovich, tytso, adilger.kernel,
Volker.Lendecke, Chuck Lever
On Thu, Dec 11, 2025 at 10:21:11AM -0500, Chuck Lever wrote:
> From: Chuck Lever <chuck.lever@oracle.com>
>
> Enable upper layers such as NFSD to retrieve case sensitivity
> information from file systems by adding a case_info field to struct
> file_kattr.
>
> Add vfs_get_case_info() as a convenience helper for kernel
> consumers. If a filesystem does not provide a fileattr_get hook, it
> returns the default POSIX behavior (case-sensitive,
> case-preserving), which is correct for the majority of Linux
> file systems implementations.
>
> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
> ---
Thanks for listening and plumbing this into file_attr() that seems a
much better place than statx().
> fs/file_attr.c | 31 +++++++++++++++++++++++++++++++
> include/linux/fileattr.h | 23 +++++++++++++++++++++++
> 2 files changed, 54 insertions(+)
>
> diff --git a/fs/file_attr.c b/fs/file_attr.c
> index 1dcec88c0680..609e890b5101 100644
> --- a/fs/file_attr.c
> +++ b/fs/file_attr.c
> @@ -94,6 +94,37 @@ int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
> }
> EXPORT_SYMBOL(vfs_fileattr_get);
>
> +/**
> + * vfs_get_case_info - retrieve case sensitivity info for a filesystem
> + * @dentry: the object to retrieve from
> + * @case_info: pointer to store result
> + *
> + * Call i_op->fileattr_get() to retrieve case sensitivity information.
> + * If the filesystem does not provide a fileattr_get hook, return
> + * the default POSIX behavior (case-sensitive, case-preserving).
> + *
> + * Return: 0 on success, or a negative error on failure.
> + */
> +int vfs_get_case_info(struct dentry *dentry, u32 *case_info)
Hm, I would much prefer if we followed the statx() model where we have
vfs_getattr{_nosec}() that always returns a struct kstat. So we should
only have vfs_fileattr_get() instead of the special-purpose
vfs_get_case_info() thing.
I guess the main reason you did this is so that you can set the default
without having to touch each filesystem that doesn't do file_attr.
So just move the default setup of case_info into vfs_fileattr_get()?
This way it's also available to other callers of this function such as
overlayfs and ecryptfs. And then just call that in nfsd.
Otherwise I have no complaints about the VFS part.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2025-12-15 12:38 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-11 15:21 [PATCH v2 0/6] Exposing case folding behavior Chuck Lever
2025-12-11 15:21 ` [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Chuck Lever
2025-12-11 23:41 ` Eric Biggers
2025-12-12 1:16 ` Chuck Lever
2025-12-12 2:18 ` Theodore Tso
2025-12-12 15:08 ` Chuck Lever
2025-12-12 21:23 ` Theodore Tso
2025-12-12 22:49 ` Trond Myklebust
2025-12-13 16:43 ` Chuck Lever
2025-12-15 12:37 ` Christian Brauner
2025-12-11 15:21 ` [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity Chuck Lever
2025-12-12 4:42 ` OGAWA Hirofumi
2025-12-11 15:21 ` [PATCH v2 3/6] ntfs3: " Chuck Lever
2025-12-11 15:21 ` [PATCH v2 4/6] ext4: Report case sensitivity in fileattr_get Chuck Lever
2025-12-11 15:21 ` [PATCH v2 5/6] nfsd: Report export case-folding via NFSv3 PATHCONF Chuck Lever
2025-12-11 15:21 ` [PATCH v2 6/6] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING Chuck Lever
2025-12-12 5:20 ` [PATCH v2 0/6] Exposing case folding behavior Christoph Hellwig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).