Exposing case folding behavior
Subsystems (14)
Chuck Lever
maintainerv14 cover Exposing case folding behavior
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Following on from:
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-nonpreserving = false
The case-insensitivity and case-nonpreserving booleans can be consumed immediately by NFSD. These two attributes have been part of the NFSv3 and NFSv4 protocols for decades, in order to support NFS client implementations on non-POSIX systems.
Support for user space file servers is why this series exposes case folding information via a 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-nonpreserving booleans properly in order to participate as a first-class citizen in such environments.
[1] https://github.com/kofemann/ms-nfs41-client
[2] https://patchwork.kernel.org/project/linux-nfs/cover/[email protected]/
---
Changes since v13:
- Address findings from sashiko (gemini-3.1):
- ntfs3: Drop fileattr_get from symlink and special inode ops
- nfsd: Probe nfsd_get_case_info() under kernel creds to avoid spurious NFS4ERR_ACCESS from per-client MAC policy
Changes since v12:
- Address findings from sashiko (gemini-3.1):
- cifs: Restrict case-handling flags to directories per UAPI
- nfs: Clear case caps before PATHCONF so a failed reply does not retain stale bits from the prior probe
- nfsd: Document the parent-resolution corner cases of nfsd_get_case_info() (single-file exports, disconnected dentries, hardlinks) in the v3 and v4 commit messages
Changes since v11:
- isofs: Wire .fileattr_get only on directory inodes, since NFSD and ksmbd query casefolding on directories (Jan Kara)
- xfs, hfsplus: Drop the FS_CASEFOLD_FL fileattr_get mask; admit the bit through fileattr_set's allowlist instead
- Address findings from sashiko(gemini-3) and gpt-5.5:
- cifs: Wire .fileattr_get on cifs_namespace_inode_operations so DFS referral / automount directories report case handling
- fat, ntfs3: Fill FS_IMMUTABLE_FL in fileattr_get
- hfsplus: Hide FS_CASEFOLD_FL from the legacy flags view so chattr round-trips do not hit the setflags whitelist
- nfs: Clear NFS_CAP_CASE_INSENSITIVE and NFS_CAP_CASE_NONPRESERVING before re-OR'ing in the v3 and v4 probe paths so re-probe / TSM does not retain stale caps
- nfsd: Switch nfsd_get_case_info() to errno return so v3 PATHCONF and v4 GETATTR can apply version-appropriate policy on failure
- nfsd: Use dget_parent() in v4 case-attr probe to keep the parent dentry referenced across the query
- isofs: Report FS_XFLAG_CASENONPRESERVING for map=n/map=a
Changes since v10:
- cifs: Source case-handling flags from the server's cached FS_ATTRIBUTE_INFORMATION reply instead of the nocase mount option, with a nocase fallback when the reply is absent
- Address findings from sashiko(gemini-3) and gpt-5.5:
- nfs: Skip pathconf case bits on NFSv4 (set via FATTR4_CASE_* instead)
- xfs: Hide FS_CASEFOLD_FL from the legacy flags view so chattr round-trips do not hit the setflags whitelist
- ext4, f2fs: Drop redundant fileattr_get patches; the FS_CASEFOLD_FL translation in fileattr_fill_flags() already reports FS_XFLAG_CASEFOLD for casefolded directories
- nfsd: Report FATTR4_HOMOGENEOUS = FALSE when the exported filesystem has a Unicode encoding, since per-directory casefold makes the fs-scoped case attributes inhomogeneous
- nfsd: Document in nfsd_get_case_info() why -ENOIOCTLCMD and -ENOTTY are swallowed while other errors propagate
- fat: Honor vfat 'check=strict' when reporting FS_XFLAG_CASEFOLD
- Set FS_CASEFOLD_FL so FS_IOC_GETFLAGS reflects case-insensitive mount
- isofs: Register fileattr_get on regular file and symlink inodes, not just directories
- nfsd: Query NFSv4 FATTR4_CASE_* from the parent directory for non-directory objects, since casefold lives on the directory
Changes since v9:
- nfs: always probe PATHCONF for case caps. Default to case- preserving when the server does not report case_preserving
- nfsd, ksmbd: tolerate -ENOTTY from vfs_fileattr_get() so overlayfs exports on backing filesystems without fileattr_get do not fail the RPC
- xfs: map FS_XFLAG_CASEFOLD inside xfs_ip2xflags() so BULKSTAT and FS_IOC_FSGETXATTR report the flag consistently
- vboxsf: reject a short host reply to SHFL_INFO_VOLUME before trusting volinfo.properties.case_sensitive
Changes since v8:
- Rebase on v7.0-rc1
Changes since v7:
- Split file_attr initialization changes into a separate patch
Changes since v6:
- Remove the memset from vfs_fileattr_get
Changes since v5:
- Finish the conversion to FS_XFLAGs
- NFSv4 GETATTR now clears the attr mask bit if nfsd_get_case_info() fails
Changes since v4:
- Observe the MSDOS "nocase" mount option
- Define new FS_XFLAGs for the user API
Changes since v3:
- Change fa->case_preserving to fa_case_nonpreserving
- VFAT is case preserving
- Make new fields available to user space
Changes since v2:
- Remove unicode labels
- Replace vfs_get_case_info
- Add support for several more local file system implementations
- Add support for in-kernel SMB server
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 (15):
fs: Move file_kattr initialization to callers
fs: Add case sensitivity flags to file_kattr
fat: Implement fileattr_get for case sensitivity
exfat: Implement fileattr_get for case sensitivity
ntfs3: Implement fileattr_get for case sensitivity
hfs: Implement fileattr_get for case sensitivity
hfsplus: Report case sensitivity in fileattr_get
xfs: Report case sensitivity in fileattr_get
cifs: Implement fileattr_get for case sensitivity
nfs: Implement fileattr_get for case sensitivity
vboxsf: Implement fileattr_get for case sensitivity
isofs: Implement fileattr_get for case sensitivity
nfsd: Report export case-folding via NFSv3 PATHCONF
nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION
fs/exfat/exfat_fs.h | 2 + fs/exfat/file.c | 18 ++++++++- fs/exfat/namei.c | 1 + fs/fat/fat.h | 3 ++ fs/fat/file.c | 36 +++++++++++++++++ fs/fat/namei_msdos.c | 1 + fs/fat/namei_vfat.c | 1 + fs/file_attr.c | 16 ++++---- fs/hfs/dir.c | 1 + fs/hfs/hfs_fs.h | 2 + fs/hfs/inode.c | 14 +++++++ fs/hfsplus/inode.c | 16 +++++++- fs/isofs/dir.c | 16 ++++++++ fs/isofs/isofs.h | 3 ++ fs/nfs/client.c | 21 +++++++--- fs/nfs/inode.c | 15 +++++++ fs/nfs/internal.h | 3 ++ fs/nfs/namespace.c | 2 + fs/nfs/nfs3proc.c | 2 + fs/nfs/nfs3xdr.c | 7 +++- fs/nfs/nfs4proc.c | 10 +++-- fs/nfs/proc.c | 3 ++ fs/nfs/symlink.c | 3 ++ fs/nfsd/nfs3proc.c | 36 +++++++++++++---- fs/nfsd/nfs4xdr.c | 52 +++++++++++++++++++++++-- fs/nfsd/vfs.c | 88 ++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.h | 3 ++ fs/nfsd/xdr3.h | 4 +- fs/ntfs3/file.c | 29 ++++++++++++++ fs/ntfs3/namei.c | 1 + fs/ntfs3/ntfs_fs.h | 1 + fs/smb/client/cifsfs.c | 53 +++++++++++++++++++++++++ fs/smb/client/cifsfs.h | 3 ++ fs/smb/client/namespace.c | 1 + fs/smb/server/smb2pdu.c | 30 +++++++++++--- fs/vboxsf/dir.c | 1 + fs/vboxsf/file.c | 6 ++- fs/vboxsf/super.c | 7 ++++ fs/vboxsf/utils.c | 30 ++++++++++++++ fs/vboxsf/vfsmod.h | 6 +++ fs/xfs/libxfs/xfs_inode_util.c | 2 + fs/xfs/xfs_ioctl.c | 22 +++++++++-- include/linux/fileattr.h | 3 +- include/linux/nfs_fs_sb.h | 2 +- include/linux/nfs_xdr.h | 2 + include/uapi/linux/fs.h | 7 ++++ 46 files changed, 536 insertions(+), 49 deletions(-)
---
base-commit: 6596a02b207886e9e00bb0161c7fd59fea53c081
change-id: 20260422-case-sensitivity-5cbffc8f1558
Best regards,
Signature · 1 line
Chuck Lever <[email protected]>
Chuck Lever
maintainerPATCH v14 1/15 fs: Move file_kattr initialization to callers
From: Chuck Lever <[email protected]>
fileattr_fill_xflags() and fileattr_fill_flags() memset the entire file_kattr struct before populating select fields, so callers cannot pre-set fields in fa->fsx_xflags without having their values clobbered. Darrick Wong noted that a function named "fill_xflags" touching more than xflags forces callers to know implementation details beyond its apparent scope.
Drop the memset from both fill functions and initialize at the entry points instead: ioctl_setflags(), ioctl_fssetxattr(), the file_setattr() syscall, and xfs_ioc_fsgetxattra() now declare fa with an aggregate initializer. ioctl_getflags(), ioctl_fsgetxattr(), and the file_getattr() syscall already aggregate-initialize fa to pass flags_valid/fsx_valid hints into vfs_fileattr_get().
Subsequent patches rely on this so that ->fileattr_get() handlers can set case-sensitivity flags (FS_XFLAG_CASEFOLD, FS_XFLAG_CASENONPRESERVING) in fa->fsx_xflags before the fill functions run.
--- fs/file_attr.c | 12 ++++-------- fs/xfs/xfs_ioctl.c | 2 +- 2 files changed, 5 insertions(+), 9 deletions(-)
fs/file_attr.c +4 -8
@@ -15,12 +15,10 @@* @fa: fileattr pointer * @xflags: FS_XFLAG_* flags * -* Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags). All -* other fields are zeroed. +* Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags). */ void fileattr_fill_xflags (struct file_kattr *fa,u32 xflags) { -memset (fa,0 ,sizeof (*fa)); fa->fsx_valid = true; fa->fsx_xflags = xflags;if (fa->fsx_xflags &FS_XFLAG_IMMUTABLE )
@@ -48,11 +46,9 @@ EXPORT_SYMBOL(fileattr_fill_xflags);* @flags: FS_*_FL flags * * Set ->flags, ->flags_valid and ->fsx_xflags (translated flags). -* All other fields are zeroed. */ void fileattr_fill_flags (struct file_kattr *fa,u32 flags) { -memset (fa,0 ,sizeof (*fa)); fa->flags_valid = true; fa->flags = flags;if (fa->flags &FS_SYNC_FL )
@@ -325,7 +321,7 @@ int ioctl_setflags(struct file *file, unsigned int __user *argp) {struct mnt_idmap *idmap =file_mnt_idmap (file);struct dentry *dentry = file->f_path.dentry; -struct file_kattr fa; +struct file_kattr fa = {};unsigned int flags;int err;
@@ -357,7 +353,7 @@ int ioctl_fssetxattr(struct file *file, void __user *argp) {struct mnt_idmap *idmap =file_mnt_idmap (file);struct dentry *dentry = file->f_path.dentry; -struct file_kattr fa; +struct file_kattr fa = {};int err; err =copy_fsxattr_from_user (&fa, argp);
@@ -431,7 +427,7 @@ SYSCALL_DEFINE5(file_setattr, int, dfd, const char __user *, filename, struct path filepath __free(path_put) = {};unsigned int lookup_flags =0 ;struct file_attr fattr; -struct file_kattr fa; +struct file_kattr fa = {};int error;BUILD_BUG_ON (sizeof (struct file_attr ) <FILE_ATTR_SIZE_VER0 );
fs/xfs/xfs_ioctl.c +1 -1
@@ -517,7 +517,7 @@ xfs_ioc_fsgetxattra( xfs_inode_t *ip, void __user *arg) { -struct file_kattr fa; +struct file_kattr fa = {};xfs_ilock (ip,XFS_ILOCK_SHARED );xfs_fill_fsxattr (ip,XFS_ATTR_FORK , &fa);
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 2/15 fs: Add case sensitivity flags to file_kattr
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Enable upper layers such as NFSD to retrieve case sensitivity information from file systems by adding FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags.
Filesystems report case-insensitive or case-nonpreserving behavior by setting these flags directly in fa->fsx_xflags. The default (flags unset) indicates POSIX semantics: case-sensitive and case-preserving. Both flags are added to FS_XFLAG_RDONLY_MASK so FS_IOC_FSSETXATTR silently strips them, keeping the new xflags strictly a reporting interface. Callers that want to toggle casefolding continue to use FS_IOC_SETFLAGS with FS_CASEFOLD_FL, the established UAPI on filesystems that support the operation (ext4 and f2fs on empty directories).
Case sensitivity information is exported to userspace via the fa_xflags field in the FS_IOC_FSGETXATTR ioctl and file_getattr() system call.
--- fs/file_attr.c | 4 ++++ include/linux/fileattr.h | 3 ++- include/uapi/linux/fs.h | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-)
fs/file_attr.c +4 -0
@@ -37,6 +37,8 @@ void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags) fa->flags |=FS_PROJINHERIT_FL ;if (fa->fsx_xflags &FS_XFLAG_VERITY ) fa->flags |=FS_VERITY_FL ; +if (fa->fsx_xflags &FS_XFLAG_CASEFOLD ) + fa->flags |=FS_CASEFOLD_FL ; }EXPORT_SYMBOL (fileattr_fill_xflags);
@@ -67,6 +69,8 @@ void fileattr_fill_flags(struct file_kattr *fa, u32 flags) fa->fsx_xflags |=FS_XFLAG_PROJINHERIT ;if (fa->flags &FS_VERITY_FL ) fa->fsx_xflags |=FS_XFLAG_VERITY ; +if (fa->flags &FS_CASEFOLD_FL ) + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; }EXPORT_SYMBOL (fileattr_fill_flags);
include/linux/fileattr.h +2 -1
@@ -16,7 +16,8 @@/* Read-only inode flags */ #define FS_XFLAG_RDONLY_MASK \ - (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY) + (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY | \ + FS_XFLAG_CASEFOLD | FS_XFLAG_CASENONPRESERVING)/* Flags to indicate valid value of fsx_ fields */ #define FS_XFLAG_VALUES_MASK \
include/uapi/linux/fs.h +7 -0
@@ -254,6 +254,13 @@ struct file_attr {#define FS_XFLAG_DAX 0x00008000/* use DAX for IO */ #define FS_XFLAG_COWEXTSIZE 0x00010000/* CoW extent size allocator hint */ #define FS_XFLAG_VERITY 0x00020000/* fs-verity enabled */ +/* +* Case handling flags (read-only, cannot be set via ioctl). +* Default (neither set) indicates POSIX semantics: case-sensitive +* lookups and case-preserving storage. +*/ +#define FS_XFLAG_CASEFOLD 0x00040000/* case-insensitive lookups */ +#define FS_XFLAG_CASENONPRESERVING 0x00080000/* case not preserved */ #define FS_XFLAG_HASATTR 0x80000000/* no DIFLAG for this */ /* the read-only stuff doesn't really belong here, but any other place is
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 3/15 fat: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Report FAT's case sensitivity behavior via the FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags. FAT filesystems are case-insensitive by default.
MSDOS supports a 'nocase' mount option that enables case-sensitive behavior; check this option when reporting case sensitivity.
VFAT long filename entries preserve case; without VFAT, only uppercased 8.3 short names are stored. MSDOS with 'nocase' also preserves case since the name-formatting code skips upcasing when 'nocase' is set. Check both options when reporting case preservation.
--- fs/fat/fat.h | 3 +++ fs/fat/file.c | 36 ++++++++++++++++++++++++++++++++++++ fs/fat/namei_msdos.c | 1 + fs/fat/namei_vfat.c | 1 + 4 files changed, 41 insertions(+)
fs/fat/fat.h +3 -0
@@ -10,6 +10,8 @@#include <linux/fs_context.h> #include <linux/fs_parser.h> +struct file_kattr ; +/* * vfat shortname flags */
@@ -408,6 +410,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); +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);
fs/fat/file.c +36 -0
@@ -17,6 +17,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,
@@ -398,6 +399,40 @@ 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 msdos_sb_info *sbi =MSDOS_SB (dentry->d_sb); +bool case_sensitive; + +/* +* FAT filesystems are case-insensitive by default. VFAT +* becomes case-sensitive when mounted with 'check=strict', +* which installs vfat_dentry_ops. MSDOS has no such option; +* its 'nocase' mount option selects case-sensitive matching. +* +* VFAT long filename entries preserve case. Without VFAT, only +* uppercased 8.3 short names are stored. MSDOS with 'nocase' +* also preserves case. +*/ +if (sbi->options.isvfat) + case_sensitive = sbi->options.name_check =='s' ; +else + case_sensitive = sbi->options.nocase; + +if (!case_sensitive) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; +if (!sbi->options.isvfat) + fa->fsx_xflags |=FS_XFLAG_CASENONPRESERVING ; + } +if (d_inode (dentry)->i_flags &S_IMMUTABLE ) { + fa->fsx_xflags |=FS_XFLAG_IMMUTABLE ; + fa->flags |=FS_IMMUTABLE_FL ; + } +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) {
@@ -575,5 +610,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, };
fs/fat/namei_msdos.c +1 -0
@@ -644,6 +644,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, };
fs/fat/namei_vfat.c +1 -0
@@ -1185,6 +1185,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, };
Signature · 1 line
2.53.0
Re: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 6 lines · Chuck Lever
From: Chuck Lever <[email protected]>
Report FAT's case sensitivity behavior via the
FS_XFLAG_CASEFOLDandFS_XFLAG_CASENONPRESERVINGflags. FAT filesystems are case-insensitive by default.
Quoted 7 lines
MSDOS supports a 'nocase' mount option that enables case-sensitive behavior; check this option when reporting case sensitivity.
VFAT long filename entries preserve case; without VFAT, only uppercased 8.3 short names are stored. MSDOS with 'nocase' also preserves case since the name-formatting code skips upcasing when 'nocase' is set. Check both options when reporting case preservation.
I'm seeing a regression in -next with the LTP statx04 test which bisects to this commit:
tst_tmpdir.c:316: TINFO: Using /tmp/LTP_sta8hUyB4 as tmpdir (tmpfs filesystem) tst_device.c:98: TINFO: Found free device 0 '/dev/loop0'
tst_test.c:2047: TINFO: LTP version: 20260130
tst_test.c:2050: TINFO: Tested kernel: 7.1.0-rc4-next-20260520 #1 SMP PREEMPT @1779279361 aarch64
...
tst_test.c:1985: TINFO: === Testing on vfat ===
tst_test.c:1290: TINFO: Formatting /dev/loop0 with vfat opts='' extra opts='' tst_test.c:1302: TINFO: Mounting /dev/loop0 to /tmp/LTP_sta8hUyB4/mntpoint fstyp=vfat flags=0 statx04.c:121: TFAIL: STATX_ATTR_COMPRESSED not supported
statx04.c:121: TFAIL: STATX_ATTR_APPEND not supported
statx04.c:121: TFAIL: STATX_ATTR_IMMUTABLE not supported
statx04.c:121: TFAIL: STATX_ATTR_NODUMP not supported
Full log:
https://lava.sirena.org.uk/scheduler/job/2778994#L6373
bisect log, with links to intermediate test results:
# bad: [687da68900cd1a46549f7d9430c7d40346cb86a0] Add linux-next specific files for 20260520
# good: [2b248ec57f3dcb99f2ce423b72eb3b77553e90a0] Merge branch 'for-linux-next-fixes' of https://gitlab.freedesktop.org/drm/misc/kernel.git
# good: [1c9631527427d35668eeb7236803cc4b18f950a8] Merge branch 'vfs-7.2.procfs' into vfs.all
# good: [3035e4454142327ec5faee2ff57ab7cb1e9fc712] fs: Add case sensitivity flags to file_kattr
git bisect start '687da68900cd1a46549f7d9430c7d40346cb86a0' '2b248ec57f3dcb99f2ce423b72eb3b77553e90a0' '1c9631527427d35668eeb7236803cc4b18f950a8' '3035e4454142327ec5faee2ff57ab7cb1e9fc712'
# test job: [1c9631527427d35668eeb7236803cc4b18f950a8] https://lava.sirena.org.uk/scheduler/job/2774081 # test job: [3035e4454142327ec5faee2ff57ab7cb1e9fc712] https://lava.sirena.org.uk/scheduler/job/2774556 # test job: [687da68900cd1a46549f7d9430c7d40346cb86a0] https://lava.sirena.org.uk/scheduler/job/2778994 # bad: [687da68900cd1a46549f7d9430c7d40346cb86a0] Add linux-next specific files for 20260520 git bisect bad 687da68900cd1a46549f7d9430c7d40346cb86a0 # test job: [8d97e7babd9a9ff8b5be4e4105d24ad3514044ff] https://lava.sirena.org.uk/scheduler/job/2774206 # bad: [8d97e7babd9a9ff8b5be4e4105d24ad3514044ff] Merge branch 'vfs-7.2.casefold' into vfs.all git bisect bad 8d97e7babd9a9ff8b5be4e4105d24ad3514044ff # test job: [f9eba293ae7ca289e587985f94d84a390949ea31] https://lava.sirena.org.uk/scheduler/job/2773899 # bad: [f9eba293ae7ca289e587985f94d84a390949ea31] Merge branch 'kernel-7.2.misc' into vfs.all git bisect bad f9eba293ae7ca289e587985f94d84a390949ea31 # test job: [eeb7b37b9700f0dbb3e6fe7b9e910b466ac190dd] https://lava.sirena.org.uk/scheduler/job/2774402 # bad: [eeb7b37b9700f0dbb3e6fe7b9e910b466ac190dd] ntfs3: Implement fileattr_get for case sensitivity git bisect bad eeb7b37b9700f0dbb3e6fe7b9e910b466ac190dd # test job: [c92db2ca726fe61a66580d30ecff8c192a791935] https://lava.sirena.org.uk/scheduler/job/2774955 # bad: [c92db2ca726fe61a66580d30ecff8c192a791935] fat: Implement fileattr_get for case sensitivity git bisect bad c92db2ca726fe61a66580d30ecff8c192a791935 # first bad commit: [c92db2ca726fe61a66580d30ecff8c192a791935] fat: Implement fileattr_get for case sensitivity # test job: [b6fe046c30236e37e3f8c500cf5b1297c317c5ee] https://lava.sirena.org.uk/scheduler/job/2776383 # bad: [b6fe046c30236e37e3f8c500cf5b1297c317c5ee] hfs: Implement fileattr_get for case sensitivity git bisect bad b6fe046c30236e37e3f8c500cf5b1297c317c5ee # test job: [27e0b573dd4aa927670fbfd84732e569fde72078] https://lava.sirena.org.uk/scheduler/job/2774607 # bad: [27e0b573dd4aa927670fbfd84732e569fde72078] exfat: Implement fileattr_get for case sensitivity git bisect bad 27e0b573dd4aa927670fbfd84732e569fde72078 # test job: [ef14aa143f1dd8adcba6c9277c3bbed2fe0969b4] https://lava.sirena.org.uk/scheduler/job/2774344 # bad: [ef14aa143f1dd8adcba6c9277c3bbed2fe0969b4] vboxsf: Implement fileattr_get for case sensitivity git bisect bad ef14aa143f1dd8adcba6c9277c3bbed2fe0969b4 # test job: [b6fe046c30236e37e3f8c500cf5b1297c317c5ee] https://lava.sirena.org.uk/scheduler/job/2776383 # bad: [b6fe046c30236e37e3f8c500cf5b1297c317c5ee] hfs: Implement fileattr_get for case sensitivity git bisect bad b6fe046c30236e37e3f8c500cf5b1297c317c5ee # test job: [27e0b573dd4aa927670fbfd84732e569fde72078] https://lava.sirena.org.uk/scheduler/job/2774607 # bad: [27e0b573dd4aa927670fbfd84732e569fde72078] exfat: Implement fileattr_get for case sensitivity git bisect bad 27e0b573dd4aa927670fbfd84732e569fde72078 # test job: [c92db2ca726fe61a66580d30ecff8c192a791935] https://lava.sirena.org.uk/scheduler/job/2774955 # bad: [c92db2ca726fe61a66580d30ecff8c192a791935] fat: Implement fileattr_get for case sensitivity git bisect bad c92db2ca726fe61a66580d30ecff8c192a791935 # first bad commit: [c92db2ca726fe61a66580d30ecff8c192a791935] fat: Implement fileattr_get for case sensitivity
Chuck Lever
maintainerRe: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 27 lines · Mark Brown
Quoted 6 lines · Chuck Lever
From: Chuck Lever <[email protected]>
Report FAT's case sensitivity behavior via the
FS_XFLAG_CASEFOLDandFS_XFLAG_CASENONPRESERVINGflags. FAT filesystems are case-insensitive by default.Quoted 7 lines
MSDOS supports a 'nocase' mount option that enables case-sensitive behavior; check this option when reporting case sensitivity.
VFAT long filename entries preserve case; without VFAT, only uppercased 8.3 short names are stored. MSDOS with 'nocase' also preserves case since the name-formatting code skips upcasing when 'nocase' is set. Check both options when reporting case preservation.
I'm seeing a regression in -next with the LTP statx04 test which bisects to this commit:
tst_tmpdir.c:316: TINFO: Using
/tmp/LTP_sta8hUyB4as tmpdir (tmpfs filesystem)
tst_device.c:98: TINFO: Found free device 0 '/dev/loop0' tst_test.c:2047: TINFO: LTP version: 20260130 tst_test.c:2050: TINFO: Tested kernel: 7.1.0-rc4-next-20260520 #1 SMP PREEMPT @1779279361 aarch64...
Quoted 9 lines
tst_test.c:1985: TINFO: === Testing on vfat === tst_test.c:1290: TINFO: Formatting
/dev/loop0with vfat opts='' extra opts=''
tst_test.c:1302: TINFO: Mounting/dev/loop0to/tmp/LTP_sta8hUyB4/mntpointfstyp=vfat flags=0 statx04.c:121: TFAIL:STATX_ATTR_COMPRESSEDnot supported statx04.c:121: TFAIL:STATX_ATTR_APPENDnot supported statx04.c:121: TFAIL:STATX_ATTR_IMMUTABLEnot supported statx04.c:121: TFAIL:STATX_ATTR_NODUMPnot supported
At first blush, that does not seem like a plausible bisect result. This commit shouldn't affect the behavior of tmpfs in any way.
Signature · 1 line
Chuck Lever
Re: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 25 lines · Chuck Lever
Quoted 14 lines · Mark Brown
On Thu, May 07, 2026 at 04:52:56AM -0400, Chuck Lever wrote:
I'm seeing a regression in -next with the LTP statx04 test which bisects to this commit:
tst_tmpdir.c:316: TINFO: Using
/tmp/LTP_sta8hUyB4as tmpdir (tmpfs filesystem)
tst_device.c:98: TINFO: Found free device 0 '/dev/loop0' tst_test.c:2047: TINFO: LTP version: 20260130 tst_test.c:2050: TINFO: Tested kernel: 7.1.0-rc4-next-20260520 #1 SMP PREEMPT @1779279361 aarch64...
Quoted 9 lines
tst_test.c:1985: TINFO: === Testing on vfat === tst_test.c:1290: TINFO: Formatting
/dev/loop0with vfat opts='' extra opts=''
tst_test.c:1302: TINFO: Mounting/dev/loop0to/tmp/LTP_sta8hUyB4/mntpointfstyp=vfat flags=0 statx04.c:121: TFAIL:STATX_ATTR_COMPRESSEDnot supported statx04.c:121: TFAIL:STATX_ATTR_APPENDnot supported statx04.c:121: TFAIL:STATX_ATTR_IMMUTABLEnot supported statx04.c:121: TFAIL:STATX_ATTR_NODUMPnot supported
Quoted 3 lines
At first blush, that does not seem like a plausible bisect result. This commit shouldn't affect the behavior of tmpfs in any way.
It's not testing tmpfs (well, it does but that passed), as the log above shows it is making a vfat filesystem on a loop device backed by a file that happens to be in a tmpfs and then testing that. There's a bunch of filesystems covered in this manner:
tst_test.c:1985: TINFO: === Testing on ext2 ===
tst_test.c:1985: TINFO: === Testing on ext3 ===
tst_test.c:1985: TINFO: === Testing on ext4 ===
tst_test.c:1985: TINFO: === Testing on btrfs ===
tst_test.c:1985: TINFO: === Testing on vfat ===
tst_test.c:1985: TINFO: === Testing on tmpfs ===
Chuck Lever
maintainerRe: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 35 lines · Mark Brown
Quoted 25 lines · Chuck Lever
Quoted 14 lines · Mark Brown
On Thu, May 07, 2026 at 04:52:56AM -0400, Chuck Lever wrote:
I'm seeing a regression in -next with the LTP statx04 test which bisects to this commit:
tst_tmpdir.c:316: TINFO: Using
/tmp/LTP_sta8hUyB4as tmpdir (tmpfs filesystem)
tst_device.c:98: TINFO: Found free device 0 '/dev/loop0' tst_test.c:2047: TINFO: LTP version: 20260130 tst_test.c:2050: TINFO: Tested kernel: 7.1.0-rc4-next-20260520 #1 SMP PREEMPT @1779279361 aarch64...
Quoted 9 lines
tst_test.c:1985: TINFO: === Testing on vfat === tst_test.c:1290: TINFO: Formatting
/dev/loop0with vfat opts='' extra opts=''
tst_test.c:1302: TINFO: Mounting/dev/loop0to/tmp/LTP_sta8hUyB4/mntpointfstyp=vfat flags=0 statx04.c:121: TFAIL:STATX_ATTR_COMPRESSEDnot supported statx04.c:121: TFAIL:STATX_ATTR_APPENDnot supported statx04.c:121: TFAIL:STATX_ATTR_IMMUTABLEnot supported statx04.c:121: TFAIL:STATX_ATTR_NODUMPnot supportedQuoted 3 lines
At first blush, that does not seem like a plausible bisect result. This commit shouldn't affect the behavior of tmpfs in any way.
It's not testing tmpfs (well, it does but that passed), as the log above shows it is making a vfat filesystem on a loop device backed by a file that happens to be in a tmpfs and then testing that. There's a bunch of filesystems covered in this manner:
Quoted 6 lines
tst_test.c:1985: TINFO: === Testing on ext2 ===
tst_test.c:1985: TINFO: === Testing on ext3 ===
tst_test.c:1985: TINFO: === Testing on ext4 ===
tst_test.c:1985: TINFO: === Testing on btrfs ===
tst_test.c:1985: TINFO: === Testing on vfat ===
tst_test.c:1985: TINFO: === Testing on tmpfs ===
OK. Is vfat the only failure in LTP statx04 ?
Signature · 1 line
Chuck Lever
Re: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 8 lines · Chuck Lever
Quoted 4 lines · Mark Brown
It's not testing tmpfs (well, it does but that passed), as the log above shows it is making a vfat filesystem on a loop device backed by a file that happens to be in a tmpfs and then testing that. There's a bunch of filesystems covered in this manner:
OK. Is vfat the only failure in LTP statx04 ?
Yes, it's the only one showing as failing - there are four failures correspoding to the four tests done for vfat. It's only testing a subset of filesystems (a combination of what the test knows about and what's available at runtime with the kernel and rootfs.
Like I say there's a full log available at:
Chuck Lever
maintainerRe: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 8 lines · Mark Brown
Quoted 6 lines · Chuck Lever
Quoted 4 lines · Mark Brown
It's not testing tmpfs (well, it does but that passed), as the log above shows it is making a vfat filesystem on a loop device backed by a file that happens to be in a tmpfs and then testing that. There's a bunch of filesystems covered in this manner:
Quoted 4 lines
Quoted 1 line
OK. Is vfat the only failure in LTP statx04 ?
Yes, it's the only one showing as failing - there are four failures correspoding to the four tests done for vfat.
03/15 adds .fileattr_get = fat_fileattr_get for both fat_file_inode_operations and vfat_dir_inode_operations. LTP opens a directory (SAFE_OPEN(TESTDIR, O_RDONLY|O_DIRECTORY)), so FS_IOC_GETFLAGS on the dir now succeeds, and statx04 proceeds where it was previously skipped.
AFAICS, 03/15 did not change pre-existing kernel behavior of stx_attributes_mask on vfat. It merely converted a "skipped" LTP outcome into an "executed but failed" outcome.
Fix options:
* fat_getattr() could call generic_fill_statx_attr(inode, stat), which advertises KSTAT_ATTR_VFS_FLAGS (IMMUTABLE + APPEND). That clears 2 of 4 TFAILs but not COMPRESSED/NODUMP, which FAT genuinely does not back.
* Set stat->attributes_mask |= KSTAT_ATTR_FS_IOC_FLAGS in fat_getattr(). Honest only to the extent that FAT now exposes some FS_*_FL bits via fileattr. This would silence the test failures, but advertises capabilities (COMPRESSED, NODUMP) FAT doesn't track.
* Admit the LTP statx04 test needs to be updated. FS_IOC_GETFLAGS succeeding does not logically imply all four FS_IOC_FLAGS-mapped STATX_ATTR_* bits are supported. The test's gate is too coarse for filesystems that gained a narrowly-scoped fileattr_get (just casefold/immutable). The test's tag list pins it to filesystems that do support the full set, but vfat was tacitly excluded by the prior ENOTTY.
The first option is the narrowest kernel-side change, and matches what other minimal-fileattr filesystems do.
Signature · 1 line
Chuck Lever
Re: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 11 lines · Chuck Lever
Quoted 2 lines · Mark Brown
Yes, it's the only one showing as failing - there are four failures correspoding to the four tests done for vfat.
03/15 adds .fileattr_get =
fat_fileattr_getfor bothfat_file_inode_operationsandvfat_dir_inode_operations. LTP opens a directory (SAFE_OPEN(TESTDIR, O_RDONLY|O_DIRECTORY)), soFS_IOC_GETFLAGSon the dir now succeeds, and statx04 proceeds where it was previously skipped.
Quoted 3 lines
AFAICS, 03/15 did not change pre-existing kernel behavior of
stx_attributes_maskon vfat. It merely converted a "skipped" LTP outcome into an "executed but failed" outcome.
Ah, that's an interesting issue with the way the test reports. LTP could use nested reports a la TAP here so we're not just seeing the top level failure from the test case in automation.
Quoted 6 lines
Fix options:
*
fat_getattr()could callgeneric_fill_statx_attr(inode, stat), which advertisesKSTAT_ATTR_VFS_FLAGS(IMMUTABLE + APPEND). That clears 2 of 4 TFAILs but not COMPRESSED/NODUMP, which FAT genuinely does not back.
...
Quoted 7 lines
* Admit the LTP statx04 test needs to be updated.
FS_IOC_GETFLAGSsucceeding does not logically imply all four FS_IOC_FLAGS-mapped STATX_ATTR_* bits are supported. The test's gate is too coarse for filesystems that gained a narrowly-scopedfileattr_get(just casefold/immutable). The test's tag list pins it to filesystems that do support the full set, but vfat was tacitly excluded by the prior ENOTTY.
I think this is needed, it's hardly the first LTP test to make unwarranted assumptions about the kernel APIs. I'll try to look into it.
Quoted 2 lines
The first option is the narrowest kernel-side change, and matches what other minimal-fileattr filesystems do.
That sounds like a good idea regardless of what we do with the test?
Thanks for looking into this so quickly and thoroughly.
Chuck Lever
maintainerRe: [PATCH v14 03/15] fat: Implement fileattr_get for case sensitivity
Quoted 5 lines · Mark Brown
Quoted 2 lines · Chuck Lever
The first option is the narrowest kernel-side change, and matches what other minimal-fileattr filesystems do.
That sounds like a good idea regardless of what we do with the test?
Yes, I have no objection to this approach, but it would be great to hear from the vfat maintainers/contributors on this one before I dig in.
Signature · 1 line
Chuck Lever
Chuck Lever
maintainerPATCH v14 4/15 exfat: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Report exFAT's case sensitivity behavior via the FS_XFLAG_CASEFOLD flag. exFAT compares names through the volume's upcase table; in practice that table folds case, and case is preserved at rest.
--- fs/exfat/exfat_fs.h | 2 ++ fs/exfat/file.c | 18 ++++++++++++++++-- fs/exfat/namei.c | 1 + 3 files changed, 19 insertions(+), 2 deletions(-)
fs/exfat/exfat_fs.h +2 -0
@@ -496,6 +496,8 @@ int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,int exfat_getattr (struct mnt_idmap *idmap,const struct path *path,struct kstat *stat,unsigned int request_mask,unsigned int query_flags); +struct file_kattr ; +int exfat_fileattr_get (struct dentry *dentry,struct file_kattr *fa);int exfat_file_fsync (struct file *file,loff_t start,loff_t end,int datasync);long exfat_ioctl (struct file *filp,unsigned int cmd,unsigned long arg); long exfat_compat_ioctl(struct file *filp, unsigned int cmd,
fs/exfat/file.c +16 -2
@@ -14,6 +14,7 @@#include <linux/writeback.h> #include <linux/filelock.h> #include <linux/falloc.h> +#include <linux/fileattr.h> #include "exfat_raw.h" #include "exfat_fs.h"
@@ -323,6 +324,18 @@ int exfat_getattr(struct mnt_idmap *idmap, const struct path *path,return 0 ; } +int exfat_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +/* +* exFAT compares filenames through an upcase table, so lookup +* is always case-insensitive. Long names are stored in UTF-16 +* with case intact; CASENONPRESERVING stays clear. +*/ + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; +return 0 ; +} +int exfat_setattr (struct mnt_idmap *idmap,struct dentry *dentry,struct iattr *attr) {
@@ -817,6 +830,7 @@ const struct file_operations exfat_file_operations = { };const struct inode_operations exfat_file_inode_operations = { - .setattr = exfat_setattr, - .getattr = exfat_getattr, + .setattr = exfat_setattr, + .getattr = exfat_getattr, + .fileattr_get = exfat_fileattr_get, };
fs/exfat/namei.c +1 -0
@@ -1311,4 +1311,5 @@ const struct inode_operations exfat_dir_inode_operations = { .rename = exfat_rename, .setattr = exfat_setattr, .getattr = exfat_getattr, + .fileattr_get = exfat_fileattr_get, };
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 5/15 ntfs3: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Report NTFS case sensitivity behavior via the FS_XFLAG_CASEFOLD flag. NTFS always preserves case at rest.
--- fs/ntfs3/file.c | 29 +++++++++++++++++++++++++++++ fs/ntfs3/namei.c | 1 + fs/ntfs3/ntfs_fs.h | 1 + 3 files changed, 31 insertions(+)
fs/ntfs3/file.c +29 -0
@@ -180,6 +180,34 @@ 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 (the default). Case sensitivity depends on +* mount options: with "nocase", NTFS is case-insensitive; +* otherwise it is case-sensitive. +*/ +if (sbi->options->nocase) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +if (inode->i_flags &S_IMMUTABLE ) { + fa->fsx_xflags |=FS_XFLAG_IMMUTABLE ; + fa->flags |=FS_IMMUTABLE_FL ; + } +return 0 ; +} +/* * ntfs_getattr - inode_operations::getattr */
@@ -1547,6 +1575,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 = {
fs/ntfs3/namei.c +1 -0
@@ -518,6 +518,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 = {
fs/ntfs3/ntfs_fs.h +1 -0
@@ -529,6 +529,7 @@ bool dir_is_empty(struct inode *dir);extern const struct file_operations ntfs_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,
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 6/15 hfs: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Report HFS case sensitivity behavior via the FS_XFLAG_CASEFOLD flag. HFS is always case-insensitive (using Mac OS Roman case folding) and always preserves case at rest.
--- fs/hfs/dir.c | 1 + fs/hfs/hfs_fs.h | 2 ++ fs/hfs/inode.c | 14 ++++++++++++++ 3 files changed, 17 insertions(+)
fs/hfs/dir.c +1 -0
@@ -328,4 +328,5 @@ const struct inode_operations hfs_dir_inode_operations = { .rmdir = hfs_remove, .rename = hfs_rename, .setattr = hfs_inode_setattr, + .fileattr_get = hfs_fileattr_get, };
fs/hfs/hfs_fs.h +2 -0
@@ -177,6 +177,8 @@ extern int hfs_get_block(struct inode *inode, sector_t block,extern const struct address_space_operations hfs_aops;extern const struct address_space_operations hfs_btree_aops; +struct file_kattr ; +int hfs_fileattr_get (struct dentry *dentry,struct file_kattr *fa);int hfs_write_begin (const struct kiocb *iocb,struct address_space *mapping,loff_t pos,unsigned int len,struct folio **foliop,void **fsdata);
fs/hfs/inode.c +14 -0
@@ -18,6 +18,7 @@#include <linux/uio.h> #include <linux/xattr.h> #include <linux/blkdev.h> +#include <linux/fileattr.h> #include "hfs_fs.h" #include "btree.h"
@@ -699,6 +700,18 @@ static int hfs_file_fsync(struct file *filp, loff_t start, loff_t end,return ret; } +int hfs_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +/* +* HFS compares filenames using Mac OS Roman case folding, so +* lookup is always case-insensitive. Names are stored on disk +* with case intact; CASENONPRESERVING stays clear. +*/ + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; +return 0 ; +} +static const struct file_operations hfs_file_operations = { .llseek = generic_file_llseek, .read_iter = generic_file_read_iter,
@@ -715,4 +728,5 @@ static const struct inode_operations hfs_file_inode_operations = { .lookup = hfs_file_lookup, .setattr = hfs_inode_setattr, .listxattr = generic_listxattr, + .fileattr_get = hfs_fileattr_get, };
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 7/15 hfsplus: Report case sensitivity in fileattr_get
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Add case sensitivity reporting to the existing hfsplus_fileattr_get() function via the FS_XFLAG_CASEFOLD flag. HFS+ always preserves case at rest.
Case sensitivity depends on how the volume was formatted: HFSX volumes may be either case-sensitive or case-insensitive, indicated by the HFSPLUS_SB_CASEFOLD superblock flag.
FS_XFLAG_CASEFOLD is read-only: FS_XFLAG_RDONLY_MASK ensures FS_IOC_FSSETXATTR strips it. The legacy FS_IOC_SETFLAGS path in hfsplus_fileattr_set() also allows FS_CASEFOLD_FL through its allowlist on case-insensitive volumes so that a chattr read-modify-write cycle does not fail with EOPNOTSUPP.
--- fs/hfsplus/inode.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
fs/hfsplus/inode.c +15 -1
@@ -740,6 +740,7 @@ int hfsplus_fileattr_get(struct dentry *dentry, struct file_kattr *fa) {struct inode *inode =d_inode (dentry);struct hfsplus_inode_info *hip =HFSPLUS_I (inode); +struct hfsplus_sb_info *sbi =HFSPLUS_SB (inode->i_sb);unsigned int flags =0 ;if (inode->i_flags &S_IMMUTABLE )
@@ -748,6 +749,8 @@ int hfsplus_fileattr_get(struct dentry *dentry, struct file_kattr *fa) flags |=FS_APPEND_FL ;if (hip->userflags &HFSPLUS_FLG_NODUMP ) flags |=FS_NODUMP_FL ; +if (test_bit (HFSPLUS_SB_CASEFOLD , &sbi->flags)) + flags |=FS_CASEFOLD_FL ;fileattr_fill_flags (fa, flags);
@@ -759,13 +762,24 @@ int hfsplus_fileattr_set(struct mnt_idmap *idmap, {struct inode *inode =d_inode (dentry);struct hfsplus_inode_info *hip =HFSPLUS_I (inode); +struct hfsplus_sb_info *sbi =HFSPLUS_SB (inode->i_sb); +unsigned int allowed =FS_IMMUTABLE_FL |FS_APPEND_FL |FS_NODUMP_FL ;unsigned int new_fl =0 ;if (fileattr_has_fsx (fa))return -EOPNOTSUPP ; +/* +* FS_CASEFOLD_FL reflects HFSPLUS_SB_CASEFOLD, a mount-time +* property. Accept it as a no-op so chattr's RMW round-trip +* succeeds; reject any attempt to enable it on a volume that +* was not formatted case-insensitive. +*/ +if (test_bit (HFSPLUS_SB_CASEFOLD , &sbi->flags)) + allowed |=FS_CASEFOLD_FL ; +/* don't silently ignore unsupported ext2 flags */ -if (fa->flags & ~(FS_IMMUTABLE_FL |FS_APPEND_FL |FS_NODUMP_FL )) +if (fa->flags & ~allowed)return -EOPNOTSUPP ;if (fa->flags &FS_IMMUTABLE_FL )
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 8/15 xfs: Report case sensitivity in fileattr_get
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Upper layers such as NFSD need to query whether a filesystem is case-sensitive. Add FS_XFLAG_CASEFOLD to xfs_ip2xflags() when the filesystem is formatted with the ASCIICI feature flag. This serves both FS_IOC_FSGETXATTR (via xfs_fill_fsxattr() in xfs_fileattr_get()) and XFS_IOC_BULKSTAT (which populates bs_xflags directly from xfs_ip2xflags()), so bulkstat consumers and per-inode queries see a consistent view of the filesystem's case-folding behavior.
FS_XFLAG_CASEFOLD is read-only: FS_XFLAG_RDONLY_MASK ensures FS_IOC_FSSETXATTR strips it, and xfs_flags2diflags() has no clause for CASEFOLD so the on-disk diflags are unaffected. The legacy FS_IOC_SETFLAGS path in xfs_fileattr_set() also allows FS_CASEFOLD_FL through its allowlist on ASCIICI filesystems so that a chattr read-modify-write cycle does not fail with EOPNOTSUPP.
XFS always preserves case. XFS is case-sensitive by default, but supports ASCII case-insensitive lookups when formatted with the ASCIICI feature flag.
--- fs/xfs/libxfs/xfs_inode_util.c | 2 ++ fs/xfs/xfs_ioctl.c | 20 +++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-)
fs/xfs/libxfs/xfs_inode_util.c +2 -0
@@ -130,6 +130,8 @@ xfs_ip2xflags(if (xfs_inode_has_attr_fork (ip)) flags |=FS_XFLAG_HASATTR ; +if (xfs_has_asciici (ip->i_mount)) + flags |=FS_XFLAG_CASEFOLD ;return flags; }
fs/xfs/xfs_ioctl.c +17 -3
@@ -755,9 +755,23 @@ xfs_fileattr_set(trace_xfs_ioctl_setattr (ip);if (!fa->fsx_valid) { -if (fa->flags & ~(FS_IMMUTABLE_FL |FS_APPEND_FL | -FS_NOATIME_FL |FS_NODUMP_FL | -FS_SYNC_FL |FS_DAX_FL |FS_PROJINHERIT_FL )) +unsigned int allowed =FS_IMMUTABLE_FL |FS_APPEND_FL | +FS_NOATIME_FL |FS_NODUMP_FL | +FS_SYNC_FL |FS_DAX_FL | +FS_PROJINHERIT_FL ; + +/* +* FS_CASEFOLD_FL reflects the ASCIICI superblock feature, +* a read-only property. Accept it as a no-op so chattr's +* RMW round-trip succeeds; reject any attempt to enable +* it on a non-ASCIICI filesystem. xfs_flags2diflags() +* has no clause for CASEFOLD, so the bit is dropped from +* the on-disk diflags regardless. +*/ +if (xfs_has_asciici (mp)) + allowed |=FS_CASEFOLD_FL ; + +if (fa->flags & ~allowed)return -EOPNOTSUPP ; }
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 9/15 cifs: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Upper layers such as NFSD need a way to query whether a filesystem handles filenames in a case-sensitive manner. Report CIFS/SMB case handling behavior via FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING.
The authoritative source is the server itself: at mount time CIFS issues QueryFSInfo(FS_ATTRIBUTE_INFORMATION) and caches the reply on the tcon. That reply carries FILE_CASE_SENSITIVE_SEARCH and FILE_CASE_PRESERVED_NAMES, which reflect whatever case handling the share actually implements after SMB3.1.1 POSIX extensions negotiation. Translating those two bits into the VFS flags lets cifs_fileattr_get report what the server advertises rather than what the client was asked to pretend.
QueryFSInfo is best-effort; the mount completes even if the server does not answer. MaxPathNameComponentLength is zero in that case and is used as the "no reply received" sentinel. When no reply is available, fall back to the nocase mount option so that the reported behavior agrees with the dentry comparison operations installed on the superblock.
The callback is registered on cifs_dir_inode_ops so that NFSD, ksmbd, and other consumers querying case handling against a directory get a definitive answer, and on cifs_file_inode_ops to preserve FS_COMPR_FL reporting on regular files. cifs_set_ops() also installs cifs_namespace_inode_operations on DFS referral directories that carry IS_AUTOMOUNT; register the same callback there so the answer does not depend on whether the directory is a referral point.
Registering fileattr_get routes FS_IOC_GETFLAGS through vfs_fileattr_get() and short-circuits the syscall's fallback to cifs_ioctl(). That fallback invoked CIFSGetExtAttr() under CONFIG_CIFS_POSIX and CONFIG_CIFS_ALLOW_INSECURE_LEGACY on servers advertising CIFS_UNIX_EXTATTR_CAP, surfacing the SMB1 Unix-extension immutable, append, and nodump bits. cifs_fileattr_get carries over only FS_COMPR_FL from cached cifsAttrs; the SMB1 extattr fetch is not reproduced. SMB1 is deprecated, and acquiring a netfid from within a dentry-only callback is not worth preserving a path tied to an insecure legacy dialect.
--- fs/smb/client/cifsfs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++ fs/smb/client/cifsfs.h | 3 +++ fs/smb/client/namespace.c | 1 + 3 files changed, 57 insertions(+)
fs/smb/client/cifsfs.c +53 -0
@@ -30,6 +30,7 @@#include <linux/xattr.h> #include <linux/mm.h> #include <linux/key-type.h> +#include <linux/fileattr.h> #include <uapi/linux/magic.h> #include <net/ipv6.h> #include "cifsfs.h"
@@ -1199,6 +1200,56 @@ struct file_system_type smb3_fs_type = {MODULE_ALIAS_FS ("smb3" );MODULE_ALIAS ("smb3" ); +int cifs_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +struct cifs_sb_info *cifs_sb =CIFS_SB (dentry->d_sb); +struct cifs_tcon *tcon =cifs_sb_master_tcon (cifs_sb); +struct inode *inode =d_inode (dentry); +u32 attrs; + +/* Preserve FS_COMPR_FL previously reported by cifs_ioctl(). */ +if (CIFS_I (inode)->cifsAttrs &ATTR_COMPRESSED ) + fa->flags |=FS_COMPR_FL ; + +/* +* FS_CASEFOLD_FL is defined by UAPI as a folder attribute, +* and userspace tools (e.g., lsattr) display it only on +* directories. Confine the case-handling bits to directories +* to match that convention; for non-directories the share's +* case semantics are still discoverable through the parent. +*/ +if (!S_ISDIR (inode->i_mode)) +return 0 ; + +/* +* The server's FS_ATTRIBUTE_INFORMATION response, cached on +* the tcon at mount, reflects the share's case-handling +* semantics after any POSIX extensions negotiation. Prefer +* it over the client-local nocase mount option, which only +* governs dentry comparison on this superblock. +* +* QueryFSInfo is best-effort at mount; when it did not +* populate fsAttrInfo, MaxPathNameComponentLength remains +* zero. In that case fall back to nocase so the reporting +* matches the comparison behavior installed on the sb. +*/ +if (le32_to_cpu (tcon->fsAttrInfo.MaxPathNameComponentLength) ==0 ) { +if (tcon->nocase) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +return 0 ; + } + attrs =le32_to_cpu (tcon->fsAttrInfo.Attributes); +if (!(attrs &FILE_CASE_SENSITIVE_SEARCH )) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +if (!(attrs &FILE_CASE_PRESERVED_NAMES )) + fa->fsx_xflags |=FS_XFLAG_CASENONPRESERVING ; +return 0 ; +} +const struct inode_operations cifs_dir_inode_ops = { .create = cifs_create, .atomic_open = cifs_atomic_open,
@@ -1217,6 +1268,7 @@ const struct inode_operations cifs_dir_inode_ops = { .listxattr = cifs_listxattr, .get_acl = cifs_get_acl, .set_acl = cifs_set_acl, + .fileattr_get = cifs_fileattr_get, };const struct inode_operations cifs_file_inode_ops = {
@@ -1227,6 +1279,7 @@ const struct inode_operations cifs_file_inode_ops = { .fiemap = cifs_fiemap, .get_acl = cifs_get_acl, .set_acl = cifs_set_acl, + .fileattr_get = cifs_fileattr_get, }; const char *cifs_get_link(struct dentry *dentry, struct inode *inode,
fs/smb/client/cifsfs.h +3 -0
@@ -89,6 +89,9 @@ extern const struct inode_operations cifs_file_inode_ops;extern const struct inode_operations cifs_symlink_inode_ops;extern const struct inode_operations cifs_namespace_inode_operations; +struct file_kattr ; +int cifs_fileattr_get (struct dentry *dentry,struct file_kattr *fa); +/* Functions related to files and directories */ extern const struct netfs_request_ops cifs_req_ops;
fs/smb/client/namespace.c +1 -0
@@ -294,4 +294,5 @@ struct vfsmount *cifs_d_automount(struct path *path) }const struct inode_operations cifs_namespace_inode_operations = { + .fileattr_get = cifs_fileattr_get, };
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 10/15 nfs: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
An NFS server re-exporting an NFS mount point needs to report the case sensitivity behavior of the underlying filesystem to its clients. NFSD's attribute encoder obtains that information by calling vfs_fileattr_get() on the lower filesystem, so the NFS client must implement fileattr_get to surface what it learned from its own server.
The NFS client already retrieves case sensitivity information from servers during mount via PATHCONF (NFSv3) or the FATTR4_CASE_INSENSITIVE/FATTR4_CASE_PRESERVING attributes (NFSv4). Expose this information through fileattr_get by reporting the FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags. NFSv2 lacks PATHCONF support, so mounts using that protocol version default to standard POSIX behavior: case-sensitive and case-preserving.
PATHCONF is now invoked unconditionally for NFSv2 and NFSv3 mounts so the case-sensitivity capabilities are established even when the user pins server->namelen with the namlen= mount option. That option is orthogonal to case handling, and skipping PATHCONF because namelen was already known would leave the caps unset.
The two capability bits carry opposite polarity because their POSIX defaults differ. Most servers are case-sensitive and case- preserving, matching "neither xflag set." NFS_CAP_CASE_INSENSITIVE is set only when the server affirms case insensitivity, so "server said no" and "server did not answer" both collapse to the case- sensitive default. NFS_CAP_CASE_NONPRESERVING follows the same pattern in the opposite direction: set only when the server affirms that it does not preserve case, so that silence or a missing attribute lands on the case-preserving default. The NFSv4 probe checks res.attr_bitmask[0] to distinguish "server said false" from "server omitted the attribute" before setting the bit.
Both capability bits are cleared before each probe so a remount, an NFSv4 transparent state migration to a server with different case semantics, or a probe whose reply does not arrive does not retain stale capabilities from the prior probe.
--- fs/nfs/client.c | 21 +++++++++++++++------ fs/nfs/inode.c | 15 +++++++++++++++ fs/nfs/internal.h | 3 +++ fs/nfs/namespace.c | 2 ++ fs/nfs/nfs3proc.c | 2 ++ fs/nfs/nfs3xdr.c | 7 +++++-- fs/nfs/nfs4proc.c | 10 +++++++--- fs/nfs/proc.c | 3 +++ fs/nfs/symlink.c | 3 +++ include/linux/nfs_fs_sb.h | 2 +- include/linux/nfs_xdr.h | 2 ++ 11 files changed, 58 insertions(+), 12 deletions(-)
fs/nfs/client.c +15 -6
@@ -914,6 +914,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,*/ static int nfs_probe_fsinfo (struct nfs_server *server,struct nfs_fh *mntfh,struct nfs_fattr *fattr) { +struct nfs_pathconf pathinfo = { };struct nfs_fsinfo fsinfo;struct nfs_client *clp = server->nfs_client;int error;
@@ -933,15 +934,23 @@ static int nfs_probe_fsinfo(struct nfs_server *server, struct nfs_fh *mntfh, strnfs_server_set_fsinfo (server, &fsinfo); -/* Get some general file system info */ -if (server->namelen ==0 ) { -struct nfs_pathconf pathinfo; + pathinfo.fattr = fattr; +nfs_fattr_init (fattr); - pathinfo.fattr = fattr; -nfs_fattr_init (fattr); +/* Clear before probing so a failed RPC does not retain stale bits. */ +if (clp->rpc_ops->version <4 ) + server->caps &= ~(NFS_CAP_CASE_INSENSITIVE | +NFS_CAP_CASE_NONPRESERVING ); -if (clp->rpc_ops->pathconf (server, mntfh, &pathinfo) >=0 ) +if (clp->rpc_ops->pathconf (server, mntfh, &pathinfo) >=0 ) { +if (server->namelen ==0 ) server->namelen = pathinfo.max_namelen; +if (clp->rpc_ops->version <4 ) { +if (pathinfo.case_insensitive) + server->caps |=NFS_CAP_CASE_INSENSITIVE ; +if (!pathinfo.case_preserving) + server->caps |=NFS_CAP_CASE_NONPRESERVING ; + } } if (clp->rpc_ops->discover_trunking != NULL &&
fs/nfs/inode.c +15 -0
@@ -41,6 +41,7 @@#include <linux/freezer.h> #include <linux/uaccess.h> #include <linux/iversion.h> +#include <linux/fileattr.h> #include "nfs4_fs.h" #include "callback.h"
@@ -1101,6 +1102,20 @@ int nfs_getattr(struct mnt_idmap *idmap, const struct path *path, }EXPORT_SYMBOL_GPL (nfs_getattr); +int nfs_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +struct inode *inode =d_inode (dentry); + +if (nfs_server_capable (inode,NFS_CAP_CASE_INSENSITIVE )) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +if (nfs_server_capable (inode,NFS_CAP_CASE_NONPRESERVING )) + fa->fsx_xflags |=FS_XFLAG_CASENONPRESERVING ; +return 0 ; +} +EXPORT_SYMBOL_GPL (nfs_fileattr_get); +static void nfs_init_lock_context (struct nfs_lock_context *l_ctx) {refcount_set (&l_ctx->count,1 );
fs/nfs/internal.h +3 -0
@@ -449,6 +449,9 @@ extern void nfs_set_cache_invalid(struct inode *inode, unsigned long flags);extern bool nfs_check_cache_invalid (struct inode *,unsigned long );extern int nfs_wait_bit_killable (struct wait_bit_key *key,int mode); +struct file_kattr ; +int nfs_fileattr_get (struct dentry *dentry,struct file_kattr *fa); +#if IS_ENABLED (CONFIG_NFS_LOCALIO )/* localio.c */ struct nfs_local_dio {
fs/nfs/namespace.c +2 -0
@@ -246,11 +246,13 @@ nfs_namespace_setattr(struct mnt_idmap *idmap, struct dentry *dentry,const struct inode_operations nfs_mountpoint_inode_operations = { .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, };const struct inode_operations nfs_referral_inode_operations = { .getattr = nfs_namespace_getattr, .setattr = nfs_namespace_setattr, + .fileattr_get = nfs_fileattr_get, };static void nfs_expire_automounts (struct work_struct *work)
fs/nfs/nfs3proc.c +2 -0
@@ -1053,6 +1053,7 @@ static const struct inode_operations nfs3_dir_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .get_inode_acl = nfs3_get_acl,
@@ -1064,6 +1065,7 @@ static const struct inode_operations nfs3_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, #ifdef CONFIG_NFS_V3_ACL .listxattr = nfs3_listxattr, .get_inode_acl = nfs3_get_acl,
fs/nfs/nfs3xdr.c +5 -2
@@ -2276,8 +2276,11 @@ static int decode_pathconf3resok(struct xdr_stream *xdr,if (unlikely (!p))return -EIO ; result->max_link =be32_to_cpup (p++); - result->max_namelen =be32_to_cpup (p); -/* ignore remaining fields */ + result->max_namelen =be32_to_cpup (p++); + p++;/* ignore no_trunc */ + p++;/* ignore chown_restricted */ + result->case_insensitive =be32_to_cpup (p++) !=0 ; + result->case_preserving =be32_to_cpup (p) !=0 ;return 0 ; }
fs/nfs/nfs4proc.c +7 -3
@@ -3933,7 +3933,8 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f server->caps &= ~(NFS_CAP_ACLS |NFS_CAP_HARDLINKS |NFS_CAP_SYMLINKS |NFS_CAP_SECURITY_LABEL |NFS_CAP_FS_LOCATIONS | -NFS_CAP_OPEN_XOR |NFS_CAP_DELEGTIME ); +NFS_CAP_OPEN_XOR |NFS_CAP_DELEGTIME | +NFS_CAP_CASE_INSENSITIVE |NFS_CAP_CASE_NONPRESERVING ); server->fattr_valid =NFS_ATTR_FATTR_V4 ;if (res.attr_bitmask[0 ] &FATTR4_WORD0_ACL && res.acl_bitmask &ACL4_SUPPORT_ALLOW_ACL )
@@ -3944,8 +3945,9 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f server->caps |=NFS_CAP_SYMLINKS ;if (res.case_insensitive) server->caps |=NFS_CAP_CASE_INSENSITIVE ; -if (res.case_preserving) - server->caps |=NFS_CAP_CASE_PRESERVING ; +if ((res.attr_bitmask[0 ] &FATTR4_WORD0_CASE_PRESERVING ) && + !res.case_preserving) + server->caps |=NFS_CAP_CASE_NONPRESERVING ;#ifdef CONFIG_NFS_V4_SECURITY_LABEL if (res.attr_bitmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) server->caps |=NFS_CAP_SECURITY_LABEL ;
@@ -10598,6 +10600,7 @@ static const struct inode_operations nfs4_dir_inode_operations = { .getattr = nfs_getattr, .setattr = nfs_setattr, .listxattr = nfs4_listxattr, + .fileattr_get = nfs_fileattr_get, };static const struct inode_operations nfs4_file_inode_operations = {
@@ -10605,6 +10608,7 @@ static const struct inode_operations nfs4_file_inode_operations = { .getattr = nfs_getattr, .setattr = nfs_setattr, .listxattr = nfs4_listxattr, + .fileattr_get = nfs_fileattr_get, }; static struct nfs_server *nfs4_clone_server(struct nfs_server *source,
fs/nfs/proc.c +3 -0
@@ -598,6 +598,7 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle, { info->max_link =0 ; info->max_namelen =NFS2_MAXNAMLEN ; + info->case_preserving = true;return 0 ; }
@@ -718,12 +719,14 @@ static const struct inode_operations nfs_dir_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, };static const struct inode_operations nfs_file_inode_operations = { .permission = nfs_permission, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, };const struct nfs_rpc_ops nfs_v2_clientops = {
fs/nfs/symlink.c +3 -0
@@ -22,6 +22,8 @@#include <linux/mm.h> #include <linux/string.h> +#include "internal.h" +/* Symlink caching in the page cache is even more simplistic * and straight-forward than readdir caching. */
@@ -74,4 +76,5 @@ const struct inode_operations nfs_symlink_inode_operations = { .get_link = nfs_get_link, .getattr = nfs_getattr, .setattr = nfs_setattr, + .fileattr_get = nfs_fileattr_get, };
include/linux/nfs_fs_sb.h +1 -1
@@ -306,7 +306,7 @@ struct nfs_server {#define NFS_CAP_ATOMIC_OPEN (1U << 4)#define NFS_CAP_LGOPEN (1U << 5)#define NFS_CAP_CASE_INSENSITIVE (1U << 6) -#define NFS_CAP_CASE_PRESERVING (1U << 7) +#define NFS_CAP_CASE_NONPRESERVING (1U << 7)#define NFS_CAP_REBOOT_LAYOUTRETURN (1U << 8)#define NFS_CAP_OFFLOAD_STATUS (1U << 9)#define NFS_CAP_ZERO_RANGE (1U << 10)
include/linux/nfs_xdr.h +2 -0
@@ -182,6 +182,8 @@ struct nfs_pathconf {struct nfs_fattr *fattr;/* Post-op attributes */ __u32 max_link;/* max # of hard links */ __u32 max_namelen;/* max name length */ +bool case_insensitive; +bool case_preserving; };struct nfs4_change_info {
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 11/15 vboxsf: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Upper layers such as NFSD need a way to query whether a filesystem handles filenames in a case-sensitive manner. Report VirtualBox shared folder case handling behavior via the FS_XFLAG_CASEFOLD flag.
The case sensitivity property is queried from the VirtualBox host service at mount time and cached in struct vboxsf_sbi. The host determines case sensitivity based on the underlying host filesystem (for example, Windows NTFS is case-insensitive while Linux ext4 is case-sensitive).
VirtualBox shared folders always preserve filename case exactly as provided by the guest. The host interface does not expose a separate case-preserving property; leaving FS_XFLAG_CASENONPRESERVING unset reports the POSIX-default case-preserving behavior, which matches vboxsf semantics.
The callback is registered in all three inode_operations structures (directory, file, and symlink) to ensure consistent reporting across all inode types.
--- fs/vboxsf/dir.c | 1 + fs/vboxsf/file.c | 6 ++++-- fs/vboxsf/super.c | 7 +++++++ fs/vboxsf/utils.c | 30 ++++++++++++++++++++++++++++++ fs/vboxsf/vfsmod.h | 6 ++++++ 5 files changed, 48 insertions(+), 2 deletions(-)
fs/vboxsf/dir.c +1 -0
@@ -477,4 +477,5 @@ const struct inode_operations vboxsf_dir_iops = { .symlink = vboxsf_dir_symlink, .getattr = vboxsf_getattr, .setattr = vboxsf_setattr, + .fileattr_get = vboxsf_fileattr_get, };
fs/vboxsf/file.c +4 -2
@@ -222,7 +222,8 @@ const struct file_operations vboxsf_reg_fops = {const struct inode_operations vboxsf_reg_iops = { .getattr = vboxsf_getattr, - .setattr = vboxsf_setattr + .setattr = vboxsf_setattr, + .fileattr_get = vboxsf_fileattr_get, };static int vboxsf_read_folio (struct file *file,struct folio *folio)
@@ -389,5 +390,6 @@ static const char *vboxsf_get_link(struct dentry *dentry, struct inode *inode, }const struct inode_operations vboxsf_lnk_iops = { - .get_link = vboxsf_get_link + .get_link = vboxsf_get_link, + .fileattr_get = vboxsf_fileattr_get, };
fs/vboxsf/super.c +7 -0
@@ -185,6 +185,13 @@ static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)if (err) goto fail_unmap; +/* +* A failed query leaves sbi->case_insensitive false, so the +* mount defaults to reporting case-sensitive behavior. Do not +* fail the mount over an advisory attribute. +*/ +vboxsf_query_case_sensitive (sbi); + sb->s_magic =VBOXSF_SUPER_MAGIC ; sb->s_blocksize =1024 ; sb->s_maxbytes =MAX_LFS_FILESIZE ;
fs/vboxsf/utils.c +30 -0
@@ -11,6 +11,7 @@#include <linux/sizes.h> #include <linux/pagemap.h> #include <linux/vfs.h> +#include <linux/fileattr.h> #include "vfsmod.h" struct inode *vboxsf_new_inode (struct super_block *sb)
@@ -567,3 +568,32 @@ int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d,return err; } + +int vboxsf_query_case_sensitive (struct vboxsf_sbi *sbi) +{ +struct shfl_volinfo volinfo = {}; +u32 buf_len; +int err; + + buf_len =sizeof (volinfo); + err =vboxsf_fsinfo (sbi->root,0 ,SHFL_INFO_GET |SHFL_INFO_VOLUME , + &buf_len, &volinfo); +if (err) +return err; +if (buf_len <sizeof (volinfo)) +return 0 ; + + sbi->case_insensitive = !volinfo.properties.case_sensitive; +return 0 ; +} + +int vboxsf_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +struct vboxsf_sbi *sbi =VBOXSF_SBI (dentry->d_sb); + +if (sbi->case_insensitive) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +return 0 ; +}
fs/vboxsf/vfsmod.h +6 -0
@@ -47,6 +47,7 @@ struct vboxsf_sbi {u32 next_generation;u32 root;int bdi_id; +bool case_insensitive; };/* per-inode information */
@@ -111,6 +112,11 @@ void vboxsf_dir_info_free(struct vboxsf_dir_info *p);int vboxsf_dir_read_all (struct vboxsf_sbi *sbi,struct vboxsf_dir_info *sf_d,u64 handle); +int vboxsf_query_case_sensitive (struct vboxsf_sbi *sbi); + +struct file_kattr ; +int vboxsf_fileattr_get (struct dentry *dentry,struct file_kattr *fa); +/* from vboxsf_wrappers.c */ int vboxsf_connect (void );void vboxsf_disconnect (void );
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 12/15 isofs: Implement fileattr_get for case sensitivity
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
Upper layers such as NFSD need a way to query whether a filesystem handles filenames in a case-sensitive manner so they can provide correct semantics to remote clients. Without this information, NFS exports of ISO 9660 filesystems cannot advertise their filename case behavior.
Implement isofs_fileattr_get() to report ISO 9660 case handling behavior. The 'check=r' (relaxed) mount option enables case-insensitive lookups and is reported via FS_XFLAG_CASEFOLD. By default, Joliet extensions operate in relaxed mode while plain ISO 9660 uses strict (case-sensitive) mode.
Plain ISO 9660 names on the medium are uppercase. When neither Rock Ridge nor Joliet is in effect, the default 'map=n' option (and 'map=a') routes lookup and readdir through isofs_name_translate(), which forces A-Z to a-z. The names visible to userspace then differ in case from the on-disc form, so report FS_XFLAG_CASENONPRESERVING in that configuration. Rock Ridge and Joliet both deliver names as authored, and 'map=o' emits the raw on-disc name unchanged, so those configurations remain case-preserving.
Casefolding is a directory property, and the in-tree consumers (NFSD, ksmbd) issue the query against a directory: NFSD walks to the parent for non-directory dentries before calling vfs_fileattr_get(), and ksmbd reports per-share attributes from the share root. Wire .fileattr_get only on isofs_dir_inode_operations. The CASEFOLD flag is set in both fa->fsx_xflags and fa->flags so FS_IOC_FSGETXATTR and FS_IOC_GETFLAGS agree.
--- fs/isofs/dir.c | 16 ++++++++++++++++ fs/isofs/isofs.h | 3 +++ 2 files changed, 19 insertions(+)
fs/isofs/dir.c +16 -0
@@ -14,6 +14,7 @@#include <linux/gfp.h> #include <linux/filelock.h> #include "isofs.h" +#include <linux/fileattr.h> int isofs_name_translate (struct iso_directory_record *de,char *new,struct inode *inode) {
@@ -267,6 +268,20 @@ static int isofs_readdir(struct file *file, struct dir_context *ctx)return result; } +int isofs_fileattr_get (struct dentry *dentry,struct file_kattr *fa) +{ +struct isofs_sb_info *sbi =ISOFS_SB (dentry->d_sb); + +if (sbi->s_check =='r' ) { + fa->fsx_xflags |=FS_XFLAG_CASEFOLD ; + fa->flags |=FS_CASEFOLD_FL ; + } +if (!sbi->s_joliet_level && !sbi->s_rock && + (sbi->s_mapping =='n' || sbi->s_mapping =='a' )) + fa->fsx_xflags |=FS_XFLAG_CASENONPRESERVING ; +return 0 ; +} +const struct file_operations isofs_dir_operations = { .llseek = generic_file_llseek,
@@ -281,6 +296,7 @@ const struct file_operations isofs_dir_operations =const struct inode_operations isofs_dir_inode_operations = { .lookup = isofs_lookup, + .fileattr_get = isofs_fileattr_get, };
fs/isofs/isofs.h +3 -0
@@ -197,6 +197,9 @@ isofs_normalize_block_and_offset(struct iso_directory_record* de, } } +struct file_kattr ; +int isofs_fileattr_get (struct dentry *dentry,struct file_kattr *fa); +extern const struct inode_operations isofs_dir_inode_operations;extern const struct file_operations isofs_dir_operations;extern const struct address_space_operations isofs_symlink_aops;
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 13/15 nfsd: Report export case-folding via NFSv3 PATHCONF
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
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.
--- fs/nfsd/nfs3proc.c | 36 +++++++++++++++++----- fs/nfsd/vfs.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/nfsd/vfs.h | 3 ++ fs/nfsd/xdr3.h | 4 +-- 4 files changed, 121 insertions(+), 10 deletions(-)
fs/nfsd/nfs3proc.c +28 -8
@@ -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 ; } }
fs/nfsd/vfs.c +88 -0
97 lines not on this page · raw message
fs/nfsd/vfs.h +3 -0
@@ -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);
fs/nfsd/xdr3.h +2 -2
@@ -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 {
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 14/15 nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
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.
--- fs/nfsd/nfs4xdr.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-)
fs/nfsd/nfs4xdr.c +49 -3
@@ -3158,6 +3158,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,
@@ -3356,6 +3358,33 @@ 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_homogeneous (struct xdr_stream *xdr, +const struct nfsd4_fattr_args *args) +{ +/* +* Casefold-capable filesystems (e.g. ext4 or f2fs with the +* casefold feature) attach a Unicode encoding at mount time +* but apply case folding per directory. The per-file-system +* case_insensitive and case_preserving values can therefore +* legitimately differ across objects that share the same fsid. +* Report FATTR4_HOMOGENEOUS = FALSE on such filesystems to +* keep that variation consistent with RFC 8881 Section 5.8.2.16. +*/ +return nfsd4_encode_bool (xdr, !sb_has_encoding (args->dentry->d_sb)); +} +static __be32 nfsd4_encode_fattr4_filehandle (struct xdr_stream *xdr,const struct nfsd4_fattr_args *args) {
@@ -3748,8 +3777,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,
@@ -3758,7 +3787,7 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_ops[] = { [FATTR4_FILES_TOTAL] = nfsd4_encode_fattr4_files_total, [FATTR4_FS_LOCATIONS] = nfsd4_encode_fattr4_fs_locations, [FATTR4_HIDDEN] = nfsd4_encode_fattr4__noop, - [FATTR4_HOMOGENEOUS] = nfsd4_encode_fattr4__true, + [FATTR4_HOMOGENEOUS] = nfsd4_encode_fattr4_homogeneous, [FATTR4_MAXFILESIZE] = nfsd4_encode_fattr4_maxfilesize, [FATTR4_MAXLINK] = nfsd4_encode_fattr4_maxlink, [FATTR4_MAXNAME] = nfsd4_encode_fattr4_maxname,
@@ -3968,6 +3997,23 @@ 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 )) { + err =nfsd_get_case_info (dentry, &args.case_insensitive, + &args.case_preserving); +/* +* Per RFC 8881 Section 18.7.3, an attribute advertised +* in SUPPORTED_ATTRS must come back with a value or the +* GETATTR must fail. nfsd_get_case_info() fills POSIX +* defaults and returns -EOPNOTSUPP when the underlying +* filesystem does not expose case state; encode those +* defaults so the reply agrees with what SUPPORTED_ATTRS +* advertises. Other errors fail the operation as the +* spec requires. +*/ +if (err && err != -EOPNOTSUPP ) + goto out_nfserr; + }if (attrmask[0 ] &FATTR4_WORD0_ACL ) { err =nfsd4_get_nfs4_acl (rqstp, dentry, &args.acl);
Signature · 1 line
2.53.0
Chuck Lever
maintainerPATCH v14 15/15 ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION
In reply to Chuck LeverFrom: Chuck Lever <[email protected]>
FS_ATTRIBUTE_INFORMATION responses have always reported FILE_CASE_SENSITIVE_SEARCH and FILE_CASE_PRESERVED_NAMES unconditionally. Case-insensitive filesystems like exFAT, and casefolded directories on ext4 or f2fs, have no way to signal their actual semantics to SMB clients.
Now that filesystems expose case behavior through ->fileattr_get, query it via vfs_fileattr_get() and translate the FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags into the corresponding SMB attributes. Filesystems without ->fileattr_get continue reporting default POSIX behavior (case-sensitive, case-preserving).
SMB's FS_ATTRIBUTE_INFORMATION reports per-share attributes from the share root, not per-file. Shares mixing casefold and non-casefold directories report the root directory's behavior.
--- fs/smb/server/smb2pdu.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-)
fs/smb/server/smb2pdu.c +24 -6
@@ -14,6 +14,7 @@#include <linux/falloc.h> #include <linux/mount.h> #include <linux/filelock.h> +#include <linux/fileattr.h> #include "glob.h" #include "smbfsctl.h"
@@ -5541,16 +5542,33 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,case FS_ATTRIBUTE_INFORMATION : {FILE_SYSTEM_ATTRIBUTE_INFO *info; +struct file_kattr fa = {};size_t sz; +u32 attrs; +int err; info = (FILE_SYSTEM_ATTRIBUTE_INFO *)rsp->Buffer; - info->Attributes =cpu_to_le32 (FILE_SUPPORTS_OBJECT_IDS | -FILE_PERSISTENT_ACLS | -FILE_UNICODE_ON_DISK | -FILE_CASE_PRESERVED_NAMES | -FILE_CASE_SENSITIVE_SEARCH | -FILE_SUPPORTS_BLOCK_REFCOUNTING ); + attrs =FILE_SUPPORTS_OBJECT_IDS | +FILE_PERSISTENT_ACLS | +FILE_UNICODE_ON_DISK | +FILE_SUPPORTS_BLOCK_REFCOUNTING ; + err =vfs_fileattr_get (path.dentry, &fa); +/* +* -EINVAL, -EOPNOTSUPP: ntfs-3g and other FUSE +* filesystems that lack FS_IOC_FSGETXATTR support. +*/ +if (err && err != -ENOIOCTLCMD && err != -ENOTTY && + err != -EINVAL && err != -EOPNOTSUPP ) { +path_put (&path); +return err; + } +if (!(fa.fsx_xflags &FS_XFLAG_CASEFOLD )) + attrs |=FILE_CASE_SENSITIVE_SEARCH ; +if (!(fa.fsx_xflags &FS_XFLAG_CASENONPRESERVING )) + attrs |=FILE_CASE_PRESERVED_NAMES ; + + info->Attributes =cpu_to_le32 (attrs); info->Attributes |=cpu_to_le32 (server_conf.share_fake_fscaps); if (test_share_config_flag(work->tcon->share_conf,
Signature · 1 line
2.53.0
Quoted 8 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Following on from:
[...]
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree. Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase, trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git branch: vfs-7.2.exportfs
[01/15] fs: Move file_kattr initialization to callers
https://git.kernel.org/vfs/vfs/c/9d3942fa6a55 [02/15] fs: Add case sensitivity flags to file_kattr https://git.kernel.org/vfs/vfs/c/72504a889e52 [03/15] fat: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/d0d06cfce960 [04/15] exfat: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/64a4f2090cb2 [05/15] ntfs3: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/5fff53318cbf [06/15] hfs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/1b25c01375e0 [07/15] hfsplus: Report case sensitivity in fileattr_get https://git.kernel.org/vfs/vfs/c/b9e976dd58ff [08/15] xfs: Report case sensitivity in fileattr_get https://git.kernel.org/vfs/vfs/c/30617d630d2f [09/15] cifs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/0f372b05c80c [10/15] nfs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/3ca9954cdc04 [11/15] vboxsf: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/0f5f23d411ac [12/15] isofs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/d56f6094035c [13/15] nfsd: Report export case-folding via NFSv3 PATHCONF https://git.kernel.org/vfs/vfs/c/5ca2c8f14428 [14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING https://git.kernel.org/vfs/vfs/c/62c9555937ca [15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION https://git.kernel.org/vfs/vfs/c/35188379f010
Quoted 4 lines · Christian Brauner
Quoted 3 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Quoted 8 lines
Quoted 5 lines
Following on from:
[...]
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree. Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
Not vfs-7.2-casefold ?
Fwiw, I was intending to rebase nfsd-next on the vfs integration branch, which should have both vfs-7.2-casefold and vfs-7.2.exportfs merged in, along with Jeff's series that implements the infrastructure to support directory delegation properly. LMK if that's crazy talk.
Signature · 1 line
Chuck Lever
Christian Brauner
maintainerQuoted 14 lines · Chuck Lever
Quoted 4 lines · Christian Brauner
Quoted 3 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Quoted 8 lines
Quoted 5 lines
Following on from:
[...]
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree. Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
Quoted 6 lines
Not vfs-7.2-casefold ?
Fwiw, I was intending to rebase nfsd-next on the vfs integration branch, which should have both vfs-7.2-casefold and vfs-7.2.exportfs merged in, along with Jeff's series that implements the infrastructure to support directory delegation properly. LMK if that's crazy talk.
I think you should just merge:
vfs-7.2.exportfs
vfs-7.2.casefold
as the order doesn't matter and they don't depend on each other. I have marked both branches as shared so they won't get touched again. If more ends on either of these branches it doesn't matter to you. IOW, I think you should just pick the minimum you need and then you don't need to hear from again and by the time you send your pull request all the prerequisites will already be in Linus' tree.
If you merge in vfs.all you're subject to problems from rebases. So I'd not recommend that.
Quoted 5 lines · Christian Brauner
Quoted 3 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Quoted 8 lines
Quoted 5 lines
Following on from:
[...]
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree. Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
@Chuck Lever Thank you!
Does that mean the support for case-insensitive filesystems will work with Linux 7.2?
Ced
Signature · 3 lines
Cedric Blancher <[email protected]> [https://plus.google.com/u/0/+CedricBlancher/] Institute Pasteur
Chuck Lever
maintainerQuoted 12 lines · Cedric Blancher
Quoted 11 lines · Christian Brauner
Quoted 8 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Following on from:
[...]
Quoted 7 lines
Quoted 2 lines
Applied to the vfs-7.2.exportfs branch of the vfs/vfs.git tree. Patches in the vfs-7.2.exportfs branch should appear in linux-next soon.
@Chuck Lever Thank you!
Does that mean the support for case-insensitive filesystems will work with Linux 7.2?
I don't want to make claims with 100% certainty, but we expect this series to get merged into 7.2. It's early days, so there are likely to be bugs -- there is so much subtle behavior under the covers.
Signature · 1 line
Chuck Lever
Christian Brauner
maintainerQuoted 2 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Perfect!
Quoted 8 lines · Chuck Lever
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Following on from:
[...]
Now on the correct branch and pushed out.
---
Applied to the vfs-7.2.casefold branch of the vfs/vfs.git tree. Patches in the vfs-7.2.casefold branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase, trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git branch: master
[01/15] fs: Move file_kattr initialization to callers
https://git.kernel.org/vfs/vfs/c/14c3197ecf07 [02/15] fs: Add case sensitivity flags to file_kattr https://git.kernel.org/vfs/vfs/c/3035e4454142 [03/15] fat: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/c92db2ca726f [04/15] exfat: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/27e0b573dd4a [05/15] ntfs3: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/eeb7b37b9700 [06/15] hfs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/b6fe046c3023 [07/15] hfsplus: Report case sensitivity in fileattr_get https://git.kernel.org/vfs/vfs/c/a6469a15eefe [08/15] xfs: Report case sensitivity in fileattr_get https://git.kernel.org/vfs/vfs/c/c9da43e4e5c3 [09/15] cifs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/e50bc12f5a36 [10/15] nfs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/92d67628a1a9 [11/15] vboxsf: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/ef14aa143f1d [12/15] isofs: Implement fileattr_get for case sensitivity https://git.kernel.org/vfs/vfs/c/7bbd51b1d748 [13/15] nfsd: Report export case-folding via NFSv3 PATHCONF https://git.kernel.org/vfs/vfs/c/211cb2ba4877 [14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING https://git.kernel.org/vfs/vfs/c/01ee7c3d2e23 [15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION https://git.kernel.org/vfs/vfs/c/0164df1d1de7
This series was applied to jaegeuk/f2fs.git (dev) by Christian Brauner <[email protected]>:
Hello:
This series was applied to jaegeuk/f2fs.git (dev)
by Christian Brauner <[email protected]>:
Quoted 8 lines · On Thu, 07 May 2026 04:52:53 -0400 you wrote:
Christian, let's lock this one in. I will post subsequent changes as delta patches.
Following on from:
[...]
Here is the summary with links:
- [f2fs-dev,v14,01/15] fs: Move file_kattr initialization to callers
https://git.kernel.org/jaegeuk/f2fs/c/14c3197ecf07 - [f2fs-dev,v14,02/15] fs: Add case sensitivity flags to file_kattr https://git.kernel.org/jaegeuk/f2fs/c/3035e4454142 - [f2fs-dev,v14,03/15] fat: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/c92db2ca726f - [f2fs-dev,v14,04/15] exfat: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/27e0b573dd4a - [f2fs-dev,v14,05/15] ntfs3: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/eeb7b37b9700 - [f2fs-dev,v14,06/15] hfs: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/b6fe046c3023 - [f2fs-dev,v14,07/15] hfsplus: Report case sensitivity in fileattr_get https://git.kernel.org/jaegeuk/f2fs/c/a6469a15eefe - [f2fs-dev,v14,08/15] xfs: Report case sensitivity in fileattr_get https://git.kernel.org/jaegeuk/f2fs/c/c9da43e4e5c3 - [f2fs-dev,v14,09/15] cifs: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/e50bc12f5a36 - [f2fs-dev,v14,10/15] nfs: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/92d67628a1a9 - [f2fs-dev,v14,11/15] vboxsf: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/ef14aa143f1d - [f2fs-dev,v14,12/15] isofs: Implement fileattr_get for case sensitivity https://git.kernel.org/jaegeuk/f2fs/c/7bbd51b1d748 - [f2fs-dev,v14,13/15] nfsd: Report export case-folding via NFSv3 PATHCONF https://git.kernel.org/jaegeuk/f2fs/c/211cb2ba4877 - [f2fs-dev,v14,14/15] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING https://git.kernel.org/jaegeuk/f2fs/c/01ee7c3d2e23 - [f2fs-dev,v14,15/15] ksmbd: Report filesystem case sensitivity via FS_ATTRIBUTE_INFORMATION https://git.kernel.org/jaegeuk/f2fs/c/0164df1d1de7
You are awesome, thank you!
Signature · 2 lines
Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html