Skip to content

Commit 1cd8fad

Browse files
committed
Merge remote-tracking branches 'vfs/vfs-7.2.casefold', 'vfs/vfs-7.2.directory.delegations' and 'vfs/vfs-7.2.exportfs' into vfs-7.2-merge
4 parents e43ffb6 + ea3120f + 246bc86 + 79e33dd commit 1cd8fad

70 files changed

Lines changed: 1121 additions & 210 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9916,7 +9916,7 @@ S: Supported
99169916
F: Documentation/filesystems/nfs/exporting.rst
99179917
F: fs/exportfs/
99189918
F: fs/fhandle.c
9919-
F: include/linux/exportfs.h
9919+
F: include/linux/exportfs*.h
99209920

99219921
FILESYSTEMS [IDMAPPED MOUNTS]
99229922
M: Christian Brauner <brauner@kernel.org>

fs/attr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ int notify_change(struct mnt_idmap *idmap, struct dentry *dentry,
547547
* breaking the delegation in this case.
548548
*/
549549
if (!(ia_valid & ATTR_DELEG)) {
550-
error = try_break_deleg(inode, delegated_inode);
550+
error = try_break_deleg(inode, 0, delegated_inode);
551551
if (error)
552552
return error;
553553
}

fs/exfat/exfat_fs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,8 @@ int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
496496
int exfat_getattr(struct mnt_idmap *idmap, const struct path *path,
497497
struct kstat *stat, unsigned int request_mask,
498498
unsigned int query_flags);
499+
struct file_kattr;
500+
int exfat_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
499501
int exfat_file_fsync(struct file *file, loff_t start, loff_t end, int datasync);
500502
long exfat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
501503
long exfat_compat_ioctl(struct file *filp, unsigned int cmd,

fs/exfat/file.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/writeback.h>
1515
#include <linux/filelock.h>
1616
#include <linux/falloc.h>
17+
#include <linux/fileattr.h>
1718

1819
#include "exfat_raw.h"
1920
#include "exfat_fs.h"
@@ -323,6 +324,18 @@ int exfat_getattr(struct mnt_idmap *idmap, const struct path *path,
323324
return 0;
324325
}
325326

327+
int exfat_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
328+
{
329+
/*
330+
* exFAT compares filenames through an upcase table, so lookup
331+
* is always case-insensitive. Long names are stored in UTF-16
332+
* with case intact; CASENONPRESERVING stays clear.
333+
*/
334+
fa->fsx_xflags |= FS_XFLAG_CASEFOLD;
335+
fa->flags |= FS_CASEFOLD_FL;
336+
return 0;
337+
}
338+
326339
int exfat_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
327340
struct iattr *attr)
328341
{
@@ -817,6 +830,7 @@ const struct file_operations exfat_file_operations = {
817830
};
818831

819832
const struct inode_operations exfat_file_inode_operations = {
820-
.setattr = exfat_setattr,
821-
.getattr = exfat_getattr,
833+
.setattr = exfat_setattr,
834+
.getattr = exfat_getattr,
835+
.fileattr_get = exfat_fileattr_get,
822836
};

fs/exfat/namei.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1311,4 +1311,5 @@ const struct inode_operations exfat_dir_inode_operations = {
13111311
.rename = exfat_rename,
13121312
.setattr = exfat_setattr,
13131313
.getattr = exfat_getattr,
1314+
.fileattr_get = exfat_fileattr_get,
13141315
};

fs/fat/fat.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <linux/fs_context.h>
1111
#include <linux/fs_parser.h>
1212

13+
struct file_kattr;
14+
1315
/*
1416
* vfat shortname flags
1517
*/
@@ -408,6 +410,7 @@ extern void fat_truncate_blocks(struct inode *inode, loff_t offset);
408410
extern int fat_getattr(struct mnt_idmap *idmap,
409411
const struct path *path, struct kstat *stat,
410412
u32 request_mask, unsigned int flags);
413+
int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa);
411414
extern int fat_file_fsync(struct file *file, loff_t start, loff_t end,
412415
int datasync);
413416

fs/fat/file.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/fsnotify.h>
1818
#include <linux/security.h>
1919
#include <linux/falloc.h>
20+
#include <linux/fileattr.h>
2021
#include "fat.h"
2122

2223
static long fat_fallocate(struct file *file, int mode,
@@ -398,6 +399,40 @@ void fat_truncate_blocks(struct inode *inode, loff_t offset)
398399
fat_flush_inodes(inode->i_sb, inode, NULL);
399400
}
400401

402+
int fat_fileattr_get(struct dentry *dentry, struct file_kattr *fa)
403+
{
404+
struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb);
405+
bool case_sensitive;
406+
407+
/*
408+
* FAT filesystems are case-insensitive by default. VFAT
409+
* becomes case-sensitive when mounted with 'check=strict',
410+
* which installs vfat_dentry_ops. MSDOS has no such option;
411+
* its 'nocase' mount option selects case-sensitive matching.
412+
*
413+
* VFAT long filename entries preserve case. Without VFAT, only
414+
* uppercased 8.3 short names are stored. MSDOS with 'nocase'
415+
* also preserves case.
416+
*/
417+
if (sbi->options.isvfat)
418+
case_sensitive = sbi->options.name_check == 's';
419+
else
420+
case_sensitive = sbi->options.nocase;
421+
422+
if (!case_sensitive) {
423+
fa->fsx_xflags |= FS_XFLAG_CASEFOLD;
424+
fa->flags |= FS_CASEFOLD_FL;
425+
if (!sbi->options.isvfat)
426+
fa->fsx_xflags |= FS_XFLAG_CASENONPRESERVING;
427+
}
428+
if (d_inode(dentry)->i_flags & S_IMMUTABLE) {
429+
fa->fsx_xflags |= FS_XFLAG_IMMUTABLE;
430+
fa->flags |= FS_IMMUTABLE_FL;
431+
}
432+
return 0;
433+
}
434+
EXPORT_SYMBOL_GPL(fat_fileattr_get);
435+
401436
int fat_getattr(struct mnt_idmap *idmap, const struct path *path,
402437
struct kstat *stat, u32 request_mask, unsigned int flags)
403438
{
@@ -575,5 +610,6 @@ EXPORT_SYMBOL_GPL(fat_setattr);
575610
const struct inode_operations fat_file_inode_operations = {
576611
.setattr = fat_setattr,
577612
.getattr = fat_getattr,
613+
.fileattr_get = fat_fileattr_get,
578614
.update_time = fat_update_time,
579615
};

fs/fat/namei_msdos.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,7 @@ static const struct inode_operations msdos_dir_inode_operations = {
644644
.rename = msdos_rename,
645645
.setattr = fat_setattr,
646646
.getattr = fat_getattr,
647+
.fileattr_get = fat_fileattr_get,
647648
.update_time = fat_update_time,
648649
};
649650

fs/fat/namei_vfat.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,6 +1185,7 @@ static const struct inode_operations vfat_dir_inode_operations = {
11851185
.rename = vfat_rename2,
11861186
.setattr = fat_setattr,
11871187
.getattr = fat_getattr,
1188+
.fileattr_get = fat_fileattr_get,
11881189
.update_time = fat_update_time,
11891190
};
11901191

fs/file_attr.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@
1515
* @fa: fileattr pointer
1616
* @xflags: FS_XFLAG_* flags
1717
*
18-
* Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags). All
19-
* other fields are zeroed.
18+
* Set ->fsx_xflags, ->fsx_valid and ->flags (translated xflags).
2019
*/
2120
void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags)
2221
{
23-
memset(fa, 0, sizeof(*fa));
2422
fa->fsx_valid = true;
2523
fa->fsx_xflags = xflags;
2624
if (fa->fsx_xflags & FS_XFLAG_IMMUTABLE)
@@ -39,6 +37,8 @@ void fileattr_fill_xflags(struct file_kattr *fa, u32 xflags)
3937
fa->flags |= FS_PROJINHERIT_FL;
4038
if (fa->fsx_xflags & FS_XFLAG_VERITY)
4139
fa->flags |= FS_VERITY_FL;
40+
if (fa->fsx_xflags & FS_XFLAG_CASEFOLD)
41+
fa->flags |= FS_CASEFOLD_FL;
4242
}
4343
EXPORT_SYMBOL(fileattr_fill_xflags);
4444

@@ -48,11 +48,9 @@ EXPORT_SYMBOL(fileattr_fill_xflags);
4848
* @flags: FS_*_FL flags
4949
*
5050
* Set ->flags, ->flags_valid and ->fsx_xflags (translated flags).
51-
* All other fields are zeroed.
5251
*/
5352
void fileattr_fill_flags(struct file_kattr *fa, u32 flags)
5453
{
55-
memset(fa, 0, sizeof(*fa));
5654
fa->flags_valid = true;
5755
fa->flags = flags;
5856
if (fa->flags & FS_SYNC_FL)
@@ -71,6 +69,8 @@ void fileattr_fill_flags(struct file_kattr *fa, u32 flags)
7169
fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;
7270
if (fa->flags & FS_VERITY_FL)
7371
fa->fsx_xflags |= FS_XFLAG_VERITY;
72+
if (fa->flags & FS_CASEFOLD_FL)
73+
fa->fsx_xflags |= FS_XFLAG_CASEFOLD;
7474
}
7575
EXPORT_SYMBOL(fileattr_fill_flags);
7676

@@ -325,7 +325,7 @@ int ioctl_setflags(struct file *file, unsigned int __user *argp)
325325
{
326326
struct mnt_idmap *idmap = file_mnt_idmap(file);
327327
struct dentry *dentry = file->f_path.dentry;
328-
struct file_kattr fa;
328+
struct file_kattr fa = {};
329329
unsigned int flags;
330330
int err;
331331

@@ -357,7 +357,7 @@ int ioctl_fssetxattr(struct file *file, void __user *argp)
357357
{
358358
struct mnt_idmap *idmap = file_mnt_idmap(file);
359359
struct dentry *dentry = file->f_path.dentry;
360-
struct file_kattr fa;
360+
struct file_kattr fa = {};
361361
int err;
362362

363363
err = copy_fsxattr_from_user(&fa, argp);
@@ -431,7 +431,7 @@ SYSCALL_DEFINE5(file_setattr, int, dfd, const char __user *, filename,
431431
struct path filepath __free(path_put) = {};
432432
unsigned int lookup_flags = 0;
433433
struct file_attr fattr;
434-
struct file_kattr fa;
434+
struct file_kattr fa = {};
435435
int error;
436436

437437
BUILD_BUG_ON(sizeof(struct file_attr) < FILE_ATTR_SIZE_VER0);

0 commit comments

Comments
 (0)