On 3/4/25 07:06, Eric Biggers wrote: > On Mon, Mar 03, 2025 at 11:46:06AM +0800, Chao Yu via Linux-f2fs-devel wrote: >> This patch introduces a new flag F2FS_NOLINEAR_LOOKUP_FL, so that we can >> tag casefolded directory w/ it to disable linear lookup functionality, >> it can be used for QA. >> >> Signed-off-by: Chao Yu <chao@xxxxxxxxxx> >> --- >> fs/f2fs/dir.c | 3 ++- >> fs/f2fs/f2fs.h | 2 ++ >> fs/f2fs/file.c | 36 +++++++++++++++++++++++------------- >> include/uapi/linux/f2fs.h | 5 +++++ >> 4 files changed, 32 insertions(+), 14 deletions(-) >> >> diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c >> index 54dd52de7269..4c74f29a2c73 100644 >> --- a/fs/f2fs/dir.c >> +++ b/fs/f2fs/dir.c >> @@ -366,7 +366,8 @@ struct f2fs_dir_entry *__f2fs_find_entry(struct inode *dir, >> >> out: >> #if IS_ENABLED(CONFIG_UNICODE) >> - if (IS_CASEFOLDED(dir) && !de && use_hash) { >> + if (IS_CASEFOLDED(dir) && !de && use_hash && >> + !IS_NOLINEAR_LOOKUP(dir)) { >> use_hash = false; >> goto start_find_entry; >> } >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h >> index 05879c6dc4d6..787f1e5a52d7 100644 >> --- a/fs/f2fs/f2fs.h >> +++ b/fs/f2fs/f2fs.h >> @@ -3047,6 +3047,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) >> #define F2FS_NOCOMP_FL 0x00000400 /* Don't compress */ >> #define F2FS_INDEX_FL 0x00001000 /* hash-indexed directory */ >> #define F2FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */ >> +#define F2FS_NOLINEAR_LOOKUP_FL 0x08000000 /* do not use linear lookup */ >> #define F2FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */ >> #define F2FS_CASEFOLD_FL 0x40000000 /* Casefolded file */ >> #define F2FS_DEVICE_ALIAS_FL 0x80000000 /* File for aliasing a device */ >> @@ -3066,6 +3067,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr) >> #define F2FS_OTHER_FLMASK (F2FS_NODUMP_FL | F2FS_NOATIME_FL) >> >> #define IS_DEVICE_ALIASING(inode) (F2FS_I(inode)->i_flags & F2FS_DEVICE_ALIAS_FL) >> +#define IS_NOLINEAR_LOOKUP(inode) (F2FS_I(inode)->i_flags & F2FS_NOLINEAR_LOOKUP_FL) >> >> static inline __u32 f2fs_mask_flags(umode_t mode, __u32 flags) >> { >> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c >> index 014cb7660a9a..1acddc4d11e4 100644 >> --- a/fs/f2fs/file.c >> +++ b/fs/f2fs/file.c >> @@ -2062,6 +2062,11 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask) >> } >> } >> >> + if ((iflags ^ masked_flags) & F2FS_NOLINEAR_LOOKUP_FLAG) { >> + if (!S_ISDIR(inode->i_mode) || !IS_CASEFOLDED(inode)) >> + return -EINVAL; >> + } >> + >> fi->i_flags = iflags | (fi->i_flags & ~mask); >> f2fs_bug_on(F2FS_I_SB(inode), (fi->i_flags & F2FS_COMPR_FL) && >> (fi->i_flags & F2FS_NOCOMP_FL)); >> @@ -2093,17 +2098,18 @@ static const struct { >> u32 iflag; >> u32 fsflag; >> } f2fs_fsflags_map[] = { >> - { F2FS_COMPR_FL, FS_COMPR_FL }, >> - { F2FS_SYNC_FL, FS_SYNC_FL }, >> - { F2FS_IMMUTABLE_FL, FS_IMMUTABLE_FL }, >> - { F2FS_APPEND_FL, FS_APPEND_FL }, >> - { F2FS_NODUMP_FL, FS_NODUMP_FL }, >> - { F2FS_NOATIME_FL, FS_NOATIME_FL }, >> - { F2FS_NOCOMP_FL, FS_NOCOMP_FL }, >> - { F2FS_INDEX_FL, FS_INDEX_FL }, >> - { F2FS_DIRSYNC_FL, FS_DIRSYNC_FL }, >> - { F2FS_PROJINHERIT_FL, FS_PROJINHERIT_FL }, >> - { F2FS_CASEFOLD_FL, FS_CASEFOLD_FL }, >> + { F2FS_COMPR_FL, FS_COMPR_FL }, >> + { F2FS_SYNC_FL, FS_SYNC_FL }, >> + { F2FS_IMMUTABLE_FL, FS_IMMUTABLE_FL }, >> + { F2FS_APPEND_FL, FS_APPEND_FL }, >> + { F2FS_NODUMP_FL, FS_NODUMP_FL }, >> + { F2FS_NOATIME_FL, FS_NOATIME_FL }, >> + { F2FS_NOCOMP_FL, FS_NOCOMP_FL }, >> + { F2FS_INDEX_FL, FS_INDEX_FL }, >> + { F2FS_DIRSYNC_FL, FS_DIRSYNC_FL }, >> + { F2FS_PROJINHERIT_FL, FS_PROJINHERIT_FL }, >> + { F2FS_CASEFOLD_FL, FS_CASEFOLD_FL }, >> + { F2FS_NOLINEAR_LOOKUP_FL, F2FS_NOLINEAR_LOOKUP_FL }, >> }; >> >> #define F2FS_GETTABLE_FS_FL ( \ >> @@ -2121,7 +2127,8 @@ static const struct { >> FS_INLINE_DATA_FL | \ >> FS_NOCOW_FL | \ >> FS_VERITY_FL | \ >> - FS_CASEFOLD_FL) >> + FS_CASEFOLD_FL | \ >> + F2FS_NOLINEAR_LOOKUP_FL) >> >> #define F2FS_SETTABLE_FS_FL ( \ >> FS_COMPR_FL | \ >> @@ -2133,7 +2140,8 @@ static const struct { >> FS_NOCOMP_FL | \ >> FS_DIRSYNC_FL | \ >> FS_PROJINHERIT_FL | \ >> - FS_CASEFOLD_FL) >> + FS_CASEFOLD_FL | \ >> + F2FS_NOLINEAR_LOOKUP_FL) >> >> /* Convert f2fs on-disk i_flags to FS_IOC_{GET,SET}FLAGS flags */ >> static inline u32 f2fs_iflags_to_fsflags(u32 iflags) >> @@ -3344,6 +3352,8 @@ int f2fs_fileattr_get(struct dentry *dentry, struct fileattr *fa) >> fsflags |= FS_INLINE_DATA_FL; >> if (is_inode_flag_set(inode, FI_PIN_FILE)) >> fsflags |= FS_NOCOW_FL; >> + if (IS_NOLINEAR_LOOKUP(inode)) >> + fsflags |= F2FS_NOLINEAR_LOOKUP_FL; >> >> fileattr_fill_flags(fa, fsflags & F2FS_GETTABLE_FS_FL); >> >> diff --git a/include/uapi/linux/f2fs.h b/include/uapi/linux/f2fs.h >> index 795e26258355..a03626fdcf35 100644 >> --- a/include/uapi/linux/f2fs.h >> +++ b/include/uapi/linux/f2fs.h >> @@ -104,4 +104,9 @@ struct f2fs_comp_option { >> __u8 log_cluster_size; >> }; >> >> +/* used for FS_IOC_GETFLAGS and FS_IOC_SETFLAGS */ >> +enum { >> + F2FS_NOLINEAR_LOOKUP_FLAG = 0x08000000, >> +}; > > FS_IOC_GETFLAGS and FS_IOC_SETFLAGS are not filesystem-specific, and the > supported flags are declared in include/uapi/linux/fs.h. You can't just > randomly give an unused bit a filesystem specific meaning. Yeah, let me have a try to propose it into vfs. Thanks, > > - Eric