[uapi change, so add linux-api]
On Tue, Jan 20, 2026 at 04:48:31PM -0500, Chuck Lever wrote:
>
>
> On Tue, Jan 20, 2026, at 12:26 PM, Darrick J. Wong wrote:
> > On Tue, Jan 20, 2026 at 09:24:24AM -0500, Chuck Lever wrote:
> >> From: 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. These flags are read-only; userspace cannot set
> >> them via ioctl.
> >>
> >> Relocate struct file_kattr initialization from fileattr_fill_xflags()
> >> and fileattr_fill_flags() to vfs_fileattr_get() and the ioctl/syscall
> >> call sites. This allows filesystem ->fileattr_get() callbacks to set
> >> flags directly in fa->fsx_xflags before invoking the fill functions,
> >> which previously would have zeroed those values. Callers that bypass
> >> vfs_fileattr_get() must now zero-initialize the struct themselves.
> >>
> >> Case sensitivity information is exported to userspace via the
> >> fa_xflags field in the FS_IOC_FSGETXATTR ioctl and file_getattr()
> >> system call.
> >>
> >> Signed-off-by: Chuck Lever <[email protected]>
> >> ---
> >> fs/file_attr.c | 14 ++++++--------
> >> fs/xfs/xfs_ioctl.c | 2 +-
> >> include/linux/fileattr.h | 3 ++-
> >> include/uapi/linux/fs.h | 2 ++
> >
> > This ought to go to linux-api because you're changing the userspace api.
> > Granted it's only adding a flag definition to an existing ioctl, but
> > FS_XFLAG_CASEFOLD /does/ collide with Andrey's fsverity xflag patch...
> >
> > (The rest of the changes looks ok to me.)
>
> Process question for Christian: Do you want to see a v7 of this
> series with Cc: linux-api before proceeding, or are you taking
> both Andrey's and mine and can resolve the conflict, or ... ?
Well now that I've griped at both patchsets on the same public list,
I'll at least chime in that I'd be satisfied if whoever decides to merge
them to fix up the conflicts whenever they merge them. :)
--D
>
> > --D
> >
> >> 4 files changed, 11 insertions(+), 10 deletions(-)
> >>
> >> diff --git a/fs/file_attr.c b/fs/file_attr.c
> >> index 13cdb31a3e94..2700200c5b9c 100644
> >> --- a/fs/file_attr.c
> >> +++ b/fs/file_attr.c
> >> @@ -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)
> >> @@ -46,11 +44,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)
> >> @@ -84,6 +80,8 @@ int vfs_fileattr_get(struct dentry *dentry, struct
> >> file_kattr *fa)
> >> struct inode *inode = d_inode(dentry);
> >> int error;
> >>
> >> + memset(fa, 0, sizeof(*fa));
> >> +
> >> if (!inode->i_op->fileattr_get)
> >> return -ENOIOCTLCMD;
> >>
> >> @@ -323,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;
> >>
> >> @@ -355,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);
> >> @@ -434,7 +432,7 @@ SYSCALL_DEFINE5(file_setattr, int, dfd, const char
> >> __user *, filename,
> >> struct filename *name __free(putname) = NULL;
> >> 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);
> >> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> >> index 59eaad774371..f0417c4d1fca 100644
> >> --- a/fs/xfs/xfs_ioctl.c
> >> +++ b/fs/xfs/xfs_ioctl.c
> >> @@ -496,7 +496,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);
> >> diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h
> >> index f89dcfad3f8f..709de829659f 100644
> >> --- a/include/linux/fileattr.h
> >> +++ b/include/linux/fileattr.h
> >> @@ -16,7 +16,8 @@
> >>
> >> /* Read-only inode flags */
> >> #define FS_XFLAG_RDONLY_MASK \
> >> - (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR)
> >> + (FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | \
> >> + FS_XFLAG_CASEFOLD | FS_XFLAG_CASENONPRESERVING)
> >>
> >> /* Flags to indicate valid value of fsx_ fields */
> >> #define FS_XFLAG_VALUES_MASK \
> >> diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h
> >> index 66ca526cf786..919148beaa8c 100644
> >> --- a/include/uapi/linux/fs.h
> >> +++ b/include/uapi/linux/fs.h
> >> @@ -253,6 +253,8 @@ struct file_attr {
> >> #define FS_XFLAG_FILESTREAM 0x00004000 /* use filestream
> >> allocator */
> >> #define FS_XFLAG_DAX 0x00008000 /* use DAX for IO */
> >> #define FS_XFLAG_COWEXTSIZE 0x00010000 /* CoW extent size
> >> allocator hint */
> >> +#define FS_XFLAG_CASEFOLD 0x00020000 /* case-insensitive lookups */
> >> +#define FS_XFLAG_CASENONPRESERVING 0x00040000 /* 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
> >> --
> >> 2.52.0
> >>
> >>
>
> --
> Chuck Lever
>
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel