]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: Report case sensitivity in fileattr_get
authorChuck Lever <chuck.lever@oracle.com>
Thu, 7 May 2026 08:53:01 +0000 (04:53 -0400)
committerChristian Brauner <brauner@kernel.org>
Mon, 11 May 2026 14:50:29 +0000 (16:50 +0200)
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.

Reviewed-by: Roland Mainz <roland.mainz@nrubsig.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260507-case-sensitivity-v14-8-e62cc8200435@oracle.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
fs/xfs/libxfs/xfs_inode_util.c
fs/xfs/xfs_ioctl.c

index 551fa51befb65e343e496fa4d5413e7303d67978..82be54b6f8d3a8d050dd5435ef29fa23491e542d 100644 (file)
@@ -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;
 }
 
index ed9b4846c05ff86fcb948932212ff67bc7591cf4..f8216f74679fde5b5431e490165210280f2fe407 100644 (file)
@@ -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;
        }