diff mbox series

[f2fs-dev] f2fs: support F2FS_NOLINEAR_LOOKUP_FL

Message ID 20250303034606.1355224-1-chao@kernel.org (mailing list archive)
State New
Headers show
Series [f2fs-dev] f2fs: support F2FS_NOLINEAR_LOOKUP_FL | expand

Commit Message

Chao Yu March 3, 2025, 3:46 a.m. UTC
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@kernel.org>
---
 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(-)

Comments

Eric Biggers March 3, 2025, 11:06 p.m. UTC | #1
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@kernel.org>
> ---
>  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.

- Eric
Chao Yu March 5, 2025, 8:24 a.m. UTC | #2
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@kernel.org>
>> ---
>>  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
Christoph Hellwig March 5, 2025, 2:46 p.m. UTC | #3
On Mon, Mar 03, 2025 at 11:06:44PM +0000, Eric Biggers wrote:
> > +/* 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.

Eww, yes.  This needs to be reverted ASAP.

And I'd like to repeat my reminder that we need to stop file systems
(and f2fs is particularly bad for this) to stop just adding random
uapis without review from linux-fsdevel and linux-api.
diff mbox series

Patch

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,
+};
+
 #endif /* _UAPI_LINUX_F2FS_H */