summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2026-05-07 11:53:00 +0300
committerChristian Brauner <brauner@kernel.org>2026-05-11 17:50:28 +0300
commita6469a15eefe10e8c5e49eb80cc38dbe94803ea9 (patch)
tree461ee79bc4a06a05b120d9149a6359518e747fb7
parentb6fe046c30236e37e3f8c500cf5b1297c317c5ee (diff)
downloadlinux-a6469a15eefe10e8c5e49eb80cc38dbe94803ea9.tar.xz
hfsplus: Report case sensitivity in fileattr_get
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. Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> 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-7-e62cc8200435@oracle.com Signed-off-by: Christian Brauner <brauner@kernel.org>
-rw-r--r--fs/hfsplus/inode.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index d05891ec492e..5565c14b4bf6 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -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)