* [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
@ 2024-09-03 8:54 Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 01/13] f2fs: add inline tail mount option Wu Bo via Linux-f2fs-devel
` (14 more replies)
0 siblings, 15 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
The inode in F2FS occupies an entire 4k block. For many small files, this means
they consume much more space than their actual size. Therefore, there is
significant potential to better utilize the inode block space.
Currently, F2FS has two features to make use of the inode block space: inline
data and inline xattr.
Inline data stores file which size is smaller then 3.5k in inode block. However,
for slightly larger small files, there still have much waste.
For example, a 5k file requires 3 blocks, totaling 12k of space, which is
more than twice the size of the file itself!
Additionally, the end of a file often does not occupy an entire block. If we can
store the end of the file data within the inode block, we can save an entire
block for the file. This is particularly important for small files.
In fact, the current inline data is a special case of inline tail, and
inline tail is an extension of inline data.
To make it simple, inline tail only on small files(<64k). And for larger files,
inline tails don't provide any significant benefits.
The layout of an inline tail inode block is following:
| inode block | 4096 | inline tail enable |
| --------------- | ---- | --------------------------|
| inode info | 360 | |
| --------------- | ---- | --------------------------|
| | | extra info | 0~36 |
| | | **compact_addr[16] | 64 |
| addr table[923] | 3692 | reserved | 4 |
| | | **tail data | |
| | | inline_xattr | 200 |
| --------------- | ---- | --------------------------|
| nid table[5] | 20 |
| node footer | 24 |
F2fs-tools to support inline tail:
https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
I tested inline tail by copying the source code of Linux 6.9.7. The storage
space was reduced by approximately 8%. Additionally, due to the reduced IO, the
copy time also reduced by around 10%.
This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
-g quick' both with and without the patch; no regressions were observed.
The test result is:
f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
Failures: generic/050 generic/064 generic/250 generic/252 generic/563
generic/735
Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
Wu Bo (13):
f2fs: add inline tail mount option
f2fs: add inline tail disk layout definition
f2fs: implement inline tail write & truncate
f2fs: implement inline tail read & fiemap
f2fs: set inline tail flag when create inode
f2fs: fix address info has been truncated
f2fs: support seek for inline tail
f2fs: convert inline tail when inode expand
f2fs: fix data loss during inline tail writing
f2fs: avoid inlining quota files
f2fs: fix inline tail data lost
f2fs: convert inline tails to avoid potential issues
f2fs: implement inline tail forward recovery
fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
fs/f2fs/f2fs.h | 46 ++++++++++++-
fs/f2fs/file.c | 85 +++++++++++++++++++++++-
fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
fs/f2fs/inode.c | 6 ++
fs/f2fs/namei.c | 3 +
fs/f2fs/node.c | 6 +-
fs/f2fs/recovery.c | 9 ++-
fs/f2fs/super.c | 25 +++++++
fs/f2fs/verity.c | 4 ++
10 files changed, 409 insertions(+), 27 deletions(-)
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 01/13] f2fs: add inline tail mount option
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 02/13] f2fs: add inline tail disk layout definition Wu Bo via Linux-f2fs-devel
` (13 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Same as inline data, use mount option to control inline tail enable or
disable. And enable inline tail as default.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/f2fs.h | 1 +
fs/f2fs/super.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ac19c61f0c3e..3956740ca7e2 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -116,6 +116,7 @@ extern const char *f2fs_fault_name[FAULT_MAX];
#define F2FS_MOUNT_GC_MERGE 0x02000000
#define F2FS_MOUNT_COMPRESS_CACHE 0x04000000
#define F2FS_MOUNT_AGE_EXTENT_CACHE 0x08000000
+#define F2FS_MOUNT_INLINE_TAIL 0x10000000
#define F2FS_OPTION(sbi) ((sbi)->mount_opt)
#define clear_opt(sbi, option) (F2FS_OPTION(sbi).opt &= ~F2FS_MOUNT_##option)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 3959fd137cc9..d4ec32ba6cad 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -136,6 +136,7 @@ enum {
Opt_inline_data,
Opt_inline_dentry,
Opt_noinline_dentry,
+ Opt_inline_tail,
Opt_flush_merge,
Opt_noflush_merge,
Opt_barrier,
@@ -144,6 +145,7 @@ enum {
Opt_extent_cache,
Opt_noextent_cache,
Opt_noinline_data,
+ Opt_noinline_tail,
Opt_data_flush,
Opt_reserve_root,
Opt_resgid,
@@ -212,6 +214,7 @@ static match_table_t f2fs_tokens = {
{Opt_inline_data, "inline_data"},
{Opt_inline_dentry, "inline_dentry"},
{Opt_noinline_dentry, "noinline_dentry"},
+ {Opt_inline_tail, "inline_tail"},
{Opt_flush_merge, "flush_merge"},
{Opt_noflush_merge, "noflush_merge"},
{Opt_barrier, "barrier"},
@@ -220,6 +223,7 @@ static match_table_t f2fs_tokens = {
{Opt_extent_cache, "extent_cache"},
{Opt_noextent_cache, "noextent_cache"},
{Opt_noinline_data, "noinline_data"},
+ {Opt_noinline_tail, "noinline_tail"},
{Opt_data_flush, "data_flush"},
{Opt_reserve_root, "reserve_root=%u"},
{Opt_resgid, "resgid=%u"},
@@ -811,6 +815,9 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
case Opt_noinline_dentry:
clear_opt(sbi, INLINE_DENTRY);
break;
+ case Opt_inline_tail:
+ set_opt(sbi, INLINE_TAIL);
+ break;
case Opt_flush_merge:
set_opt(sbi, FLUSH_MERGE);
break;
@@ -835,6 +842,9 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
case Opt_noinline_data:
clear_opt(sbi, INLINE_DATA);
break;
+ case Opt_noinline_tail:
+ clear_opt(sbi, INLINE_DATA);
+ break;
case Opt_data_flush:
set_opt(sbi, DATA_FLUSH);
break;
@@ -1989,6 +1999,10 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
seq_puts(seq, ",inline_data");
else
seq_puts(seq, ",noinline_data");
+ if (test_opt(sbi, INLINE_TAIL))
+ seq_puts(seq, ",inline_tail");
+ else
+ seq_puts(seq, ",noinline_tail");
if (test_opt(sbi, INLINE_DENTRY))
seq_puts(seq, ",inline_dentry");
else
@@ -2138,6 +2152,7 @@ static void default_options(struct f2fs_sb_info *sbi, bool remount)
set_opt(sbi, INLINE_XATTR);
set_opt(sbi, INLINE_DATA);
set_opt(sbi, INLINE_DENTRY);
+ set_opt(sbi, INLINE_TAIL);
set_opt(sbi, MERGE_CHECKPOINT);
F2FS_OPTION(sbi).unusable_cap = 0;
sbi->sb->s_flags |= SB_LAZYTIME;
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 02/13] f2fs: add inline tail disk layout definition
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 01/13] f2fs: add inline tail mount option Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 03/13] f2fs: implement inline tail write & truncate Wu Bo via Linux-f2fs-devel
` (12 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
When inline tail is enabled, use a compact block address array. And the
rest space is used to save file tail data. The layout of an inode block
as following:
| inode block | 4096 | inline tail enable |
| --------------- | ---- | --------------------------|
| inode info | 360 | |
| --------------- | ---- | --------------------------|
| | | extra info | 0~36 |
| | | **compact_addr[16] | 64 |
| addr table[923] | 3692 | reserved | 4 |
| | | **tail data | |
| | | inline_xattr | 200 |
| --------------- | ---- | --------------------------|
| nid table[5] | 20 |
| node footer | 24 |
So if we define compact address array size is 16, then we can have
3392~3428 bytes to store tail data.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/f2fs.h | 27 ++++++++++++++++++++++++++-
fs/f2fs/inode.c | 6 ++++++
2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 3956740ca7e2..e02a6619b90a 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -476,12 +476,17 @@ static inline bool __has_cursum_space(struct f2fs_journal *journal,
/* for inline stuff */
#define DEF_INLINE_RESERVED_SIZE 1
+#define COMPACT_ADDRS_PER_INODE 16
static inline int get_extra_isize(struct inode *inode);
static inline int get_inline_xattr_addrs(struct inode *inode);
+static inline int get_reserved_addrs(struct inode *inode);
#define MAX_INLINE_DATA(inode) (sizeof(__le32) * \
(CUR_ADDRS_PER_INODE(inode) - \
get_inline_xattr_addrs(inode) - \
- DEF_INLINE_RESERVED_SIZE))
+ get_reserved_addrs(inode)))
+
+#define MAX_INLINE_TAIL(inode) (MAX_INLINE_DATA(inode) + \
+ (PAGE_SIZE * COMPACT_ADDRS_PER_INODE))
/* for inline dir */
#define NR_INLINE_DENTRY(inode) (MAX_INLINE_DATA(inode) * BITS_PER_BYTE / \
@@ -805,6 +810,7 @@ enum {
FI_ATOMIC_COMMITTED, /* indicate atomic commit completed except disk sync */
FI_ATOMIC_REPLACE, /* indicate atomic replace */
FI_OPENED_FILE, /* indicate file has been opened */
+ FI_INLINE_TAIL, /* used for inline tail */
FI_MAX, /* max flag, never be used */
};
@@ -3002,6 +3008,7 @@ static inline void f2fs_change_bit(unsigned int nr, char *addr)
#define F2FS_DIRSYNC_FL 0x00010000 /* dirsync behaviour (directories only) */
#define F2FS_PROJINHERIT_FL 0x20000000 /* Create with parents projid */
#define F2FS_CASEFOLD_FL 0x40000000 /* Casefolded file */
+#define F2FS_INLINE_TAIL 0x80000000 /* Has inline tail */
#define F2FS_QUOTA_DEFAULT_FL (F2FS_NOATIME_FL | F2FS_IMMUTABLE_FL)
@@ -3263,6 +3270,11 @@ static inline int f2fs_has_inline_data(struct inode *inode)
return is_inode_flag_set(inode, FI_INLINE_DATA);
}
+static inline int f2fs_has_inline_tail(struct inode *inode)
+{
+ return is_inode_flag_set(inode, FI_INLINE_TAIL);
+}
+
static inline int f2fs_exist_data(struct inode *inode)
{
return is_inode_flag_set(inode, FI_DATA_EXIST);
@@ -3299,6 +3311,9 @@ static inline void *inline_data_addr(struct inode *inode, struct page *page)
{
__le32 *addr = get_dnode_addr(inode, page);
+ if (f2fs_has_inline_tail(inode))
+ addr += COMPACT_ADDRS_PER_INODE;
+
return (void *)(addr + DEF_INLINE_RESERVED_SIZE);
}
@@ -3428,6 +3443,16 @@ static inline int get_extra_isize(struct inode *inode)
return F2FS_I(inode)->i_extra_isize / sizeof(__le32);
}
+static inline int get_reserved_addrs(struct inode *inode)
+{
+ int size = DEF_INLINE_RESERVED_SIZE;
+
+ if (f2fs_has_inline_tail(inode))
+ size += COMPACT_ADDRS_PER_INODE;
+
+ return size;
+}
+
static inline int get_inline_xattr_addrs(struct inode *inode)
{
return F2FS_I(inode)->i_inline_xattr_size;
diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
index aef57172014f..88dfcf16da0e 100644
--- a/fs/f2fs/inode.c
+++ b/fs/f2fs/inode.c
@@ -425,6 +425,8 @@ static int do_read_inode(struct inode *inode)
fi->i_dir_level = ri->i_dir_level;
get_inline_info(inode, ri);
+ if (fi->i_flags & F2FS_INLINE_TAIL)
+ set_bit(FI_INLINE_TAIL, fi->flags);
fi->i_extra_isize = f2fs_has_extra_attr(inode) ?
le16_to_cpu(ri->i_extra_isize) : 0;
@@ -666,6 +668,10 @@ void f2fs_update_inode(struct inode *inode, struct page *node_page)
memset(&ri->i_ext, 0, sizeof(ri->i_ext));
}
set_raw_inline(inode, ri);
+ if (is_inode_flag_set(inode, FI_INLINE_TAIL))
+ F2FS_I(inode)->i_flags |= F2FS_INLINE_TAIL;
+ else
+ F2FS_I(inode)->i_flags &= ~F2FS_INLINE_TAIL;
ri->i_atime = cpu_to_le64(inode_get_atime_sec(inode));
ri->i_ctime = cpu_to_le64(inode_get_ctime_sec(inode));
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 03/13] f2fs: implement inline tail write & truncate
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 01/13] f2fs: add inline tail mount option Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 02/13] f2fs: add inline tail disk layout definition Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 04/13] f2fs: implement inline tail read & fiemap Wu Bo via Linux-f2fs-devel
` (11 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
As f2fs inline data is a special case of inline tail, we can expand
inline tail based on inline data.
If file tail can inline to inode block, not bother to pre-allocate block
at write begin. When tail page writing back, inline it or normally write
it if the tail is oversize.
And when inode page writing back, update inline data from tail page.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/data.c | 30 ++++++++++++++++++++++++++++++
fs/f2fs/f2fs.h | 16 ++++++++++++++++
fs/f2fs/file.c | 10 ++++++++++
fs/f2fs/inline.c | 38 +++++++++++++++++++++++++++++++-------
fs/f2fs/node.c | 6 +++++-
5 files changed, 92 insertions(+), 8 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6457e5bca9c9..cd13b5703228 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2776,6 +2776,7 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
loff_t psize = (loff_t)(page->index + 1) << PAGE_SHIFT;
unsigned offset = 0;
bool need_balance_fs = false;
+ bool need_clear_tail = false;
bool quota_inode = IS_NOQUOTA(inode);
int err = 0;
struct f2fs_io_info fio = {
@@ -2867,6 +2868,16 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
goto out;
}
+ if (f2fs_has_inline_tail(inode) && page->index == end_index) {
+ if (support_tail_inline(inode, i_size)) {
+ err = f2fs_write_inline_data(inode, page);
+ if (!err)
+ goto out;
+ } else {
+ need_clear_tail = true;
+ }
+ }
+
if (err == -EAGAIN) {
err = f2fs_do_write_data_page(&fio);
if (err == -EAGAIN) {
@@ -2889,6 +2900,11 @@ int f2fs_write_single_data_page(struct page *page, int *submitted,
if (err && err != -ENOENT)
goto redirty_out;
+ if (need_clear_tail) {
+ err = f2fs_clear_inline_tail(inode, false);
+ if (err)
+ goto redirty_out;
+ }
out:
inode_dec_dirty_pages(inode);
if (err) {
@@ -3393,6 +3409,11 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
flag = F2FS_GET_BLOCK_DEFAULT;
f2fs_map_lock(sbi, flag);
locked = true;
+ } else if (f2fs_has_inline_tail(inode)) {
+ if (!support_tail_inline(inode, pos + len)) {
+ f2fs_map_lock(sbi, flag);
+ locked = true;
+ }
} else if ((pos & PAGE_MASK) >= i_size_read(inode)) {
f2fs_map_lock(sbi, flag);
locked = true;
@@ -3421,6 +3442,15 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
goto out;
}
+ if (f2fs_has_inline_tail(inode)) {
+ if (support_tail_inline(inode, pos + len)) {
+ f2fs_do_read_inline_data(page_folio(page), ipage);
+ if (inode->i_nlink)
+ set_page_private_inline(ipage);
+ goto out;
+ }
+ }
+
if (!f2fs_lookup_read_extent_cache_block(inode, index,
&dn.data_blkaddr)) {
if (locked) {
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index e02a6619b90a..2e0530b55e74 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3322,6 +3322,21 @@ static inline int f2fs_has_inline_dentry(struct inode *inode)
return is_inode_flag_set(inode, FI_INLINE_DENTRY);
}
+static inline bool support_tail_inline(struct inode *inode, loff_t i_size)
+{
+ const pgoff_t tail_index = ((unsigned long long)i_size) >> PAGE_SHIFT;
+ unsigned long tail_len = i_size & (PAGE_SIZE - 1);
+
+ if (tail_index > COMPACT_ADDRS_PER_INODE)
+ return false;
+ if (!tail_len)
+ return false;
+ if (tail_len > MAX_INLINE_DATA(inode))
+ return false;
+
+ return true;
+}
+
static inline int is_file(struct inode *inode, int type)
{
return F2FS_I(inode)->i_advise & type;
@@ -4197,6 +4212,7 @@ void f2fs_truncate_inline_inode(struct inode *inode,
int f2fs_read_inline_data(struct inode *inode, struct folio *folio);
int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page);
int f2fs_convert_inline_inode(struct inode *inode);
+int f2fs_clear_inline_tail(struct inode *inode, bool force);
int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry);
int f2fs_write_inline_data(struct inode *inode, struct page *page);
int f2fs_recover_inline_data(struct inode *inode, struct page *npage);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 168f08507004..957d1ff55350 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -748,6 +748,9 @@ int f2fs_do_truncate_blocks(struct inode *inode, u64 from, bool lock)
goto out;
}
+ if (f2fs_has_inline_tail(inode) && f2fs_exist_data(inode))
+ f2fs_truncate_inline_inode(inode, ipage, 0);
+
set_new_dnode(&dn, inode, ipage, NULL, 0);
err = f2fs_get_dnode_of_data(&dn, free_from, LOOKUP_NODE_RA);
if (err) {
@@ -4703,6 +4706,13 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter,
return ret;
}
+ if (f2fs_has_inline_tail(inode) &&
+ (pos + count > MAX_INLINE_TAIL(inode))) {
+ ret = f2fs_clear_inline_tail(inode, true);
+ if (ret)
+ return ret;
+ }
+
/* Do not preallocate blocks that will be written partially in 4KB. */
map.m_lblk = F2FS_BLK_ALIGN(pos);
map.m_len = F2FS_BYTES_TO_BLK(pos + count);
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index cca7d448e55c..2e63e9389fd7 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -102,6 +102,7 @@ void f2fs_truncate_inline_inode(struct inode *inode,
{
void *addr;
+ from = from & (PAGE_SIZE - 1);
if (from >= MAX_INLINE_DATA(inode))
return;
@@ -156,11 +157,12 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
};
struct node_info ni;
int dirty, err;
+ pgoff_t index = page->index;
if (!f2fs_exist_data(dn->inode))
goto clear_out;
- err = f2fs_reserve_block(dn, 0);
+ err = f2fs_reserve_block(dn, index);
if (err)
return err;
@@ -176,8 +178,8 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
if (unlikely(dn->data_blkaddr != NEW_ADDR)) {
f2fs_put_dnode(dn);
set_sbi_flag(fio.sbi, SBI_NEED_FSCK);
- f2fs_warn(fio.sbi, "%s: corrupted inline inode ino=%lx, i_addr[0]:0x%x, run fsck to fix.",
- __func__, dn->inode->i_ino, dn->data_blkaddr);
+ f2fs_warn(fio.sbi, "%s: corrupted inline inode ino=%lx, i_addr[%lu]:0x%x, run fsck to fix.",
+ __func__, dn->inode->i_ino, index, dn->data_blkaddr);
f2fs_handle_error(fio.sbi, ERROR_INVALID_BLKADDR);
return -EFSCORRUPTED;
}
@@ -210,10 +212,33 @@ int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
clear_out:
stat_dec_inline_inode(dn->inode);
clear_inode_flag(dn->inode, FI_INLINE_DATA);
+ if (index >= COMPACT_ADDRS_PER_INODE)
+ clear_inode_flag(dn->inode, FI_INLINE_TAIL);
f2fs_put_dnode(dn);
return 0;
}
+int f2fs_clear_inline_tail(struct inode *inode, bool force)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct page *ipage;
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_SHIFT;
+
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
+ if (IS_ERR(ipage))
+ return PTR_ERR(ipage);
+
+ f2fs_truncate_inline_inode(inode, ipage, 0);
+ clear_page_private_inline(ipage);
+
+ if (force || end_index >= COMPACT_ADDRS_PER_INODE)
+ clear_inode_flag(inode, FI_INLINE_TAIL);
+
+ f2fs_put_page(ipage, 1);
+ return 0;
+}
+
int f2fs_convert_inline_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
@@ -263,20 +288,19 @@ int f2fs_convert_inline_inode(struct inode *inode)
int f2fs_write_inline_data(struct inode *inode, struct page *page)
{
struct dnode_of_data dn;
+ pgoff_t index = page->index;
int err;
set_new_dnode(&dn, inode, NULL, NULL, 0);
- err = f2fs_get_dnode_of_data(&dn, 0, LOOKUP_NODE);
+ err = f2fs_get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err)
return err;
- if (!f2fs_has_inline_data(inode)) {
+ if (!f2fs_has_inline_data(inode) && !f2fs_has_inline_tail(inode)) {
f2fs_put_dnode(&dn);
return -EAGAIN;
}
- f2fs_bug_on(F2FS_I_SB(inode), page->index);
-
f2fs_wait_on_page_writeback(dn.inode_page, NODE, true, true);
memcpy_from_page(inline_data_addr(inode, dn.inode_page),
page, 0, MAX_INLINE_DATA(inode));
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index b72ef96f7e33..5c45de7f60a1 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1514,6 +1514,8 @@ static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino)
{
struct inode *inode;
struct page *page;
+ loff_t i_size;
+ pgoff_t end_index;
int ret;
/* should flush inline_data before evict_inode */
@@ -1521,7 +1523,9 @@ static void flush_inline_data(struct f2fs_sb_info *sbi, nid_t ino)
if (!inode)
return;
- page = f2fs_pagecache_get_page(inode->i_mapping, 0,
+ i_size = i_size_read(inode);
+ end_index = i_size >> PAGE_SHIFT;
+ page = f2fs_pagecache_get_page(inode->i_mapping, end_index,
FGP_LOCK|FGP_NOWAIT, 0);
if (!page)
goto iput_out;
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 04/13] f2fs: implement inline tail read & fiemap
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (2 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 03/13] f2fs: implement inline tail write & truncate Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode Wu Bo via Linux-f2fs-devel
` (10 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Expand the inline data read & fiemap to support inline tail.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/data.c | 31 ++++++++++++++++++++++++++++++-
fs/f2fs/inline.c | 26 ++++++++++++--------------
2 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index cd13b5703228..476325a26d4e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1922,9 +1922,11 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 logical = 0, phys = 0, size = 0;
u32 flags = 0;
int ret = 0;
- bool compr_cluster = false, compr_appended;
+ bool compr_cluster = false, compr_appended, inline_tail = false;
unsigned int cluster_size = F2FS_I(inode)->i_cluster_size;
unsigned int count_in_cluster = 0;
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_SHIFT;
loff_t maxbytes;
if (fieinfo->fi_flags & FIEMAP_FLAG_CACHE) {
@@ -1983,6 +1985,16 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
/* HOLE */
if (!compr_cluster && !(map.m_flags & F2FS_MAP_FLAGS)) {
+ /*
+ * There is a reserved space between address array and inline
+ * data. So it must meet this hole state before inline data.
+ */
+ if (f2fs_has_inline_tail(inode) && start_blk == end_index
+ && f2fs_exist_data(inode)) {
+ inline_tail = true;
+ goto fill_extent;
+ }
+
start_blk = next_pgofs;
if (blks_to_bytes(inode, start_blk) < blks_to_bytes(inode,
@@ -2000,6 +2012,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
goto skip_fill;
}
+fill_extent:
if (size) {
flags |= FIEMAP_EXTENT_MERGED;
if (IS_ENCRYPTED(inode))
@@ -2013,6 +2026,13 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
size = 0;
}
+ if (inline_tail) {
+ start = blks_to_bytes(inode, start_blk);
+ ret = f2fs_inline_data_fiemap(inode, fieinfo, start, len);
+ if (ret != -EAGAIN)
+ goto out;
+ }
+
if (start_blk > last_blk)
goto out;
@@ -2377,6 +2397,8 @@ static int f2fs_mpage_readpages(struct inode *inode,
#endif
unsigned nr_pages = rac ? readahead_count(rac) : 1;
unsigned max_nr_pages = nr_pages;
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_SHIFT;
pgoff_t index;
int ret = 0;
@@ -2397,6 +2419,12 @@ static int f2fs_mpage_readpages(struct inode *inode,
index = folio_index(folio);
+ if (f2fs_has_inline_tail(inode) && index == end_index &&
+ f2fs_exist_data(inode)) {
+ ret = f2fs_read_inline_data(inode, folio);
+ goto out;
+ }
+
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (!f2fs_compressed_file(inode))
goto read_single_page;
@@ -2462,6 +2490,7 @@ static int f2fs_mpage_readpages(struct inode *inode,
}
#endif
}
+out:
if (bio)
f2fs_submit_read_bio(F2FS_I_SB(inode), bio, DATA);
return ret;
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 2e63e9389fd7..30b18053e784 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -86,8 +86,6 @@ void f2fs_do_read_inline_data(struct folio *folio, struct page *ipage)
if (folio_test_uptodate(folio))
return;
- f2fs_bug_on(F2FS_I_SB(inode), folio_index(folio));
-
folio_zero_segment(folio, MAX_INLINE_DATA(inode), folio_size(folio));
/* Copy the whole inline data block */
@@ -126,15 +124,12 @@ int f2fs_read_inline_data(struct inode *inode, struct folio *folio)
return PTR_ERR(ipage);
}
- if (!f2fs_has_inline_data(inode)) {
+ if (!f2fs_has_inline_data(inode) && !f2fs_has_inline_tail(inode)) {
f2fs_put_page(ipage, 1);
return -EAGAIN;
}
- if (folio_index(folio))
- folio_zero_segment(folio, 0, folio_size(folio));
- else
- f2fs_do_read_inline_data(folio, ipage);
+ f2fs_do_read_inline_data(folio, ipage);
if (!folio_test_uptodate(folio))
folio_mark_uptodate(folio);
@@ -814,7 +809,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
int f2fs_inline_data_fiemap(struct inode *inode,
struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
{
- __u64 byteaddr, ilen;
+ __u64 byteaddr, ilen, offset;
__u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
FIEMAP_EXTENT_LAST;
struct node_info ni;
@@ -826,7 +821,8 @@ int f2fs_inline_data_fiemap(struct inode *inode,
return PTR_ERR(ipage);
if ((S_ISREG(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
- !f2fs_has_inline_data(inode)) {
+ !f2fs_has_inline_data(inode) &&
+ !f2fs_has_inline_tail(inode)) {
err = -EAGAIN;
goto out;
}
@@ -836,12 +832,14 @@ int f2fs_inline_data_fiemap(struct inode *inode,
goto out;
}
- ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode));
- if (start >= ilen)
+ ilen = min_t(size_t, MAX_INLINE_DATA(inode),
+ i_size_read(inode) & (PAGE_SIZE - 1));
+ offset = start & (PAGE_SIZE - 1);
+ if (offset >= ilen)
goto out;
- if (start + len < ilen)
- ilen = start + len;
- ilen -= start;
+ if (offset + len < ilen)
+ ilen = offset + len;
+ ilen -= offset;
err = f2fs_get_node_info(F2FS_I_SB(inode), inode->i_ino, &ni, false);
if (err)
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (3 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 04/13] f2fs: implement inline tail read & fiemap Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 9:49 ` [f2fs-dev] [External Mail] " Huang Jianan via Linux-f2fs-devel
2024-09-03 9:50 ` Huang Jianan via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 06/13] f2fs: fix address info has been truncated Wu Bo via Linux-f2fs-devel
` (9 subsequent siblings)
14 siblings, 2 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Set inline tail flag to enable this feature when new inode is created.
Inherit the conditions from inline data.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/namei.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index 38b4750475db..13c295ea19de 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -315,6 +315,9 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
/* Should enable inline_data after compression set */
if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
set_inode_flag(inode, FI_INLINE_DATA);
+ /* Inherit the conditions from inline data */
+ if (test_opt(sbi, INLINE_TAIL) && f2fs_has_inline_data(inode))
+ set_inode_flag(inode, FI_INLINE_TAIL);
if (name && !test_opt(sbi, DISABLE_EXT_IDENTIFY))
set_file_temperature(sbi, inode, name);
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 06/13] f2fs: fix address info has been truncated
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (4 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 07/13] f2fs: support seek for inline tail Wu Bo via Linux-f2fs-devel
` (8 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
If there is no data inline, the address table should not be truncate,
in case there may be reserved address info.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/inline.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 30b18053e784..a542956d618a 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -224,7 +224,8 @@ int f2fs_clear_inline_tail(struct inode *inode, bool force)
if (IS_ERR(ipage))
return PTR_ERR(ipage);
- f2fs_truncate_inline_inode(inode, ipage, 0);
+ if (f2fs_exist_data(inode))
+ f2fs_truncate_inline_inode(inode, ipage, 0);
clear_page_private_inline(ipage);
if (force || end_index >= COMPACT_ADDRS_PER_INODE)
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 07/13] f2fs: support seek for inline tail
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (5 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 06/13] f2fs: fix address info has been truncated Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 08/13] f2fs: convert inline tail when inode expand Wu Bo via Linux-f2fs-devel
` (7 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Fix to support seek for inline tail files
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/file.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 957d1ff55350..dda4cf6d7325 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -400,6 +400,7 @@ static bool __found_offset(struct address_space *mapping,
block_t blkaddr = f2fs_data_blkaddr(dn);
struct inode *inode = mapping->host;
bool compressed_cluster = false;
+ bool inline_tail = false;
if (f2fs_compressed_file(inode)) {
block_t first_blkaddr = data_blkaddr(dn->inode, dn->node_page,
@@ -408,6 +409,14 @@ static bool __found_offset(struct address_space *mapping,
compressed_cluster = first_blkaddr == COMPRESS_ADDR;
}
+ if (f2fs_has_inline_tail(inode)) {
+ loff_t isize = i_size_read(inode);
+ if ((isize >> PAGE_SHIFT == index) &&
+ (f2fs_exist_data(inode) ||
+ xa_get_mark(&mapping->i_pages, index, PAGECACHE_TAG_DIRTY)))
+ inline_tail = true;
+ }
+
switch (whence) {
case SEEK_DATA:
if (__is_valid_data_blkaddr(blkaddr))
@@ -417,11 +426,13 @@ static bool __found_offset(struct address_space *mapping,
return true;
if (compressed_cluster)
return true;
+ if (inline_tail)
+ return true;
break;
case SEEK_HOLE:
if (compressed_cluster)
return false;
- if (blkaddr == NULL_ADDR)
+ if (blkaddr == NULL_ADDR && !inline_tail)
return true;
break;
}
@@ -473,6 +484,8 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
}
end_offset = ADDRS_PER_PAGE(dn.node_page, inode);
+ if (f2fs_has_inline_tail(inode))
+ end_offset = COMPACT_ADDRS_PER_INODE + 1;
/* find data/hole in dnode block */
for (; dn.ofs_in_node < end_offset;
@@ -496,6 +509,8 @@ static loff_t f2fs_seek_block(struct file *file, loff_t offset, int whence)
}
}
f2fs_put_dnode(&dn);
+ if (f2fs_has_inline_tail(inode) && dn.ofs_in_node == end_offset)
+ goto fail;
}
if (whence == SEEK_DATA)
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 08/13] f2fs: convert inline tail when inode expand
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (6 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 07/13] f2fs: support seek for inline tail Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 09/13] f2fs: fix data loss during inline tail writing Wu Bo via Linux-f2fs-devel
` (6 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Convert an inline tail file to a normal file when the inode expansion
exceeds the maximum size allowed for the inline tail.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/f2fs.h | 1 +
fs/f2fs/file.c | 6 ++++++
fs/f2fs/inline.c | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 50 insertions(+)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 2e0530b55e74..f889d97209c7 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4211,6 +4211,7 @@ void f2fs_truncate_inline_inode(struct inode *inode,
struct page *ipage, u64 from);
int f2fs_read_inline_data(struct inode *inode, struct folio *folio);
int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page);
+int f2fs_convert_inline_tail(struct inode *inode);
int f2fs_convert_inline_inode(struct inode *inode);
int f2fs_clear_inline_tail(struct inode *inode, bool force);
int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index dda4cf6d7325..2551403a5b83 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1783,6 +1783,12 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
if (err)
return err;
+ if (len + offset > MAX_INLINE_TAIL(inode)) {
+ err = f2fs_convert_inline_tail(inode);
+ if (err)
+ return err;
+ }
+
f2fs_balance_fs(sbi, true);
pg_start = ((unsigned long long)offset) >> PAGE_SHIFT;
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index a542956d618a..c2f84f3dde67 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -235,6 +235,49 @@ int f2fs_clear_inline_tail(struct inode *inode, bool force)
return 0;
}
+int f2fs_convert_inline_tail(struct inode *inode)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct dnode_of_data dn;
+ struct page *ipage, *page;
+ loff_t i_size = i_size_read(inode);
+ pgoff_t end_index = i_size >> PAGE_SHIFT;
+ int err = 0;
+
+ if (!f2fs_has_inline_tail(inode))
+ return 0;
+
+ page = f2fs_grab_cache_page(inode->i_mapping, end_index, false);
+ if (!page)
+ return -ENOMEM;
+
+ f2fs_lock_op(sbi);
+
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
+ if (IS_ERR(ipage)) {
+ err = PTR_ERR(ipage);
+ goto out;
+ }
+
+ set_new_dnode(&dn, inode, ipage, ipage, 0);
+
+ if (f2fs_has_inline_tail(inode))
+ err = f2fs_convert_inline_page(&dn, page);
+
+ f2fs_put_dnode(&dn);
+out:
+ f2fs_unlock_op(sbi);
+
+ f2fs_put_page(page, 1);
+
+ if (!err) {
+ err = f2fs_clear_inline_tail(inode, true);
+ f2fs_balance_fs(sbi, dn.node_changed);
+ }
+
+ return err;
+}
+
int f2fs_convert_inline_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 09/13] f2fs: fix data loss during inline tail writing
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (7 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 08/13] f2fs: convert inline tail when inode expand Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 10/13] f2fs: avoid inlining quota files Wu Bo via Linux-f2fs-devel
` (5 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
This is detected by xfstest generic/114. The inline data needs to be
read out before writing to avoid losing the already inline data.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/data.c | 3 ++-
fs/f2fs/file.c | 7 ++++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 476325a26d4e..275c5739993e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3477,7 +3477,8 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
if (inode->i_nlink)
set_page_private_inline(ipage);
goto out;
- }
+ } else if (f2fs_exist_data(inode))
+ f2fs_do_read_inline_data(page_folio(page), ipage);
}
if (!f2fs_lookup_read_extent_cache_block(inode, index,
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 2551403a5b83..64ea0bfc2e1e 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -4729,7 +4729,7 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *iter,
if (f2fs_has_inline_tail(inode) &&
(pos + count > MAX_INLINE_TAIL(inode))) {
- ret = f2fs_clear_inline_tail(inode, true);
+ ret = f2fs_convert_inline_tail(inode);
if (ret)
return ret;
}
@@ -4842,6 +4842,7 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from,
if (iocb->ki_flags & IOCB_NOWAIT) {
/* f2fs_convert_inline_inode() and block allocation can block */
if (f2fs_has_inline_data(inode) ||
+ f2fs_has_inline_tail(inode) ||
!f2fs_overwrite_io(inode, pos, count)) {
ret = -EAGAIN;
goto out;
@@ -4861,6 +4862,10 @@ static ssize_t f2fs_dio_write_iter(struct kiocb *iocb, struct iov_iter *from,
if (ret)
goto out;
+ ret = f2fs_convert_inline_tail(inode);
+ if (ret)
+ goto out;
+
f2fs_down_read(&fi->i_gc_rwsem[WRITE]);
if (do_opu)
f2fs_down_read(&fi->i_gc_rwsem[READ]);
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 10/13] f2fs: avoid inlining quota files
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (8 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 09/13] f2fs: fix data loss during inline tail writing Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 11/13] f2fs: fix inline tail data lost Wu Bo via Linux-f2fs-devel
` (4 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Quota files have a different write path and are incompatible with
inlined inodes (whether data or tail inlined). To simplify the process,
inlining is disabled for quota files here.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/data.c | 9 +++++++++
fs/f2fs/super.c | 10 ++++++++++
2 files changed, 19 insertions(+)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 275c5739993e..6d7b6074763f 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3641,6 +3641,15 @@ static int f2fs_write_begin(struct file *file, struct address_space *mapping,
goto fail;
}
+ if (IS_NOQUOTA(inode)) {
+ err = f2fs_convert_inline_inode(inode);
+ if (err)
+ goto fail;
+ err = f2fs_convert_inline_tail(inode);
+ if (err)
+ goto fail;
+ }
+
#ifdef CONFIG_F2FS_FS_COMPRESSION
if (f2fs_compressed_file(inode)) {
int ret;
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d4ec32ba6cad..0f54c055f053 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2807,6 +2807,14 @@ static int f2fs_quota_enable(struct super_block *sb, int type, int format_id,
return PTR_ERR(qf_inode);
}
+ err = f2fs_convert_inline_inode(qf_inode);
+ if (err)
+ goto out;
+
+ err = f2fs_convert_inline_tail(qf_inode);
+ if (err)
+ goto out;
+
/* Don't account quota for quota files to avoid recursion */
inode_lock(qf_inode);
qf_inode->i_flags |= S_NOQUOTA;
@@ -2818,6 +2826,8 @@ static int f2fs_quota_enable(struct super_block *sb, int type, int format_id,
inode_unlock(qf_inode);
err = dquot_load_quota_inode(qf_inode, type, format_id, flags);
+
+out:
iput(qf_inode);
return err;
}
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 11/13] f2fs: fix inline tail data lost
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (9 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 10/13] f2fs: avoid inlining quota files Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 12/13] f2fs: convert inline tails to avoid potential issues Wu Bo via Linux-f2fs-devel
` (3 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Before adding a new page to the tail, the old inlined tail page must be
converted first; otherwise, the data on that page could be lost.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/data.c | 26 +++++++++++++++++++++-----
1 file changed, 21 insertions(+), 5 deletions(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 6d7b6074763f..f52834c1cacd 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3418,7 +3418,9 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
block_t *blk_addr, bool *node_changed)
{
struct inode *inode = page->mapping->host;
+ loff_t i_size = i_size_read(inode);
pgoff_t index = page->index;
+ pgoff_t end_index = i_size >> PAGE_SHIFT;
struct dnode_of_data dn;
struct page *ipage;
bool locked = false;
@@ -3438,12 +3440,12 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
flag = F2FS_GET_BLOCK_DEFAULT;
f2fs_map_lock(sbi, flag);
locked = true;
- } else if (f2fs_has_inline_tail(inode)) {
+ } else if (f2fs_has_inline_tail(inode) && index >= end_index) {
if (!support_tail_inline(inode, pos + len)) {
f2fs_map_lock(sbi, flag);
locked = true;
}
- } else if ((pos & PAGE_MASK) >= i_size_read(inode)) {
+ } else if ((pos & PAGE_MASK) >= i_size) {
f2fs_map_lock(sbi, flag);
locked = true;
}
@@ -3471,14 +3473,28 @@ static int prepare_write_begin(struct f2fs_sb_info *sbi,
goto out;
}
- if (f2fs_has_inline_tail(inode)) {
+ if (f2fs_has_inline_tail(inode) && index >= end_index) {
+ if (index > end_index && f2fs_exist_data(inode)) {
+ struct page *tail_page = f2fs_grab_cache_page(
+ inode->i_mapping, end_index, false);
+ if (!page) {
+ err = -ENOMEM;
+ goto out;
+ }
+ err = f2fs_convert_inline_page(&dn, tail_page);
+ f2fs_put_page(tail_page, 1);
+ if (err || dn.data_blkaddr != NULL_ADDR)
+ goto out;
+ }
if (support_tail_inline(inode, pos + len)) {
f2fs_do_read_inline_data(page_folio(page), ipage);
if (inode->i_nlink)
set_page_private_inline(ipage);
goto out;
- } else if (f2fs_exist_data(inode))
- f2fs_do_read_inline_data(page_folio(page), ipage);
+ }
+ err = f2fs_convert_inline_page(&dn, page);
+ if (err || dn.data_blkaddr != NULL_ADDR)
+ goto out;
}
if (!f2fs_lookup_read_extent_cache_block(inode, index,
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 12/13] f2fs: convert inline tails to avoid potential issues
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (10 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 11/13] f2fs: fix inline tail data lost Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery Wu Bo via Linux-f2fs-devel
` (2 subsequent siblings)
14 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
Like the 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@vivo.com>
---
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
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (11 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 12/13] f2fs: convert inline tails to avoid potential issues Wu Bo via Linux-f2fs-devel
@ 2024-09-03 8:54 ` Wu Bo via Linux-f2fs-devel
2024-09-03 22:47 ` kernel test robot
2024-09-03 16:29 ` [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Eric Biggers via Linux-f2fs-devel
2024-09-06 9:02 ` Juhyung Park
14 siblings, 1 reply; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-03 8:54 UTC (permalink / raw)
To: linux-kernel; +Cc: Wu Bo, Jaegeuk Kim, Wu Bo, linux-f2fs-devel
The recovery logic is similar to that of inline data, except that the
inline tail may require recovery of some blocks. This is because the
inline tail has a 16-size block address array, whereas inline data does
not.
Signed-off-by: Wu Bo <bo.wu@vivo.com>
---
fs/f2fs/f2fs.h | 1 +
fs/f2fs/inline.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
fs/f2fs/recovery.c | 9 +++++++-
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index f889d97209c7..7d5348e2127b 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4217,6 +4217,7 @@ int f2fs_clear_inline_tail(struct inode *inode, bool force);
int f2fs_try_convert_inline_dir(struct inode *dir, struct dentry *dentry);
int f2fs_write_inline_data(struct inode *inode, struct page *page);
int f2fs_recover_inline_data(struct inode *inode, struct page *npage);
+int f2fs_recover_inline_tail(struct inode *inode, struct page *npage);
struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
const struct f2fs_filename *fname,
struct page **res_page);
diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index c2f84f3dde67..003367c4cc2e 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -414,6 +414,57 @@ int f2fs_recover_inline_data(struct inode *inode, struct page *npage)
return 0;
}
+int f2fs_recover_inline_tail(struct inode *inode, struct page *npage)
+{
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+ struct f2fs_inode *ri = NULL;
+ void *src_addr, *dst_addr;
+ struct page *ipage;
+
+ if (IS_INODE(npage))
+ ri = F2FS_INODE(npage);
+
+ if (f2fs_has_inline_tail(inode) &&
+ ri && (ri->i_flags & F2FS_INLINE_TAIL)) {
+process_inline:
+ if (!(ri->i_inline & F2FS_DATA_EXIST))
+ return 0;
+
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
+ if (IS_ERR(ipage))
+ return PTR_ERR(ipage);
+
+ f2fs_wait_on_page_writeback(ipage, NODE, true, true);
+
+ src_addr = inline_data_addr(inode, npage);
+ dst_addr = inline_data_addr(inode, ipage);
+ memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode));
+
+ set_inode_flag(inode, FI_DATA_EXIST);
+
+ set_page_dirty(ipage);
+ f2fs_put_page(ipage, 1);
+ return 0;
+ }
+
+ if (f2fs_has_inline_tail(inode)) {
+ ipage = f2fs_get_node_page(sbi, inode->i_ino);
+ if (IS_ERR(ipage))
+ return PTR_ERR(ipage);
+ f2fs_truncate_inline_inode(inode, ipage, 0);
+ clear_inode_flag(inode, FI_INLINE_TAIL);
+ f2fs_put_page(ipage, 1);
+ } else if (ri && (ri->i_inline & F2FS_INLINE_TAIL)) {
+ int ret;
+
+ ret = f2fs_truncate_blocks(inode,
+ COMPACT_ADDRS_PER_INODE >> PAGE_SHIFT, false);
+ if (ret)
+ return ret;
+ goto process_inline;
+ }
+ return 0;
+}
struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
const struct f2fs_filename *fname,
struct page **res_page)
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index 9756f0f2b7f7..d73a557b82d9 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -645,9 +645,16 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
goto out;
}
+ err = f2fs_recover_inline_tail(inode, page);
+ if (err)
+ goto out;
+
/* step 3: recover data indices */
start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);
- end = start + ADDRS_PER_PAGE(page, inode);
+ if (f2fs_has_inline_tail(inode))
+ end = COMPACT_ADDRS_PER_INODE;
+ else
+ end = start + ADDRS_PER_PAGE(page, inode);
set_new_dnode(&dn, inode, NULL, NULL, 0);
retry_dn:
--
2.35.3
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [External Mail] [PATCH 05/13] f2fs: set inline tail flag when create inode
2024-09-03 8:54 ` [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode Wu Bo via Linux-f2fs-devel
@ 2024-09-03 9:49 ` Huang Jianan via Linux-f2fs-devel
2024-09-03 9:50 ` Huang Jianan via Linux-f2fs-devel
1 sibling, 0 replies; 23+ messages in thread
From: Huang Jianan via Linux-f2fs-devel @ 2024-09-03 9:49 UTC (permalink / raw)
To: Wu Bo, linux-kernel@vger.kernel.org
Cc: Wu Bo, Jaegeuk Kim, linux-f2fs-devel@lists.sourceforge.net
On 2024/9/3 16:54, Wu Bo via Linux-f2fs-devel wrote:
Hi Bo,
>
> Set inline tail flag to enable this feature when new inode is created.
> Inherit the conditions from inline data.
>
> Signed-off-by: Wu Bo <bo.wu@vivo.com>
> ---
> fs/f2fs/namei.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
> index 38b4750475db..13c295ea19de 100644
> --- a/fs/f2fs/namei.c
> +++ b/fs/f2fs/namei.c
> @@ -315,6 +315,9 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
> /* Should enable inline_data after compression set */
> if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
> set_inode_flag(inode, FI_INLINE_DATA);
> + /* Inherit the conditions from inline data */
> + if (test_opt(sbi, INLINE_TAIL) && f2fs_has_inline_data(inode))
> + set_inode_flag(inode, FI_INLINE_TAIL);
Should f2fs_post_read_required() be checked here, like inline data?
Thanks,
Jianan
>
> if (name && !test_opt(sbi, DISABLE_EXT_IDENTIFY))
> set_file_temperature(sbi, inode, name);
> --
> 2.35.3
>
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [External Mail] [PATCH 05/13] f2fs: set inline tail flag when create inode
2024-09-03 8:54 ` [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode Wu Bo via Linux-f2fs-devel
2024-09-03 9:49 ` [f2fs-dev] [External Mail] " Huang Jianan via Linux-f2fs-devel
@ 2024-09-03 9:50 ` Huang Jianan via Linux-f2fs-devel
2024-09-04 3:03 ` [f2fs-dev] " Wu Bo via Linux-f2fs-devel
1 sibling, 1 reply; 23+ messages in thread
From: Huang Jianan via Linux-f2fs-devel @ 2024-09-03 9:50 UTC (permalink / raw)
To: Wu Bo, linux-kernel@vger.kernel.org
Cc: Jaegeuk Kim, linux-f2fs-devel@lists.sourceforge.net
On 2024/9/3 16:54, Wu Bo via Linux-f2fs-devel wrote:
> [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈
>
> Set inline tail flag to enable this feature when new inode is created.
> Inherit the conditions from inline data.
>
> Signed-off-by: Wu Bo <bo.wu@vivo.com>
> ---
> fs/f2fs/namei.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
> index 38b4750475db..13c295ea19de 100644
> --- a/fs/f2fs/namei.c
> +++ b/fs/f2fs/namei.c
> @@ -315,6 +315,9 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
> /* Should enable inline_data after compression set */
> if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
> set_inode_flag(inode, FI_INLINE_DATA);
> + /* Inherit the conditions from inline data */
> + if (test_opt(sbi, INLINE_TAIL) && f2fs_has_inline_data(inode))
> + set_inode_flag(inode, FI_INLINE_TAIL);
Should f2fs_post_read_required() be checked here, like inline data?
Thanks,
Jianan
>
> if (name && !test_opt(sbi, DISABLE_EXT_IDENTIFY))
> set_file_temperature(sbi, inode, name);
> --
> 2.35.3
>
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (12 preceding siblings ...)
2024-09-03 8:54 ` [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery Wu Bo via Linux-f2fs-devel
@ 2024-09-03 16:29 ` Eric Biggers via Linux-f2fs-devel
2024-09-04 3:14 ` Wu Bo via Linux-f2fs-devel
2024-09-06 9:02 ` Juhyung Park
14 siblings, 1 reply; 23+ messages in thread
From: Eric Biggers via Linux-f2fs-devel @ 2024-09-03 16:29 UTC (permalink / raw)
To: Wu Bo; +Cc: Wu Bo, Jaegeuk Kim, linux-kernel, linux-f2fs-devel
On Tue, Sep 03, 2024 at 02:54:44AM -0600, Wu Bo via Linux-f2fs-devel wrote:
> The inode in F2FS occupies an entire 4k block. For many small files, this means
> they consume much more space than their actual size. Therefore, there is
> significant potential to better utilize the inode block space.
>
> Currently, F2FS has two features to make use of the inode block space: inline
> data and inline xattr.
>
> Inline data stores file which size is smaller then 3.5k in inode block. However,
> for slightly larger small files, there still have much waste.
> For example, a 5k file requires 3 blocks, totaling 12k of space, which is
> more than twice the size of the file itself!
>
> Additionally, the end of a file often does not occupy an entire block. If we can
> store the end of the file data within the inode block, we can save an entire
> block for the file. This is particularly important for small files.
>
> In fact, the current inline data is a special case of inline tail, and
> inline tail is an extension of inline data.
>
> To make it simple, inline tail only on small files(<64k). And for larger files,
> inline tails don't provide any significant benefits.
>
> The layout of an inline tail inode block is following:
>
> | inode block | 4096 | inline tail enable |
> | --------------- | ---- | --------------------------|
> | inode info | 360 | |
> | --------------- | ---- | --------------------------|
> | | | extra info | 0~36 |
> | | | **compact_addr[16] | 64 |
> | addr table[923] | 3692 | reserved | 4 |
> | | | **tail data | |
> | | | inline_xattr | 200 |
> | --------------- | ---- | --------------------------|
> | nid table[5] | 20 |
> | node footer | 24 |
>
> F2fs-tools to support inline tail:
> https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
>
> I tested inline tail by copying the source code of Linux 6.9.7. The storage
> space was reduced by approximately 8%. Additionally, due to the reduced IO, the
> copy time also reduced by around 10%.
>
> This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
> -g quick' both with and without the patch; no regressions were observed.
> The test result is:
> f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
> Failures: generic/050 generic/064 generic/250 generic/252 generic/563
> generic/735
> Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
>
> Wu Bo (13):
> f2fs: add inline tail mount option
> f2fs: add inline tail disk layout definition
> f2fs: implement inline tail write & truncate
> f2fs: implement inline tail read & fiemap
> f2fs: set inline tail flag when create inode
> f2fs: fix address info has been truncated
> f2fs: support seek for inline tail
> f2fs: convert inline tail when inode expand
> f2fs: fix data loss during inline tail writing
> f2fs: avoid inlining quota files
> f2fs: fix inline tail data lost
> f2fs: convert inline tails to avoid potential issues
> f2fs: implement inline tail forward recovery
>
> fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
> fs/f2fs/f2fs.h | 46 ++++++++++++-
> fs/f2fs/file.c | 85 +++++++++++++++++++++++-
> fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
> fs/f2fs/inode.c | 6 ++
> fs/f2fs/namei.c | 3 +
> fs/f2fs/node.c | 6 +-
> fs/f2fs/recovery.c | 9 ++-
> fs/f2fs/super.c | 25 +++++++
> fs/f2fs/verity.c | 4 ++
> 10 files changed, 409 insertions(+), 27 deletions(-)
This is disabled on encrypted files, right?
- Eric
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery
2024-09-03 8:54 ` [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery Wu Bo via Linux-f2fs-devel
@ 2024-09-03 22:47 ` kernel test robot
0 siblings, 0 replies; 23+ messages in thread
From: kernel test robot @ 2024-09-03 22:47 UTC (permalink / raw)
To: Wu Bo, linux-kernel
Cc: Chao Yu, linux-f2fs-devel, oe-kbuild-all, Wu Bo, Jaegeuk Kim
Hi Wu,
kernel test robot noticed the following build warnings:
[auto build test WARNING on v6.11-rc6]
[also build test WARNING on linus/master]
[cannot apply to jaegeuk-f2fs/dev-test jaegeuk-f2fs/dev next-20240903]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Wu-Bo/f2fs-add-inline-tail-mount-option/20240903-164436
base: v6.11-rc6
patch link: https://lore.kernel.org/r/b6e9e02244cf2460df1256e257103e2c77fae2a9.1725334811.git.bo.wu%40vivo.com
patch subject: [PATCH 13/13] f2fs: implement inline tail forward recovery
config: arc-randconfig-r112-20240903 (https://download.01.org/0day-ci/archive/20240904/202409040652.Gn2vQXRR-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240904/202409040652.Gn2vQXRR-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202409040652.Gn2vQXRR-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> fs/f2fs/inline.c:428:34: sparse: sparse: restricted __le32 degrades to integer
vim +428 fs/f2fs/inline.c
416
417 int f2fs_recover_inline_tail(struct inode *inode, struct page *npage)
418 {
419 struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
420 struct f2fs_inode *ri = NULL;
421 void *src_addr, *dst_addr;
422 struct page *ipage;
423
424 if (IS_INODE(npage))
425 ri = F2FS_INODE(npage);
426
427 if (f2fs_has_inline_tail(inode) &&
> 428 ri && (ri->i_flags & F2FS_INLINE_TAIL)) {
429 process_inline:
430 if (!(ri->i_inline & F2FS_DATA_EXIST))
431 return 0;
432
433 ipage = f2fs_get_node_page(sbi, inode->i_ino);
434 if (IS_ERR(ipage))
435 return PTR_ERR(ipage);
436
437 f2fs_wait_on_page_writeback(ipage, NODE, true, true);
438
439 src_addr = inline_data_addr(inode, npage);
440 dst_addr = inline_data_addr(inode, ipage);
441 memcpy(dst_addr, src_addr, MAX_INLINE_DATA(inode));
442
443 set_inode_flag(inode, FI_DATA_EXIST);
444
445 set_page_dirty(ipage);
446 f2fs_put_page(ipage, 1);
447 return 0;
448 }
449
450 if (f2fs_has_inline_tail(inode)) {
451 ipage = f2fs_get_node_page(sbi, inode->i_ino);
452 if (IS_ERR(ipage))
453 return PTR_ERR(ipage);
454 f2fs_truncate_inline_inode(inode, ipage, 0);
455 clear_inode_flag(inode, FI_INLINE_TAIL);
456 f2fs_put_page(ipage, 1);
457 } else if (ri && (ri->i_inline & F2FS_INLINE_TAIL)) {
458 int ret;
459
460 ret = f2fs_truncate_blocks(inode,
461 COMPACT_ADDRS_PER_INODE >> PAGE_SHIFT, false);
462 if (ret)
463 return ret;
464 goto process_inline;
465 }
466 return 0;
467 }
468 struct f2fs_dir_entry *f2fs_find_in_inline_dir(struct inode *dir,
469 const struct f2fs_filename *fname,
470 struct page **res_page)
471 {
472 struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
473 struct f2fs_dir_entry *de;
474 struct f2fs_dentry_ptr d;
475 struct page *ipage;
476 void *inline_dentry;
477
478 ipage = f2fs_get_node_page(sbi, dir->i_ino);
479 if (IS_ERR(ipage)) {
480 *res_page = ipage;
481 return NULL;
482 }
483
484 inline_dentry = inline_data_addr(dir, ipage);
485
486 make_dentry_ptr_inline(dir, &d, inline_dentry);
487 de = f2fs_find_target_dentry(&d, fname, NULL);
488 unlock_page(ipage);
489 if (IS_ERR(de)) {
490 *res_page = ERR_CAST(de);
491 de = NULL;
492 }
493 if (de)
494 *res_page = ipage;
495 else
496 f2fs_put_page(ipage, 0);
497
498 return de;
499 }
500
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode
2024-09-03 9:50 ` Huang Jianan via Linux-f2fs-devel
@ 2024-09-04 3:03 ` Wu Bo via Linux-f2fs-devel
0 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-04 3:03 UTC (permalink / raw)
To: Huang Jianan
Cc: Wu Bo, Jaegeuk Kim, linux-kernel@vger.kernel.org, Wu Bo,
linux-f2fs-devel@lists.sourceforge.net
On Tue, Sep 03, 2024 at 09:50:41AM +0000, Huang Jianan via Linux-f2fs-devel wrote:
> On 2024/9/3 16:54, Wu Bo via Linux-f2fs-devel wrote:
> > [外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈
> >
> > Set inline tail flag to enable this feature when new inode is created.
> > Inherit the conditions from inline data.
> >
> > Signed-off-by: Wu Bo <bo.wu@vivo.com>
> > ---
> > fs/f2fs/namei.c | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
> > index 38b4750475db..13c295ea19de 100644
> > --- a/fs/f2fs/namei.c
> > +++ b/fs/f2fs/namei.c
> > @@ -315,6 +315,9 @@ static struct inode *f2fs_new_inode(struct mnt_idmap *idmap,
> > /* Should enable inline_data after compression set */
> > if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
> > set_inode_flag(inode, FI_INLINE_DATA);
> > + /* Inherit the conditions from inline data */
> > + if (test_opt(sbi, INLINE_TAIL) && f2fs_has_inline_data(inode))
> > + set_inode_flag(inode, FI_INLINE_TAIL);
>
> Should f2fs_post_read_required() be checked here, like inline data?
To ensure the conditions for enabling inline tail are the same as for inline
data, I deliberately use the inline data flag to determine whether to enable
the inline tail.
Thanks
>
> Thanks,
> Jianan
>
> >
> > if (name && !test_opt(sbi, DISABLE_EXT_IDENTIFY))
> > set_file_temperature(sbi, inode, name);
> > --
> > 2.35.3
> >
> >
> >
> > _______________________________________________
> > Linux-f2fs-devel mailing list
> > Linux-f2fs-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
2024-09-03 16:29 ` [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Eric Biggers via Linux-f2fs-devel
@ 2024-09-04 3:14 ` Wu Bo via Linux-f2fs-devel
0 siblings, 0 replies; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-04 3:14 UTC (permalink / raw)
To: Eric Biggers; +Cc: Wu Bo, Jaegeuk Kim, linux-kernel, Wu Bo, linux-f2fs-devel
On Tue, Sep 03, 2024 at 09:29:30AM -0700, Eric Biggers via Linux-f2fs-devel wrote:
> On Tue, Sep 03, 2024 at 02:54:44AM -0600, Wu Bo via Linux-f2fs-devel wrote:
> > The inode in F2FS occupies an entire 4k block. For many small files, this means
> > they consume much more space than their actual size. Therefore, there is
> > significant potential to better utilize the inode block space.
> >
> > Currently, F2FS has two features to make use of the inode block space: inline
> > data and inline xattr.
> >
> > Inline data stores file which size is smaller then 3.5k in inode block. However,
> > for slightly larger small files, there still have much waste.
> > For example, a 5k file requires 3 blocks, totaling 12k of space, which is
> > more than twice the size of the file itself!
> >
> > Additionally, the end of a file often does not occupy an entire block. If we can
> > store the end of the file data within the inode block, we can save an entire
> > block for the file. This is particularly important for small files.
> >
> > In fact, the current inline data is a special case of inline tail, and
> > inline tail is an extension of inline data.
> >
> > To make it simple, inline tail only on small files(<64k). And for larger files,
> > inline tails don't provide any significant benefits.
> >
> > The layout of an inline tail inode block is following:
> >
> > | inode block | 4096 | inline tail enable |
> > | --------------- | ---- | --------------------------|
> > | inode info | 360 | |
> > | --------------- | ---- | --------------------------|
> > | | | extra info | 0~36 |
> > | | | **compact_addr[16] | 64 |
> > | addr table[923] | 3692 | reserved | 4 |
> > | | | **tail data | |
> > | | | inline_xattr | 200 |
> > | --------------- | ---- | --------------------------|
> > | nid table[5] | 20 |
> > | node footer | 24 |
> >
> > F2fs-tools to support inline tail:
> > https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
> >
> > I tested inline tail by copying the source code of Linux 6.9.7. The storage
> > space was reduced by approximately 8%. Additionally, due to the reduced IO, the
> > copy time also reduced by around 10%.
> >
> > This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
> > -g quick' both with and without the patch; no regressions were observed.
> > The test result is:
> > f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
> > Failures: generic/050 generic/064 generic/250 generic/252 generic/563
> > generic/735
> > Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
> >
> > Wu Bo (13):
> > f2fs: add inline tail mount option
> > f2fs: add inline tail disk layout definition
> > f2fs: implement inline tail write & truncate
> > f2fs: implement inline tail read & fiemap
> > f2fs: set inline tail flag when create inode
> > f2fs: fix address info has been truncated
> > f2fs: support seek for inline tail
> > f2fs: convert inline tail when inode expand
> > f2fs: fix data loss during inline tail writing
> > f2fs: avoid inlining quota files
> > f2fs: fix inline tail data lost
> > f2fs: convert inline tails to avoid potential issues
> > f2fs: implement inline tail forward recovery
> >
> > fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
> > fs/f2fs/f2fs.h | 46 ++++++++++++-
> > fs/f2fs/file.c | 85 +++++++++++++++++++++++-
> > fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
> > fs/f2fs/inode.c | 6 ++
> > fs/f2fs/namei.c | 3 +
> > fs/f2fs/node.c | 6 +-
> > fs/f2fs/recovery.c | 9 ++-
> > fs/f2fs/super.c | 25 +++++++
> > fs/f2fs/verity.c | 4 ++
> > 10 files changed, 409 insertions(+), 27 deletions(-)
>
> This is disabled on encrypted files, right?
Yes, conditions for enabling inline tail are the same as for inline
data now.
Thanks
>
> - Eric
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
` (13 preceding siblings ...)
2024-09-03 16:29 ` [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Eric Biggers via Linux-f2fs-devel
@ 2024-09-06 9:02 ` Juhyung Park
2024-09-06 10:57 ` Wu Bo via Linux-f2fs-devel
14 siblings, 1 reply; 23+ messages in thread
From: Juhyung Park @ 2024-09-06 9:02 UTC (permalink / raw)
To: Wu Bo; +Cc: Wu Bo, Jaegeuk Kim, linux-kernel, linux-f2fs-devel
Hi Wu,
Interesting patch-set.
A quick test here on my daily-driver phone's data (785558 inodes) with
both compression and encryption disabled, copied via rsync to 2 fresh
f2fs partitions with and without inline tail:
Before: 170064928KiB
After: 169249780KiB
So about 0.48% saved.
Let me know if this is an unexpected result.
Thanks,
On Tue, Sep 3, 2024 at 5:42 PM Wu Bo via Linux-f2fs-devel
<linux-f2fs-devel@lists.sourceforge.net> wrote:
>
> The inode in F2FS occupies an entire 4k block. For many small files, this means
> they consume much more space than their actual size. Therefore, there is
> significant potential to better utilize the inode block space.
>
> Currently, F2FS has two features to make use of the inode block space: inline
> data and inline xattr.
>
> Inline data stores file which size is smaller then 3.5k in inode block. However,
> for slightly larger small files, there still have much waste.
> For example, a 5k file requires 3 blocks, totaling 12k of space, which is
> more than twice the size of the file itself!
>
> Additionally, the end of a file often does not occupy an entire block. If we can
> store the end of the file data within the inode block, we can save an entire
> block for the file. This is particularly important for small files.
>
> In fact, the current inline data is a special case of inline tail, and
> inline tail is an extension of inline data.
>
> To make it simple, inline tail only on small files(<64k). And for larger files,
> inline tails don't provide any significant benefits.
>
> The layout of an inline tail inode block is following:
>
> | inode block | 4096 | inline tail enable |
> | --------------- | ---- | --------------------------|
> | inode info | 360 | |
> | --------------- | ---- | --------------------------|
> | | | extra info | 0~36 |
> | | | **compact_addr[16] | 64 |
> | addr table[923] | 3692 | reserved | 4 |
> | | | **tail data | |
> | | | inline_xattr | 200 |
> | --------------- | ---- | --------------------------|
> | nid table[5] | 20 |
> | node footer | 24 |
>
> F2fs-tools to support inline tail:
> https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
>
> I tested inline tail by copying the source code of Linux 6.9.7. The storage
> space was reduced by approximately 8%. Additionally, due to the reduced IO, the
> copy time also reduced by around 10%.
>
> This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
> -g quick' both with and without the patch; no regressions were observed.
> The test result is:
> f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
> Failures: generic/050 generic/064 generic/250 generic/252 generic/563
> generic/735
> Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
>
> Wu Bo (13):
> f2fs: add inline tail mount option
> f2fs: add inline tail disk layout definition
> f2fs: implement inline tail write & truncate
> f2fs: implement inline tail read & fiemap
> f2fs: set inline tail flag when create inode
> f2fs: fix address info has been truncated
> f2fs: support seek for inline tail
> f2fs: convert inline tail when inode expand
> f2fs: fix data loss during inline tail writing
> f2fs: avoid inlining quota files
> f2fs: fix inline tail data lost
> f2fs: convert inline tails to avoid potential issues
> f2fs: implement inline tail forward recovery
>
> fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
> fs/f2fs/f2fs.h | 46 ++++++++++++-
> fs/f2fs/file.c | 85 +++++++++++++++++++++++-
> fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
> fs/f2fs/inode.c | 6 ++
> fs/f2fs/namei.c | 3 +
> fs/f2fs/node.c | 6 +-
> fs/f2fs/recovery.c | 9 ++-
> fs/f2fs/super.c | 25 +++++++
> fs/f2fs/verity.c | 4 ++
> 10 files changed, 409 insertions(+), 27 deletions(-)
>
> --
> 2.35.3
>
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
2024-09-06 9:02 ` Juhyung Park
@ 2024-09-06 10:57 ` Wu Bo via Linux-f2fs-devel
2024-09-06 14:52 ` Juhyung Park
0 siblings, 1 reply; 23+ messages in thread
From: Wu Bo via Linux-f2fs-devel @ 2024-09-06 10:57 UTC (permalink / raw)
To: Juhyung Park; +Cc: linux-kernel, linux-f2fs-devel, Wu Bo, Wu Bo, Jaegeuk Kim
On Fri, Sep 06, 2024 at 06:02:42PM +0900, Juhyung Park wrote:
> Hi Wu,
>
> Interesting patch-set.
>
> A quick test here on my daily-driver phone's data (785558 inodes) with
> both compression and encryption disabled, copied via rsync to 2 fresh
> f2fs partitions with and without inline tail:
> Before: 170064928KiB
> After: 169249780KiB
>
> So about 0.48% saved.
>
Hi Juhyung,
Thanks for your test. If it's not too much trouble, please help check the f2fs
statistics:
cat /sys/kernel/debug/f2fs/status | grep Utilization
However, it’s more likely that the benefits of inline tail are indeed limited on
mobile devices. I previously evaluated the gains on my own phone, and they were
less than 1% too.
From the data on your phone, the average size is 170064928KiB/785558≈200KiB.
Storage space on phones is primarily consumed by multimedia files, so the
proportion of files smaller than 64KB is quite small.
Therefore, compared to phone storage, scenarios like storing Linux source code,
which involve many small files, are more likely to yield noticeable benefits.
However, don't be too disappointed with it, as it can still double the benefits
based on the existing gains from inline data.
Inline data:
https://lore.kernel.org/linux-f2fs-devel/1384096401-25169-1-git-send-email-huajun.li.lee@gmail.com/T/#u
Thanks,
Wu Bo
> Let me know if this is an unexpected result.
>
> Thanks,
>
> On Tue, Sep 3, 2024 at 5:42 PM Wu Bo via Linux-f2fs-devel
> <linux-f2fs-devel@lists.sourceforge.net> wrote:
> >
> > The inode in F2FS occupies an entire 4k block. For many small files, this means
> > they consume much more space than their actual size. Therefore, there is
> > significant potential to better utilize the inode block space.
> >
> > Currently, F2FS has two features to make use of the inode block space: inline
> > data and inline xattr.
> >
> > Inline data stores file which size is smaller then 3.5k in inode block. However,
> > for slightly larger small files, there still have much waste.
> > For example, a 5k file requires 3 blocks, totaling 12k of space, which is
> > more than twice the size of the file itself!
> >
> > Additionally, the end of a file often does not occupy an entire block. If we can
> > store the end of the file data within the inode block, we can save an entire
> > block for the file. This is particularly important for small files.
> >
> > In fact, the current inline data is a special case of inline tail, and
> > inline tail is an extension of inline data.
> >
> > To make it simple, inline tail only on small files(<64k). And for larger files,
> > inline tails don't provide any significant benefits.
> >
> > The layout of an inline tail inode block is following:
> >
> > | inode block | 4096 | inline tail enable |
> > | --------------- | ---- | --------------------------|
> > | inode info | 360 | |
> > | --------------- | ---- | --------------------------|
> > | | | extra info | 0~36 |
> > | | | **compact_addr[16] | 64 |
> > | addr table[923] | 3692 | reserved | 4 |
> > | | | **tail data | |
> > | | | inline_xattr | 200 |
> > | --------------- | ---- | --------------------------|
> > | nid table[5] | 20 |
> > | node footer | 24 |
> >
> > F2fs-tools to support inline tail:
> > https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
> >
> > I tested inline tail by copying the source code of Linux 6.9.7. The storage
> > space was reduced by approximately 8%. Additionally, due to the reduced IO, the
> > copy time also reduced by around 10%.
> >
> > This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
> > -g quick' both with and without the patch; no regressions were observed.
> > The test result is:
> > f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
> > Failures: generic/050 generic/064 generic/250 generic/252 generic/563
> > generic/735
> > Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
> >
> > Wu Bo (13):
> > f2fs: add inline tail mount option
> > f2fs: add inline tail disk layout definition
> > f2fs: implement inline tail write & truncate
> > f2fs: implement inline tail read & fiemap
> > f2fs: set inline tail flag when create inode
> > f2fs: fix address info has been truncated
> > f2fs: support seek for inline tail
> > f2fs: convert inline tail when inode expand
> > f2fs: fix data loss during inline tail writing
> > f2fs: avoid inlining quota files
> > f2fs: fix inline tail data lost
> > f2fs: convert inline tails to avoid potential issues
> > f2fs: implement inline tail forward recovery
> >
> > fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
> > fs/f2fs/f2fs.h | 46 ++++++++++++-
> > fs/f2fs/file.c | 85 +++++++++++++++++++++++-
> > fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
> > fs/f2fs/inode.c | 6 ++
> > fs/f2fs/namei.c | 3 +
> > fs/f2fs/node.c | 6 +-
> > fs/f2fs/recovery.c | 9 ++-
> > fs/f2fs/super.c | 25 +++++++
> > fs/f2fs/verity.c | 4 ++
> > 10 files changed, 409 insertions(+), 27 deletions(-)
> >
> > --
> > 2.35.3
> >
> >
> >
> > _______________________________________________
> > Linux-f2fs-devel mailing list
> > Linux-f2fs-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail
2024-09-06 10:57 ` Wu Bo via Linux-f2fs-devel
@ 2024-09-06 14:52 ` Juhyung Park
0 siblings, 0 replies; 23+ messages in thread
From: Juhyung Park @ 2024-09-06 14:52 UTC (permalink / raw)
To: Wu Bo; +Cc: Wu Bo, Jaegeuk Kim, linux-kernel, linux-f2fs-devel
Hi Wu,
On Fri, Sep 6, 2024 at 7:42 PM Wu Bo <bo.wu@vivo.com> wrote:
>
> On Fri, Sep 06, 2024 at 06:02:42PM +0900, Juhyung Park wrote:
> > Hi Wu,
> >
> > Interesting patch-set.
> >
> > A quick test here on my daily-driver phone's data (785558 inodes) with
> > both compression and encryption disabled, copied via rsync to 2 fresh
> > f2fs partitions with and without inline tail:
> > Before: 170064928KiB
> > After: 169249780KiB
> >
> > So about 0.48% saved.
> >
> Hi Juhyung,
>
> Thanks for your test. If it's not too much trouble, please help check the f2fs
> statistics:
> cat /sys/kernel/debug/f2fs/status | grep Utilization
# w/o inline tail
Utilization: 70% (42153224 valid blocks, 0 discard blocks)
# w/ inline tail
Utilization: 69% (41949437 valid blocks, 0 discard blocks)
>
> However, it’s more likely that the benefits of inline tail are indeed limited on
> mobile devices. I previously evaluated the gains on my own phone, and they were
> less than 1% too.
>
> From the data on your phone, the average size is 170064928KiB/785558≈200KiB.
> Storage space on phones is primarily consumed by multimedia files, so the
> proportion of files smaller than 64KB is quite small.
>
> Therefore, compared to phone storage, scenarios like storing Linux source code,
> which involve many small files, are more likely to yield noticeable benefits.
Mmm.
I do have my own Linux setups using f2fs as well with extended node bitmap:
# Workstation, 2.5T/3.5T, 55602404 inodes
Utilization: 70% (657421720 valid blocks, 902 discard blocks)
# Laptop, 736G/1.9T, 12229380 inodes
Utilization: 39% (190980868 valid blocks, 2887 discard blocks)
I do have a lot of small files here, it'll be interesting to test this
out but I can't afford to run an unstable kernel for those atm. (Not
to mention finding a new SSD for migration.)
>
> However, don't be too disappointed with it, as it can still double the benefits
> based on the existing gains from inline data.
> Inline data:
> https://lore.kernel.org/linux-f2fs-devel/1384096401-25169-1-git-send-email-huajun.li.lee@gmail.com/T/#u
>
> Thanks,
> Wu Bo
>
> > Let me know if this is an unexpected result.
> >
> > Thanks,
> >
> > On Tue, Sep 3, 2024 at 5:42 PM Wu Bo via Linux-f2fs-devel
> > <linux-f2fs-devel@lists.sourceforge.net> wrote:
> > >
> > > The inode in F2FS occupies an entire 4k block. For many small files, this means
> > > they consume much more space than their actual size. Therefore, there is
> > > significant potential to better utilize the inode block space.
> > >
> > > Currently, F2FS has two features to make use of the inode block space: inline
> > > data and inline xattr.
> > >
> > > Inline data stores file which size is smaller then 3.5k in inode block. However,
> > > for slightly larger small files, there still have much waste.
> > > For example, a 5k file requires 3 blocks, totaling 12k of space, which is
> > > more than twice the size of the file itself!
> > >
> > > Additionally, the end of a file often does not occupy an entire block. If we can
> > > store the end of the file data within the inode block, we can save an entire
> > > block for the file. This is particularly important for small files.
> > >
> > > In fact, the current inline data is a special case of inline tail, and
> > > inline tail is an extension of inline data.
> > >
> > > To make it simple, inline tail only on small files(<64k). And for larger files,
> > > inline tails don't provide any significant benefits.
> > >
> > > The layout of an inline tail inode block is following:
> > >
> > > | inode block | 4096 | inline tail enable |
> > > | --------------- | ---- | --------------------------|
> > > | inode info | 360 | |
> > > | --------------- | ---- | --------------------------|
> > > | | | extra info | 0~36 |
> > > | | | **compact_addr[16] | 64 |
> > > | addr table[923] | 3692 | reserved | 4 |
> > > | | | **tail data | |
> > > | | | inline_xattr | 200 |
> > > | --------------- | ---- | --------------------------|
> > > | nid table[5] | 20 |
> > > | node footer | 24 |
> > >
> > > F2fs-tools to support inline tail:
> > > https://lore.kernel.org/linux-f2fs-devel/20240903075931.3339584-1-bo.wu@vivo.com
> > >
> > > I tested inline tail by copying the source code of Linux 6.9.7. The storage
> > > space was reduced by approximately 8%. Additionally, due to the reduced IO, the
> > > copy time also reduced by around 10%.
> > >
> > > This patch series has been tested with xfstests by running 'kvm-xfstests -c f2fs
> > > -g quick' both with and without the patch; no regressions were observed.
> > > The test result is:
> > > f2fs/default: 583 tests, 6 failures, 213 skipped, 650 seconds
> > > Failures: generic/050 generic/064 generic/250 generic/252 generic/563
> > > generic/735
> > > Totals: 607 tests, 213 skipped, 30 failures, 0 errors, 579s
> > >
> > > Wu Bo (13):
> > > f2fs: add inline tail mount option
> > > f2fs: add inline tail disk layout definition
> > > f2fs: implement inline tail write & truncate
> > > f2fs: implement inline tail read & fiemap
> > > f2fs: set inline tail flag when create inode
> > > f2fs: fix address info has been truncated
> > > f2fs: support seek for inline tail
> > > f2fs: convert inline tail when inode expand
> > > f2fs: fix data loss during inline tail writing
> > > f2fs: avoid inlining quota files
> > > f2fs: fix inline tail data lost
> > > f2fs: convert inline tails to avoid potential issues
> > > f2fs: implement inline tail forward recovery
> > >
> > > fs/f2fs/data.c | 93 +++++++++++++++++++++++++-
> > > fs/f2fs/f2fs.h | 46 ++++++++++++-
> > > fs/f2fs/file.c | 85 +++++++++++++++++++++++-
> > > fs/f2fs/inline.c | 159 +++++++++++++++++++++++++++++++++++++++------
> > > fs/f2fs/inode.c | 6 ++
> > > fs/f2fs/namei.c | 3 +
> > > fs/f2fs/node.c | 6 +-
> > > fs/f2fs/recovery.c | 9 ++-
> > > fs/f2fs/super.c | 25 +++++++
> > > fs/f2fs/verity.c | 4 ++
> > > 10 files changed, 409 insertions(+), 27 deletions(-)
> > >
> > > --
> > > 2.35.3
> > >
> > >
> > >
> > > _______________________________________________
> > > Linux-f2fs-devel mailing list
> > > Linux-f2fs-devel@lists.sourceforge.net
> > > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
> >
> >
> > _______________________________________________
> > Linux-f2fs-devel mailing list
> > Linux-f2fs-devel@lists.sourceforge.net
> > https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2024-09-06 14:53 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-09-03 8:54 [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 01/13] f2fs: add inline tail mount option Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 02/13] f2fs: add inline tail disk layout definition Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 03/13] f2fs: implement inline tail write & truncate Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 04/13] f2fs: implement inline tail read & fiemap Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 05/13] f2fs: set inline tail flag when create inode Wu Bo via Linux-f2fs-devel
2024-09-03 9:49 ` [f2fs-dev] [External Mail] " Huang Jianan via Linux-f2fs-devel
2024-09-03 9:50 ` Huang Jianan via Linux-f2fs-devel
2024-09-04 3:03 ` [f2fs-dev] " Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 06/13] f2fs: fix address info has been truncated Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 07/13] f2fs: support seek for inline tail Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 08/13] f2fs: convert inline tail when inode expand Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 09/13] f2fs: fix data loss during inline tail writing Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 10/13] f2fs: avoid inlining quota files Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 11/13] f2fs: fix inline tail data lost Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 12/13] f2fs: convert inline tails to avoid potential issues Wu Bo via Linux-f2fs-devel
2024-09-03 8:54 ` [f2fs-dev] [PATCH 13/13] f2fs: implement inline tail forward recovery Wu Bo via Linux-f2fs-devel
2024-09-03 22:47 ` kernel test robot
2024-09-03 16:29 ` [f2fs-dev] [PATCH 00/13] f2fs: introduce inline tail Eric Biggers via Linux-f2fs-devel
2024-09-04 3:14 ` Wu Bo via Linux-f2fs-devel
2024-09-06 9:02 ` Juhyung Park
2024-09-06 10:57 ` Wu Bo via Linux-f2fs-devel
2024-09-06 14:52 ` Juhyung Park
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).