mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-06-21 15:43:21 +02:00
3035e44541
Enable upper layers such as NFSD to retrieve case sensitivity information from file systems by adding FS_XFLAG_CASEFOLD and FS_XFLAG_CASENONPRESERVING flags. Filesystems report case-insensitive or case-nonpreserving behavior by setting these flags directly in fa->fsx_xflags. The default (flags unset) indicates POSIX semantics: case-sensitive and case-preserving. Both flags are added to FS_XFLAG_RDONLY_MASK so FS_IOC_FSSETXATTR silently strips them, keeping the new xflags strictly a reporting interface. Callers that want to toggle casefolding continue to use FS_IOC_SETFLAGS with FS_CASEFOLD_FL, the established UAPI on filesystems that support the operation (ext4 and f2fs on empty directories). Case sensitivity information is exported to userspace via the fa_xflags field in the FS_IOC_FSGETXATTR ioctl and file_getattr() system call. Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Jan Kara <jack@suse.cz> 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-2-e62cc8200435@oracle.com Signed-off-by: Christian Brauner <brauner@kernel.org>
85 lines
2.9 KiB
C
85 lines
2.9 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef _LINUX_FILEATTR_H
|
|
#define _LINUX_FILEATTR_H
|
|
|
|
/* Flags shared betwen flags/xflags */
|
|
#define FS_COMMON_FL \
|
|
(FS_SYNC_FL | FS_IMMUTABLE_FL | FS_APPEND_FL | \
|
|
FS_NODUMP_FL | FS_NOATIME_FL | FS_DAX_FL | \
|
|
FS_PROJINHERIT_FL | FS_VERITY_FL)
|
|
|
|
#define FS_XFLAG_COMMON \
|
|
(FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND | \
|
|
FS_XFLAG_NODUMP | FS_XFLAG_NOATIME | FS_XFLAG_DAX | \
|
|
FS_XFLAG_PROJINHERIT | FS_XFLAG_VERITY)
|
|
|
|
/* Read-only inode flags */
|
|
#define FS_XFLAG_RDONLY_MASK \
|
|
(FS_XFLAG_PREALLOC | FS_XFLAG_HASATTR | FS_XFLAG_VERITY | \
|
|
FS_XFLAG_CASEFOLD | FS_XFLAG_CASENONPRESERVING)
|
|
|
|
/* Flags to indicate valid value of fsx_ fields */
|
|
#define FS_XFLAG_VALUES_MASK \
|
|
(FS_XFLAG_EXTSIZE | FS_XFLAG_COWEXTSIZE)
|
|
|
|
/* Flags for directories */
|
|
#define FS_XFLAG_DIRONLY_MASK \
|
|
(FS_XFLAG_RTINHERIT | FS_XFLAG_NOSYMLINKS | FS_XFLAG_EXTSZINHERIT)
|
|
|
|
/* Misc settable flags */
|
|
#define FS_XFLAG_MISC_MASK \
|
|
(FS_XFLAG_REALTIME | FS_XFLAG_NODEFRAG | FS_XFLAG_FILESTREAM)
|
|
|
|
#define FS_XFLAGS_MASK \
|
|
(FS_XFLAG_COMMON | FS_XFLAG_RDONLY_MASK | FS_XFLAG_VALUES_MASK | \
|
|
FS_XFLAG_DIRONLY_MASK | FS_XFLAG_MISC_MASK)
|
|
|
|
/*
|
|
* Merged interface for miscellaneous file attributes. 'flags' originates from
|
|
* ext* and 'fsx_flags' from xfs. There's some overlap between the two, which
|
|
* is handled by the VFS helpers, so filesystems are free to implement just one
|
|
* or both of these sub-interfaces.
|
|
*/
|
|
struct file_kattr {
|
|
u32 flags; /* flags (FS_IOC_GETFLAGS/FS_IOC_SETFLAGS) */
|
|
/* struct fsxattr: */
|
|
u32 fsx_xflags; /* xflags field value (get/set) */
|
|
u32 fsx_extsize; /* extsize field value (get/set)*/
|
|
u32 fsx_nextents; /* nextents field value (get) */
|
|
u32 fsx_projid; /* project identifier (get/set) */
|
|
u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/
|
|
/* selectors: */
|
|
bool flags_valid:1;
|
|
bool fsx_valid:1;
|
|
};
|
|
|
|
int copy_fsxattr_to_user(const struct file_kattr *fa, struct fsxattr __user *ufa);
|
|
|
|
void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags);
|
|
void fileattr_fill_flags(struct file_kattr *fa, u32 flags);
|
|
|
|
/**
|
|
* fileattr_has_fsx - check for extended flags/attributes
|
|
* @fa: fileattr pointer
|
|
*
|
|
* Return: true if any attributes are present that are not represented in
|
|
* ->flags.
|
|
*/
|
|
static inline bool fileattr_has_fsx(const struct file_kattr *fa)
|
|
{
|
|
return fa->fsx_valid &&
|
|
((fa->fsx_xflags & ~FS_XFLAG_COMMON) || fa->fsx_extsize != 0 ||
|
|
fa->fsx_projid != 0 || fa->fsx_cowextsize != 0);
|
|
}
|
|
|
|
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 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);
|
|
int ioctl_fssetxattr(struct file *file, void __user *argp);
|
|
|
|
#endif /* _LINUX_FILEATTR_H */
|