From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E001305045; Thu, 11 Dec 2025 15:21:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466513; cv=none; b=B4Hdg4w2Jjnr6gxideFTnV2QzGvuLlP+nigrzS0MT90oDGBt5r0OV8BZE3tG/Ze0DwWioIko8QS6gPwleZo6meWucEnP4JQPhDyORs36fOEYDgwkX79jYxb+o8I7+3/YoJ3pLtxsE5MLxFPbLuCg994AMX2vhb6drJESjuhbers= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466513; c=relaxed/simple; bh=ft1yumL/UkaBBj1cS/NCcXPiVJR2SF6VLxtN7WaKeTc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Bnp3gY5KknIJVwaim6BOtRq4tJdA7ysUqaG72OE7OusRuuWi7gnsM5RifmPe8zZhTWBiWD03BBhGgOH0CzUQNn24agg7RaIirwlc1DO4AP3vZs286AhcAwu+YIhptOpcrkL/lr3T3C/7svRITsWMfHqrUzITvPidbisTyQgpLJQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Mehz8o2k; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Mehz8o2k" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4213EC19421; Thu, 11 Dec 2025 15:21:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466513; bh=ft1yumL/UkaBBj1cS/NCcXPiVJR2SF6VLxtN7WaKeTc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Mehz8o2kBU6vMgGJuuHn+eGoQQS90Rfjka5NEBL1VX1BkBl5C6TPvCN6eJ8ZpZN9Q uRHTagEO0pQg8mHAzi4nGA7RxCvdLIh3nkgwNxpmBdiGX1zzg9wDzO/935sPZamssa 1X3GhUBLxEAf38kWrGLMGdtLyAyrc+4MVYJB06k9chBivfCf/YjImcjflNf1RpuXOf UqcEHKB8Ms0oMlNlHDsugtCh/YYSwaFDjh3XVCXmAkTqb79CDJ3QnDdBrx4IVhERct S21JK2gaqq+5JEARBHJaPzmGN3/pSTzLcgP4y1nvo/JpCEy+Z8iKizA3YoKGRMMkUc b/okq6Wrm6Xeg== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 1/6] fs: Add case sensitivity info to file_kattr Date: Thu, 11 Dec 2025 10:21:11 -0500 Message-ID: <20251211152116.480799-2-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chuck Lever Enable upper layers such as NFSD to retrieve case sensitivity information from file systems by adding a case_info field to struct file_kattr. Add vfs_get_case_info() as a convenience helper for kernel consumers. If a filesystem does not provide a fileattr_get hook, it returns the default POSIX behavior (case-sensitive, case-preserving), which is correct for the majority of Linux file systems implementations. Signed-off-by: Chuck Lever --- fs/file_attr.c | 31 +++++++++++++++++++++++++++++++ include/linux/fileattr.h | 23 +++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/fs/file_attr.c b/fs/file_attr.c index 1dcec88c0680..609e890b5101 100644 --- a/fs/file_attr.c +++ b/fs/file_attr.c @@ -94,6 +94,37 @@ int vfs_fileattr_get(struct dentry *dentry, struct file_= kattr *fa) } EXPORT_SYMBOL(vfs_fileattr_get); =20 +/** + * vfs_get_case_info - retrieve case sensitivity info for a filesystem + * @dentry: the object to retrieve from + * @case_info: pointer to store result + * + * Call i_op->fileattr_get() to retrieve case sensitivity information. + * If the filesystem does not provide a fileattr_get hook, return + * the default POSIX behavior (case-sensitive, case-preserving). + * + * Return: 0 on success, or a negative error on failure. + */ +int vfs_get_case_info(struct dentry *dentry, u32 *case_info) +{ + struct file_kattr fa =3D {}; + int error; + + /* Default: POSIX semantics (case-sensitive, case-preserving) */ + *case_info =3D FILEATTR_CASEFOLD_NONE | FILEATTR_CASE_PRESERVING; + + error =3D vfs_fileattr_get(dentry, &fa); + if (error =3D=3D -ENOIOCTLCMD) + return 0; + if (error) + return error; + + if (fa.case_info) + *case_info =3D fa.case_info; + return 0; +} +EXPORT_SYMBOL(vfs_get_case_info); + static void fileattr_to_file_attr(const struct file_kattr *fa, struct file_attr *fattr) { diff --git a/include/linux/fileattr.h b/include/linux/fileattr.h index f89dcfad3f8f..55674d14f697 100644 --- a/include/linux/fileattr.h +++ b/include/linux/fileattr.h @@ -48,11 +48,33 @@ struct file_kattr { u32 fsx_nextents; /* nextents field value (get) */ u32 fsx_projid; /* project identifier (get/set) */ u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/ + u32 case_info; /* case sensitivity behavior */ /* selectors: */ bool flags_valid:1; bool fsx_valid:1; }; =20 +/* + * Values for file_kattr.case_info. + */ + +/* File name case is preserved at rest. */ +#define FILEATTR_CASE_PRESERVING 0x80000000 + +/* Values stored in the low-order byte */ +enum fileattr_case_folding { + /* Code points are compared directly with no case folding. */ + FILEATTR_CASEFOLD_NONE =3D 0, + + /* ASCII case-insensitive: A-Z are treated as a-z. */ + FILEATTR_CASEFOLD_ASCII, + + /* Unicode case-insensitive matching. */ + FILEATTR_CASEFOLD_UNICODE, +}; + +#define FILEATTR_CASEFOLD_TYPE 0x000000ff + int copy_fsxattr_to_user(const struct file_kattr *fa, struct fsxattr __use= r *ufa); =20 void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags); @@ -75,6 +97,7 @@ static inline bool fileattr_has_fsx(const struct file_kat= tr *fa) int vfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa); int vfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct file_kattr *fa); +int vfs_get_case_info(struct dentry *dentry, u32 *case_info); int ioctl_getflags(struct file *file, unsigned int __user *argp); int ioctl_setflags(struct file *file, unsigned int __user *argp); int ioctl_fsgetxattr(struct file *file, void __user *argp); --=20 2.52.0 From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F2ED30C375; Thu, 11 Dec 2025 15:21:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466514; cv=none; b=sN2E4k4xMQhukV2Sp2QQrf+2c0YYp+ZQIpRU5Wmu0F5WRvQDV864bQRQX3ZfjiSIifpPlhfcD54hMpbUF9CtaPWckMoPF3K/ztSjQWSXXVsHq9lKMj+dK3l+jHQiEwEXpCrquKTb8rEjn5Zt/zJXTv0Bz1nPiqBoeNAsmjykp7g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466514; c=relaxed/simple; bh=K1wmSwwV16UCXsb+WMuc89ImO4HAvc1BlSZXGBLXsJI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=X1LeDCXA3QfoVP/+SVXZcqxfYDzEoI/Ge0aedP8z6l1Tc7qMyG7B5F7PqKwNBajwOr0a+o+wOPFQ+nRKGRsLOl0bdoNm8jP6/TKDulDYgd32laVKF7IcKF806yF11X+8l4Ie+B2HO7FF1vplprI3a15rdiFwbQbmoWxv0LfGyNI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pV8/8K1O; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pV8/8K1O" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 47EDFC113D0; Thu, 11 Dec 2025 15:21:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466514; bh=K1wmSwwV16UCXsb+WMuc89ImO4HAvc1BlSZXGBLXsJI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pV8/8K1Og3qagDhBNXc30nTBODvLIkbwkXBr7rnTBqFxf8VExwjg6xSt6fhHlUHz6 7+pArY4cDEvTXcPic7jBgNrcESwmmBp2/ex4nEYisoValbTusRIcsOO7/tVVM91RrW K0DzyodDCq4IumgbrBXCPAgbQRMVTdtyGIzR5ikdMofYhy+CNo1dta5pPb5gPfR7Un 7xg7lWMZeYkO0EPQiWRrjHdcVXn26EMMV9UZJgYS43uzDQ2tUpipKgFsxEh3YGUjWH fk/OeigJQhTjwrL/xU2V/UExbjzjtG0CymxTr1M7AZrIp+qwPDdVcCvKjCv1BLP/iZ MLiphy9qs+qwg== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 2/6] fat: Implement fileattr_get for case sensitivity Date: Thu, 11 Dec 2025 10:21:12 -0500 Message-ID: <20251211152116.480799-3-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chuck Lever Report FAT's case sensitivity behavior via the new file_kattr case_info field. FAT filesystems are case-insensitive and do not preserve case at rest (stored names are uppercased). The case folding type depends on the mount options: when utf8 is enabled, Unicode case folding is used; otherwise ASCII case folding. Signed-off-by: Chuck Lever --- fs/fat/fat.h | 3 +++ fs/fat/file.c | 18 ++++++++++++++++++ fs/fat/namei_msdos.c | 1 + fs/fat/namei_vfat.c | 1 + 4 files changed, 23 insertions(+) diff --git a/fs/fat/fat.h b/fs/fat/fat.h index d3e426de5f01..38da08d8fec4 100644 --- a/fs/fat/fat.h +++ b/fs/fat/fat.h @@ -10,6 +10,8 @@ #include #include =20 +struct file_kattr; + /* * vfat shortname flags */ @@ -407,6 +409,7 @@ extern void fat_truncate_blocks(struct inode *inode, lo= ff_t offset); extern int fat_getattr(struct mnt_idmap *idmap, const struct path *path, struct kstat *stat, u32 request_mask, unsigned int flags); +extern 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); =20 diff --git a/fs/fat/file.c b/fs/fat/file.c index 4fc49a614fb8..123f4c1efdf4 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "fat.h" =20 static long fat_fallocate(struct file *file, int mode, @@ -395,6 +396,22 @@ void fat_truncate_blocks(struct inode *inode, loff_t o= ffset) fat_flush_inodes(inode->i_sb, inode, NULL); } =20 +int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa) +{ + struct inode *inode =3D d_inode(dentry); + struct msdos_sb_info *sbi =3D MSDOS_SB(inode->i_sb); + + /* + * FAT filesystems do not preserve case: stored names are + * uppercased. They are case-insensitive, using either ASCII + * or Unicode comparison depending on mount options. + */ + fa->case_info =3D sbi->options.utf8 ? + FILEATTR_CASEFOLD_UNICODE : FILEATTR_CASEFOLD_ASCII; + 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) { @@ -574,5 +591,6 @@ EXPORT_SYMBOL_GPL(fat_setattr); const struct inode_operations fat_file_inode_operations =3D { .setattr =3D fat_setattr, .getattr =3D fat_getattr, + .fileattr_get =3D fat_fileattr_get, .update_time =3D fat_update_time, }; diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 0b920ee40a7f..380add5c6c66 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -640,6 +640,7 @@ static const struct inode_operations msdos_dir_inode_op= erations =3D { .rename =3D msdos_rename, .setattr =3D fat_setattr, .getattr =3D fat_getattr, + .fileattr_get =3D fat_fileattr_get, .update_time =3D fat_update_time, }; =20 diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 5dbc4cbb8fce..6cf513f97afa 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1180,6 +1180,7 @@ static const struct inode_operations vfat_dir_inode_o= perations =3D { .rename =3D vfat_rename2, .setattr =3D fat_setattr, .getattr =3D fat_getattr, + .fileattr_get =3D fat_fileattr_get, .update_time =3D fat_update_time, }; =20 --=20 2.52.0 From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7B212311971; Thu, 11 Dec 2025 15:21:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466515; cv=none; b=DrH0bd/1d/9Pi0TE0bQ7M8xOi2nWw2vkAf/B4rpHmAXg4VJkPUmbU7sskN9sioYykV54PFYSM3geeRcOjVTcFQPvmBWPR+/AwwRieSBLoORPFYkoiiu5ibCfm7Ya63HjAgAeS1ilrxl8pQ78Cmib2G8pn10r7rFKox4aLY9wUyM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466515; c=relaxed/simple; bh=8krsME7lzQGAnvbq2w/PdMk4UoQLtKDmlNA0rgLt2ug=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Z0MyHzHvYCW50t0vikVYIzQcIB+xRJlhFZlPLeCOgIU6Ds2Mspspi6Le0+yY7Q5P5PUNa0Rdl2JpKkLW+waRbSmvShIsxDjjMmoBCyaBJ8h5X07ywhop2j4KNX9smomQVwRfkgmpPWm8YOsfKdyu3e17adfkMoQtGujnMRLLEkk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DA8LBLVP; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DA8LBLVP" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4BBC5C16AAE; Thu, 11 Dec 2025 15:21:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466515; bh=8krsME7lzQGAnvbq2w/PdMk4UoQLtKDmlNA0rgLt2ug=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=DA8LBLVPJBxAMJgmBwZ24pOvlFMXsf9ZuUhctBhmcHrThXFqDKeLZb63VjW/wrreo UOLE0u/W4tAkYOcaiVaAsUYa11vbnHIEOOTchJb6aQzAd2WdqKPQdx1zqSnJYm3ZUb eYsKHcAFBTn55u0takpkaA92Wkymv7TQfQSmK03wdPIMN+H3oUvfhCPWritacyRsO+ ws0VZabcmbQlGsg+bslT2f7OqrOmMDH2p3n510z9JW+DPIbCEeelzZo5gdPgcQOCLB IGqP+Zb0/0Dq1KwfgF0YCQymRsVRczjj/8UATnrnIIpC89Ld7q/UF0Uisy7TymBOiq yth3/87uuaFCw== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 3/6] ntfs3: Implement fileattr_get for case sensitivity Date: Thu, 11 Dec 2025 10:21:13 -0500 Message-ID: <20251211152116.480799-4-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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, uns= igned long arg) } #endif =20 +/* + * ntfs_fileattr_get - inode_operations::fileattr_get + */ +int ntfs_fileattr_get(struct dentry *dentry, struct file_kattr *fa) +{ + struct inode *inode =3D d_inode(dentry); + struct ntfs_sb_info *sbi =3D 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 =3D FILEATTR_CASEFOLD_UNICODE | + FILEATTR_CASE_PRESERVING; + else + fa->case_info =3D FILEATTR_CASEFOLD_NONE | + FILEATTR_CASE_PRESERVING; + return 0; +} + /* * ntfs_getattr - inode_operations::getattr */ @@ -1383,6 +1409,7 @@ const struct inode_operations ntfs_file_inode_operati= ons =3D { .get_acl =3D ntfs_get_acl, .set_acl =3D ntfs_set_acl, .fiemap =3D ntfs_fiemap, + .fileattr_get =3D ntfs_fileattr_get, }; =20 const struct file_operations ntfs_file_operations =3D { 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_operati= ons =3D { .get_link =3D ntfs_get_link, .setattr =3D ntfs_setattr, .listxattr =3D ntfs_listxattr, + .fileattr_get =3D ntfs_fileattr_get, }; =20 const struct address_space_operations ntfs_aops =3D { 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= =3D { .getattr =3D ntfs_getattr, .listxattr =3D ntfs_listxattr, .fiemap =3D ntfs_fiemap, + .fileattr_get =3D ntfs_fileattr_get, }; =20 const struct inode_operations ntfs_special_inode_operations =3D { @@ -527,6 +528,7 @@ const struct inode_operations ntfs_special_inode_operat= ions =3D { .listxattr =3D ntfs_listxattr, .get_acl =3D ntfs_get_acl, .set_acl =3D ntfs_set_acl, + .fileattr_get =3D ntfs_fileattr_get, }; =20 const struct dentry_operations ntfs_dentry_ops =3D { 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; =20 /* 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, --=20 2.52.0 From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 806503128AC; Thu, 11 Dec 2025 15:21:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466516; cv=none; b=Z+iAOpvHRGTcWIepEwn7CmeqvMhP6PRmGit4GM/vGwCi1skbdhD4OEsnPeZzXPIpzbik41s6J1qJ+YuJtgNGEFnB8sUBRWRe4vgtpaDhrg82RCfiMqfKZU4lXmseqV2Kh2HjQ9X74Lj7Ky2Tjsbq7jK/awZsxxnVQLNLpu9x3lU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466516; c=relaxed/simple; bh=xKTkBQxvzaKb2/BHpHJKS548Bqa8fPqHgj5k2JtaR0U=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pKDi9aUJGG3Zb7KiylCO5Mfzdj85fmpbU4FXa6wa1mjwwNHPgkYrrIyim9ZA1I28xPlPf+tNPgq8GZ8DcxLR+hCg6pcFUpgveLFqiNyAdlkVbdjlUk0DY8ATAqtQ0MKOu00U9PK5dtIlO1xtEkFkvQE6Xuux/5YP3au9EJMUmTY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=p8LCE3PD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="p8LCE3PD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 54913C113D0; Thu, 11 Dec 2025 15:21:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466516; bh=xKTkBQxvzaKb2/BHpHJKS548Bqa8fPqHgj5k2JtaR0U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=p8LCE3PDI0L8GG1v6klE0Os1Q/pTcVw8vhzm2WuwuRz7KklyWihdL3lF2ccmM4aih oI2/yZm/5/L9LmKmGQ6clFIMMIJlVTR71EmL3la1UW8WpGbPWwbJ7R6mA7vPFozISM XpO1XAYaZx7be3b4Aia4xTaZUWw4UqMq9LXIDjShOLPseWERIjyWMbIKZznIKxTaBQ GQhm8OpXEDavN3/qSsie4LZFbu3PV0VIja6JP2Tm5oFRDpWtQDXV6xfk4gguT/RkgW qmJ/uNUUpsE2qvtRkPWN/dfQQNL7e6eiNxMs4Sb9ZGm1APC/JSt3eIx/rnLibGP7XZ eZctnHuouMmFw== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 4/6] ext4: Report case sensitivity in fileattr_get Date: Thu, 11 Dec 2025 10:21:14 -0500 Message-ID: <20251211152116.480799-5-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chuck Lever Report ext4's case sensitivity behavior via file_kattr.case_info. ext4 always preserves case at rest. Case sensitivity is a per-directory setting in ext4. If the queried inode is a casefolded directory, report Unicode case-insensitive matching; otherwise report case-sensitive (standard POSIX behavior). This enables file_getattr to report the case sensitivity behavior of individual directories within an ext4 filesystem. Signed-off-by: Chuck Lever --- fs/ext4/ioctl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index a93a7baae990..d760657bb9e2 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -996,6 +996,18 @@ int ext4_fileattr_get(struct dentry *dentry, struct fi= le_kattr *fa) if (ext4_has_feature_project(inode->i_sb)) fa->fsx_projid =3D from_kprojid(&init_user_ns, ei->i_projid); =20 + /* + * ext4 always preserves case. If this inode is a casefolded + * directory, report Unicode case-insensitive; otherwise + * report case-sensitive (standard POSIX behavior). + */ + if (IS_CASEFOLDED(inode)) + fa->case_info =3D FILEATTR_CASEFOLD_UNICODE | + FILEATTR_CASE_PRESERVING; + else + fa->case_info =3D FILEATTR_CASEFOLD_NONE | + FILEATTR_CASE_PRESERVING; + return 0; } =20 --=20 2.52.0 From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4BFED304BA8; Thu, 11 Dec 2025 15:21:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466517; cv=none; b=JOZGriuE9lkItZ57MJr+bsd+9kZG7RXVCDFqL0UfQXJd6eqCXWpaO3fb7kezdliHfXwUDEmUopeJGbWHCzW12j8BI3ktF6bsS5yihetavouOJywCMOCoBfyZaOgGMZtukIcbg222Vlr76DvQGpICMrZLv+Sf1EkFbI770L3FxX4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466517; c=relaxed/simple; bh=U7ryZOjkKzyCRiNm/3E/bSllYVtAQKU16z9oyKpwqt0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s6QTa/AnHsYwyU35FF4JKvr5PGXvKzDhruE3jDu0CYl5hsaTtHSNygTnUPtrgVx16Iyz1YzgO8JvCUVUEEhmpgvu3imzr4XdwNzBXRTsrK6ApqQqBPlUc3GvIvk8xLALlODWNzeg5w2toD20kAHe5ahMXHgBJUnHEF5dID2/+2I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=aaxXQ/lY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="aaxXQ/lY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 597A6C4CEF7; Thu, 11 Dec 2025 15:21:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466517; bh=U7ryZOjkKzyCRiNm/3E/bSllYVtAQKU16z9oyKpwqt0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aaxXQ/lYsBHNoq+e4Zte/y/Su97YYlGa6K5nufOfFMGHEOXmMa6H52+WVldbHLOM7 ToQDH8xKrtTFzq9tH9Xijd6xDHfLFY0eb+aqeBKKDFHZKehJ0UBUbf8LPniGYiTU1L cHj9p/bPc9fG8mH9GTtW1QJ6hHSy51velk4Ketjf/yUQE0egPAUGyljUgue01qWAh3 Iqqz8xCJ01ulDZh/48Ghzwb+d7z3DrXP1LK8BuxN6KU7TDE4ZbVTXg0cdgsBzg35uz XPfS92vu02T7PUKC/C06z2Ywb/SNdLl9tLy317QFy1cljb86CbYhfafhvNxxSsBlWx 9W9RWGRHQi4nQ== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 5/6] nfsd: Report export case-folding via NFSv3 PATHCONF Date: Thu, 11 Dec 2025 10:21:15 -0500 Message-ID: <20251211152116.480799-6-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chuck Lever Replace the hard-coded MSDOS_SUPER_MAGIC check in nfsd3_proc_pathconf() with a real check of the export's case behavior settings. Filesystems that implement ->fileattr_get can then report their case sensitivity behavior to NFSv3 clients. For filesystems without ->fileattr_get, the default POSIX behavior (case-sensitive, case-preserving) is reported to NFSv3 clients. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 18 ++++++++++-------- fs/nfsd/vfs.c | 25 +++++++++++++++++++++++++ fs/nfsd/vfs.h | 2 ++ 3 files changed, 37 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index b6d03e1ef5f7..c8c76819cfbc 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -721,17 +721,19 @@ nfsd3_proc_pathconf(struct svc_rqst *rqstp) =20 if (resp->status =3D=3D nfs_ok) { struct super_block *sb =3D argp->fh.fh_dentry->d_sb; + bool case_insensitive, case_preserving; =20 - /* Note that we don't care for remote fs's here */ - switch (sb->s_magic) { - case EXT2_SUPER_MAGIC: + if (sb->s_magic =3D=3D EXT2_SUPER_MAGIC) { resp->p_link_max =3D EXT2_LINK_MAX; resp->p_name_max =3D EXT2_NAME_LEN; - break; - case MSDOS_SUPER_MAGIC: - resp->p_case_insensitive =3D 1; - resp->p_case_preserving =3D 0; - break; + } + + resp->status =3D nfsd_get_case_info(&argp->fh, + &case_insensitive, + &case_preserving); + if (resp->status =3D=3D nfs_ok) { + resp->p_case_insensitive =3D case_insensitive; + resp->p_case_preserving =3D case_preserving; } } =20 diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 9cb20d4aeab1..157ddf405a5d 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -32,6 +32,7 @@ #include #include #include +#include =20 #include "xdr3.h" =20 @@ -2679,3 +2680,27 @@ nfsd_permission(struct svc_cred *cred, struct svc_ex= port *exp, =20 return err? nfserrno(err) : 0; } + +/** + * nfsd_get_case_info - get case sensitivity info for a file handle + * @fhp: file handle that has already been verified + * @case_insensitive: output, true if the filesystem is case-insensitive + * @case_preserving: output, true if the filesystem preserves case + * + * Returns nfs_ok on success, or an nfserr on failure. + */ +__be32 +nfsd_get_case_info(struct svc_fh *fhp, bool *case_insensitive, + bool *case_preserving) +{ + u32 case_info; + int err; + + err =3D vfs_get_case_info(fhp->fh_dentry, &case_info); + if (err) + return nfserrno(err); + + *case_insensitive =3D (case_info & FILEATTR_CASEFOLD_TYPE) !=3D 0; + *case_preserving =3D (case_info & FILEATTR_CASE_PRESERVING) !=3D 0; + return nfs_ok; +} diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 0c0292611c6d..a80177744325 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -154,6 +154,8 @@ __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); +__be32 nfsd_get_case_info(struct svc_fh *fhp, bool *case_insensitive, + bool *case_preserving); =20 __be32 nfsd_permission(struct svc_cred *cred, struct svc_export *exp, struct dentry *dentry, int acc); --=20 2.52.0 From nobody Mon Feb 9 23:05:32 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9D9093148A0; Thu, 11 Dec 2025 15:21:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466518; cv=none; b=KGK/Ls7os49h81zwsD/x1q3GaqNnUsy03R5dZ2TlDeV5fecdJG0rHD5fq0EiSxEY5MWkYseanrm5+Gv24WSNKZa+VG8zWd3i+eUrYwUWmyFl1E2tEWiS2mk0D5vS6I5t+Eb0J4PUIByfuCxOXqHoHtjiLAyrxMi9LXj/XBJhsl0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1765466518; c=relaxed/simple; bh=cBQ7OwxCQJmyRnBB78Msff46NnL6E68T38nm8NO24nE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gXfwGuKHwXAe/RQFDnJeKd5zSQibNXwddvJMk0fVc32Iu2SB0I+kznuGb3VmbFERw431mY1x568x3Dux1m+wEX2y8X2sdAcDvvRD+j7LcGt3ioMaEutUAESSmQDMcAv7IyPDOqjSJgPggh4xVN1iw+beUcN4Y0uAiRZRkvfGSh4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=n4AH/VHT; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="n4AH/VHT" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 61525C16AAE; Thu, 11 Dec 2025 15:21:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1765466518; bh=cBQ7OwxCQJmyRnBB78Msff46NnL6E68T38nm8NO24nE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n4AH/VHTRJQ2E11//4xXPtHcDqYx6hvHuGFjclBd+irtPAI7C1nNdhc1dyWMjnW00 OXeCbztIERWLDCzlxhb6txxL6UGHnCczW9FC7FhdR0rkdAGd2EhKGP9ZT2oT6RGaid N6DgberopwgdLk/w4u4ynLdtTbSzKgN3HTJTjSZ1owilOgEFYoP1nRqnXXFohTwl9k t5z7PRFM8rzq0JH0KeXjs5rlmXSXqSmpS6IitF1bHPLakO2vnOCf/covPTLFNMmNKY JXqTgX4lLENYAB9XUcXHjer+nD5SrJ6V5d0xhFO1dyKayhUOWz1mJfoSLy2hXWAZqX sM8HmWJH6cTUw== From: Chuck Lever To: Al Viro , Christian Brauner Cc: , linux-ext4@vger.kernel.org, , , hirofumi@mail.parknet.co.jp, almaz.alexandrovich@paragon-software.com, tytso@mit.edu, adilger.kernel@dilger.ca, Volker.Lendecke@sernet.de, Chuck Lever Subject: [PATCH v2 6/6] nfsd: Implement NFSv4 FATTR4_CASE_INSENSITIVE and FATTR4_CASE_PRESERVING Date: Thu, 11 Dec 2025 10:21:16 -0500 Message-ID: <20251211152116.480799-7-cel@kernel.org> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20251211152116.480799-1-cel@kernel.org> References: <20251211152116.480799-1-cel@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Chuck Lever Replace the hard-coded values for the NFSv4 case_insensitive and case_preserving attributes with dynamic values retrieved from the underlying filesystem via vfs_get_case_info(). This allows NFSv4 clients to discover the actual case sensitivity behavior of exported filesystems, including per-directory settings for filesystems like ext4 with casefold support. Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 67bb9c0b9fcb..0c51d390d995 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2933,6 +2933,8 @@ struct nfsd4_fattr_args { u32 rdattr_err; bool contextsupport; bool ignore_crossmnt; + bool case_insensitive; + bool case_preserving; }; =20 typedef __be32(*nfsd4_enc_attr)(struct xdr_stream *xdr, @@ -3131,6 +3133,18 @@ static __be32 nfsd4_encode_fattr4_acl(struct xdr_str= eam *xdr, return nfs_ok; } =20 +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_filehandle(struct xdr_stream *xdr, const struct nfsd4_fattr_args *args) { @@ -3482,8 +3496,8 @@ static const nfsd4_enc_attr nfsd4_enc_fattr4_encode_o= ps[] =3D { [FATTR4_ACLSUPPORT] =3D nfsd4_encode_fattr4_aclsupport, [FATTR4_ARCHIVE] =3D nfsd4_encode_fattr4__noop, [FATTR4_CANSETTIME] =3D nfsd4_encode_fattr4__true, - [FATTR4_CASE_INSENSITIVE] =3D nfsd4_encode_fattr4__false, - [FATTR4_CASE_PRESERVING] =3D nfsd4_encode_fattr4__true, + [FATTR4_CASE_INSENSITIVE] =3D nfsd4_encode_fattr4_case_insensitive, + [FATTR4_CASE_PRESERVING] =3D nfsd4_encode_fattr4_case_preserving, [FATTR4_CHOWN_RESTRICTED] =3D nfsd4_encode_fattr4__true, [FATTR4_FILEHANDLE] =3D nfsd4_encode_fattr4_filehandle, [FATTR4_FILEID] =3D nfsd4_encode_fattr4_fileid, @@ -3669,8 +3683,9 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xd= r_stream *xdr, if (err) goto out_nfserr; } - if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID)) && - !fhp) { + if ((attrmask[0] & (FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FSID | + FATTR4_WORD0_CASE_INSENSITIVE | + FATTR4_WORD0_CASE_PRESERVING)) && !fhp) { tempfh =3D kmalloc(sizeof(struct svc_fh), GFP_KERNEL); status =3D nfserr_jukebox; if (!tempfh) @@ -3682,6 +3697,13 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct x= dr_stream *xdr, args.fhp =3D tempfh; } else args.fhp =3D fhp; + if (attrmask[0] & (FATTR4_WORD0_CASE_INSENSITIVE | + FATTR4_WORD0_CASE_PRESERVING)) { + status =3D nfsd_get_case_info(args.fhp, &args.case_insensitive, + &args.case_preserving); + if (status !=3D nfs_ok) + goto out; + } =20 if (attrmask[0] & FATTR4_WORD0_ACL) { err =3D nfsd4_get_nfs4_acl(rqstp, dentry, &args.acl); --=20 2.52.0