From: Chuck Lever Report NTFS case sensitivity behavior via the new file_kattr case_info field. NTFS always preserves case at rest. Case sensitivity depends on mount options: with "nocase", NTFS performs Unicode case-insensitive matching; otherwise it is case-sensitive. Signed-off-by: Chuck Lever --- fs/ntfs3/file.c | 27 +++++++++++++++++++++++++++ fs/ntfs3/inode.c | 1 + fs/ntfs3/namei.c | 2 ++ fs/ntfs3/ntfs_fs.h | 1 + 4 files changed, 31 insertions(+) diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 4c90ec2fa2ea..35892988b788 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -104,6 +104,32 @@ long ntfs_compat_ioctl(struct file *filp, u32 cmd, unsigned long arg) } #endif +/* + * ntfs_fileattr_get - inode_operations::fileattr_get + */ +int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa) +{ + struct inode *inode = d_inode(dentry); + struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info; + + /* Avoid any operation if inode is bad. */ + if (unlikely(is_bad_ni(ntfs_i(inode)))) + return -EINVAL; + + /* + * NTFS preserves case. Case sensitivity depends on mount options: + * with "nocase" mount option, NTFS is case-insensitive using + * Unicode case folding; otherwise it is case-sensitive. + */ + if (sbi->options && sbi->options->nocase) + fa->case_info = FILEATTR_CASEFOLD_UNICODE | + FILEATTR_CASE_PRESERVING; + else + fa->case_info = FILEATTR_CASEFOLD_NONE | + FILEATTR_CASE_PRESERVING; + return 0; +} + /* * ntfs_getattr - inode_operations::getattr */ @@ -1383,6 +1409,7 @@ const struct inode_operations ntfs_file_inode_operations = { .get_acl = ntfs_get_acl, .set_acl = ntfs_set_acl, .fiemap = ntfs_fiemap, + .fileattr_get = ntfs_fileattr_get, }; const struct file_operations ntfs_file_operations = { diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 3959f23c487a..ecdea6d83980 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -2085,6 +2085,7 @@ const struct inode_operations ntfs_link_inode_operations = { .get_link = ntfs_get_link, .setattr = ntfs_setattr, .listxattr = ntfs_listxattr, + .fileattr_get = ntfs_fileattr_get, }; const struct address_space_operations ntfs_aops = { diff --git a/fs/ntfs3/namei.c b/fs/ntfs3/namei.c index 82c8ae56beee..2094e5409e43 100644 --- a/fs/ntfs3/namei.c +++ b/fs/ntfs3/namei.c @@ -519,6 +519,7 @@ const struct inode_operations ntfs_dir_inode_operations = { .getattr = ntfs_getattr, .listxattr = ntfs_listxattr, .fiemap = ntfs_fiemap, + .fileattr_get = ntfs_fileattr_get, }; const struct inode_operations ntfs_special_inode_operations = { @@ -527,6 +528,7 @@ const struct inode_operations ntfs_special_inode_operations = { .listxattr = ntfs_listxattr, .get_acl = ntfs_get_acl, .set_acl = ntfs_set_acl, + .fileattr_get = ntfs_fileattr_get, }; const struct dentry_operations ntfs_dentry_ops = { diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index 630128716ea7..a178ca66e2e0 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -503,6 +503,7 @@ extern const struct file_operations ntfs_dir_operations; extern const struct file_operations ntfs_legacy_dir_operations; /* Globals from file.c */ +int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa); int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, u32 flags); int ntfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry, -- 2.52.0