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...@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