[PATCH v2 12/13] f2fs: convert inline tails to avoid potential issues

From: Wu Bo
Date: Tue Sep 10 2024 - 23:45:56 EST


Like the commit:
commit b3d208f96d6b ("f2fs: revisit inline_data to avoid data races and potential bugs")

Due to the limitations of inline data, there are many scenarios where
inline isn't supported well, such as move file range.

Therefore, in these scenarios, convert the inline tail file to a regular
file.

Signed-off-by: Wu Bo <bo.wu@xxxxxxxx>
---
fs/f2fs/data.c | 4 ++++
fs/f2fs/file.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
fs/f2fs/verity.c | 4 ++++
3 files changed, 55 insertions(+)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index f52834c1cacd..a59758e1c878 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -4141,6 +4141,10 @@ static int f2fs_swap_activate(struct swap_info_struct *sis, struct file *file,
if (ret)
return ret;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ return ret;
+
if (!f2fs_disable_compressed_file(inode))
return -EINVAL;

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 64ea0bfc2e1e..3dcc5e363c13 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -84,6 +84,10 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
if (err)
goto out;

+ err = f2fs_convert_inline_tail(inode);
+ if (err)
+ goto out;
+
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (f2fs_compressed_file(inode)) {
int ret = f2fs_is_compressed_cluster(inode, page->index);
@@ -1070,6 +1074,12 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
return err;
}

+ if (attr->ia_size > MAX_INLINE_TAIL(inode)) {
+ err = f2fs_convert_inline_tail(inode);
+ if (err)
+ return err;
+ }
+
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);

@@ -1191,6 +1201,10 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ return ret;
+
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;

@@ -1501,6 +1515,10 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ return ret;
+
/* write out all dirty pages from offset */
ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX);
if (ret)
@@ -1591,6 +1609,10 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
if (ret)
return ret;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ return ret;
+
ret = filemap_write_and_wait_range(mapping, offset, offset + len - 1);
if (ret)
return ret;
@@ -1705,6 +1727,10 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ return ret;
+
f2fs_balance_fs(sbi, true);

filemap_invalidate_lock(mapping);
@@ -2010,6 +2036,9 @@ static int f2fs_setflags_common(struct inode *inode, u32 iflags, u32 mask)
} else {
/* try to convert inline_data to support compression */
int err = f2fs_convert_inline_inode(inode);
+ if (err)
+ return err;
+ err = f2fs_convert_inline_tail(inode);
if (err)
return err;

@@ -2172,6 +2201,10 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
if (ret)
goto out;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ goto out;
+
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);

/*
@@ -2964,10 +2997,16 @@ static int f2fs_move_file_range(struct file *file_in, loff_t pos_in,
goto out_unlock;

ret = f2fs_convert_inline_inode(src);
+ if (ret)
+ goto out_unlock;
+ ret = f2fs_convert_inline_tail(src);
if (ret)
goto out_unlock;

ret = f2fs_convert_inline_inode(dst);
+ if (ret)
+ goto out_unlock;
+ ret = f2fs_convert_inline_tail(dst);
if (ret)
goto out_unlock;

@@ -3353,6 +3392,10 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg)
if (ret)
goto out;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ goto out;
+
if (!f2fs_disable_compressed_file(inode)) {
ret = -EOPNOTSUPP;
goto out;
@@ -3998,6 +4041,10 @@ static int f2fs_sec_trim_file(struct file *filp, unsigned long arg)
if (ret)
goto err;

+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ goto err;
+
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(mapping);

diff --git a/fs/f2fs/verity.c b/fs/f2fs/verity.c
index f7bb0c54502c..aaf3e754140a 100644
--- a/fs/f2fs/verity.c
+++ b/fs/f2fs/verity.c
@@ -139,6 +139,10 @@ static int f2fs_begin_enable_verity(struct file *filp)
if (err)
return err;

+ err = f2fs_convert_inline_tail(inode);
+ if (err)
+ return err;
+
set_inode_flag(inode, FI_VERITY_IN_PROGRESS);
return 0;
}
--
2.35.3