MIME-Version: 1.0 References: <20260424-case-sensitivity-v11-0-de5619beddaf@oracle.com> <20260424-case-sensitivity-v11-3-de5619beddaf@oracle.com> In-Reply-To: From: Rick Macklem Date: Mon, 27 Apr 2026 14:30:10 -0700 X-Gm-Features: AVHnY4KgSQFR3scv6xUxgsHU_8QBh7PyOptUjRlPBEGqFL2M7EpvCJN8x1ORXY4 Message-ID: Subject: Re: FreeBSD NFSv4.1 server exporting FreeBSD FAT filesystem - case-insensitive=true? Fwd: [PATCH v11 03/15] fat: Implement fileattr_get for case sensitivity To: Cedric Blancher Cc: freebsd-hackers@freebsd.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spamd-Result: default: False [-4.37 / 15.00]; ARC_ALLOW(-1.00)[google.com:s=arc-20240605:i=1]; NEURAL_HAM_MEDIUM(-1.00)[-1.000]; NEURAL_HAM_LONG(-1.00)[-1.000]; DMARC_POLICY_ALLOW(-0.50)[gmail.com,none]; NEURAL_HAM_SHORT(-0.37)[-0.369]; R_DKIM_ALLOW(-0.20)[gmail.com:s=20251104]; R_SPF_ALLOW(-0.20)[+ip6:2a00:1450:4864::/56]; MIME_GOOD(-0.10)[text/plain]; RCPT_COUNT_TWO(0.00)[2]; MIME_TRACE(0.00)[0:+]; RCVD_TLS_LAST(0.00)[]; TO_DN_SOME(0.00)[]; DWL_DNSWL_NONE(0.00)[gmail.com:dkim]; FREEMAIL_TO(0.00)[gmail.com]; FREEMAIL_ENVFROM(0.00)[gmail.com]; TAGGED_FROM(0.00)[]; FREEMAIL_FROM(0.00)[gmail.com]; FROM_HAS_DN(0.00)[]; MISSING_XM_UA(0.00)[]; PREVIOUSLY_DELIVERED(0.00)[freebsd-hackers@freebsd.org]; MID_RHS_MATCH_FROMTLD(0.00)[]; TO_MATCH_ENVRCPT_SOME(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; DKIM_TRACE(0.00)[gmail.com:+]; MLMMJ_DEST(0.00)[freebsd-hackers@freebsd.org]; ASN(0.00)[asn:15169, ipnet:2a00:1450::/32, country:US]; TAGGED_RCPT(0.00)[]; RCVD_IN_DNSWL_NONE(0.00)[2a00:1450:4864:20::52e:from]; RCVD_COUNT_ONE(0.00)[1]; SUBJECT_HAS_QUESTION(0.00)[] X-Rspamd-Queue-Id: 4g4GvC5dpZz3ZyD X-Spamd-Bar: ---- On Mon, Apr 27, 2026 at 12:13=E2=80=AFAM Cedric Blancher wrote: > > Good morning! > > How does the FreeBSD NFSv4.1 server behave when it exports a FreeBSD > FAT filesystem? Does it set the case-insensitive and > case-nonpreserving FATTR4 attributes to case-insensitive=3Dtrue? It replies case-insensitive and case-preserving as both true. (When I create a file called Readme, ls returns Readme, so I believe that means case-preserving should be true.) The file can be open'd with any combination of case: README, readme or Readme, for example. rick > > Ced > > ---------- Forwarded message --------- > From: Chuck Lever > Date: Sat, 25 Apr 2026 at 03:53 > Subject: [PATCH v11 03/15] fat: Implement fileattr_get for case sensitivi= ty > To: Al Viro , Christian Brauner > , Jan Kara > Cc: , , > , , > , , > , > , , > , , > , , > , , , > , , , > , , > , , , > , , , > , Chuck Lever , > Roland Mainz > > > From: Chuck Lever > > Report FAT's case sensitivity behavior via the FS_XFLAG_CASEFOLD > and FS_XFLAG_CASENONPRESERVING flags. FAT filesystems are > case-insensitive by default. > > MSDOS supports a 'nocase' mount option that enables case-sensitive > behavior; check this option when reporting case sensitivity. > > VFAT long filename entries preserve case; without VFAT, only > uppercased 8.3 short names are stored. MSDOS with 'nocase' also > preserves case since the name-formatting code skips upcasing when > 'nocase' is set. Check both options when reporting case preservation. > > Reviewed-by: Jan Kara > Reviewed-by: Roland Mainz > Signed-off-by: Chuck Lever > --- > fs/fat/fat.h | 3 +++ > fs/fat/file.c | 32 ++++++++++++++++++++++++++++++++ > fs/fat/namei_msdos.c | 1 + > fs/fat/namei_vfat.c | 1 + > 4 files changed, 37 insertions(+) > > diff --git a/fs/fat/fat.h b/fs/fat/fat.h > index 5a58f0bf8ce8..99ed9228a677 100644 > --- a/fs/fat/fat.h > +++ b/fs/fat/fat.h > @@ -10,6 +10,8 @@ > #include > #include > > +struct file_kattr; > + > /* > * vfat shortname flags > */ > @@ -408,6 +410,7 @@ extern void fat_truncate_blocks(struct inode > *inode, loff_t offset); > extern int fat_getattr(struct mnt_idmap *idmap, > const struct path *path, struct kstat *stat, > u32 request_mask, unsigned int flags); > +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); > > diff --git a/fs/fat/file.c b/fs/fat/file.c > index becccdd2e501..5f0178fc2ede 100644 > --- a/fs/fat/file.c > +++ b/fs/fat/file.c > @@ -17,6 +17,7 @@ > #include > #include > #include > +#include > #include "fat.h" > > static long fat_fallocate(struct file *file, int mode, > @@ -398,6 +399,36 @@ void fat_truncate_blocks(struct inode *inode, > loff_t offset) > fat_flush_inodes(inode->i_sb, inode, NULL); > } > > +int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa) > +{ > + struct msdos_sb_info *sbi =3D MSDOS_SB(dentry->d_sb); > + bool case_sensitive; > + > + /* > + * FAT filesystems are case-insensitive by default. VFAT > + * becomes case-sensitive when mounted with 'check=3Dstrict', > + * which installs vfat_dentry_ops. MSDOS has no such option; > + * its 'nocase' mount option selects case-sensitive matching. > + * > + * VFAT long filename entries preserve case. Without VFAT, only > + * uppercased 8.3 short names are stored. MSDOS with 'nocase' > + * also preserves case. > + */ > + if (sbi->options.isvfat) > + case_sensitive =3D sbi->options.name_check =3D=3D 's'; > + else > + case_sensitive =3D sbi->options.nocase; > + > + if (!case_sensitive) { > + fa->fsx_xflags |=3D FS_XFLAG_CASEFOLD; > + fa->flags |=3D FS_CASEFOLD_FL; > + if (!sbi->options.isvfat) > + fa->fsx_xflags |=3D FS_XFLAG_CASENONPRESERVING; > + } > + 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) > { > @@ -575,5 +606,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 4cc65f330fb7..0fd2971ad4b1 100644 > --- a/fs/fat/namei_msdos.c > +++ b/fs/fat/namei_msdos.c > @@ -644,6 +644,7 @@ static const struct inode_operations > msdos_dir_inode_operations =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, > }; > > diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c > index 918b3756674c..e909447873e3 100644 > --- a/fs/fat/namei_vfat.c > +++ b/fs/fat/namei_vfat.c > @@ -1185,6 +1185,7 @@ static const struct inode_operations > vfat_dir_inode_operations =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, > }; > > > -- > 2.53.0 > > > > > -- > Cedric Blancher > [https://plus.google.com/u/0/+CedricBlancher/] > Institute Pasteur >