From: Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Kelvin Zhang <zhangxp1998@gmail.com>,
linux-f2fs-devel@lists.sourceforge.net
Cc: jaegeuk@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [f2fs-dev] [PATCH v7 06/11] f2fs: describe {i, d, id}node block layout dynamically
Date: Tue, 1 Sep 2026 19:48:45 +0800 [thread overview]
Message-ID: <63f1e1ae-444f-406f-b76d-312cd0b76bdb@kernel.org> (raw)
In-Reply-To: <a21bc0d17ce657d0ccd86fd398785b946fa268d6.1788213716.git.zhangxp1998@gmail.com>
On 9/1/26 06:08, Kelvin Zhang wrote:
> An inode block ends with five i_nid entries followed by a node footer.
> Data block address pointers (i_addr[]) precede them. Similarly, direct and
> indirect node blocks contain data addresses or node IDs followed by a node
> footer at the end of the block.
>
> Describe struct f2fs_inode, struct direct_node, and
> struct indirect_node using flexible array members. Compute the locations
> of i_nid and node footers dynamically from the filesystem block size.
> Introduce F2FS_INODE_NIDS() and F2FS_NODE_FOOTER() helpers to access these
> tail fields.
>
> Compute sbi->addrs_per_inode, sbi->addrs_per_block, and
> sbi->nids_per_block in init_sb_info(), and update node management, file
> mapping, and recovery paths accordingly.
>
> Signed-off-by: Kelvin Zhang <zhangxp1998@gmail.com>
> ---
> fs/f2fs/data.c | 2 +-
> fs/f2fs/f2fs.h | 32 ++++++++++++++++++-------
> fs/f2fs/gc.c | 2 +-
> fs/f2fs/inline.c | 3 +--
> fs/f2fs/inode.c | 5 ++--
> fs/f2fs/node.c | 4 +---
> fs/f2fs/node.h | 53 +++++++++++++++++++----------------------
> fs/f2fs/super.c | 5 ++++
> include/linux/f2fs_fs.h | 26 +++++++++++++++-----
> 9 files changed, 79 insertions(+), 53 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 6ae0eb37d20f..751b7a457d9a 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -2027,7 +2027,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
>
> phys = F2FS_BLK_TO_BYTES(ni.blk_addr);
> offset = offsetof(struct f2fs_inode, i_addr) +
> - sizeof(__le32) * (DEF_ADDRS_PER_INODE -
> + sizeof(__le32) * (DEF_ADDRS_PER_INODE_SBI(sbi) -
> get_inline_xattr_addrs(inode));
>
> phys += offset;
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index d2e54573ed34..247e56522441 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1853,6 +1853,9 @@ struct f2fs_sb_info {
> unsigned int log_blocksize; /* log2 block size */
> unsigned int blocksize; /* block size */
> unsigned int nat_entries_per_block; /* NAT entries in a block */
> + unsigned int addrs_per_inode; /* addresses in an inode block */
> + unsigned int addrs_per_block; /* addresses in a direct node block */
> + unsigned int nids_per_block; /* node IDs in an indirect node block */
> unsigned int sit_entries_per_block; /* SIT entries in a block */
> unsigned int orphans_per_block; /* orphan inodes in a block */
> unsigned int dentries_per_block; /* dentries in a block */
> @@ -2248,6 +2251,7 @@ static inline struct f2fs_sb_info *F2FS_F_SB(const struct folio *folio)
>
> #define SIT_ENTRY_PER_BLOCK(sbi) ((sbi)->sit_entries_per_block)
> #define NAT_ENTRY_PER_BLOCK(sbi) ((sbi)->nat_entries_per_block)
> +#define DEF_ADDRS_PER_INODE_SBI(sbi) ((sbi)->addrs_per_inode)
#define DEF_ADDRS_PER_INODE
> #define F2FS_ORPHANS_PER_BLOCK(sbi) ((sbi)->orphans_per_block)
> #define GET_ORPHAN_BLOCKS(sbi, n) DIV_ROUND_UP((n), \
> F2FS_ORPHANS_PER_BLOCK(sbi))
> @@ -2297,6 +2301,12 @@ static inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi)
> return (struct f2fs_checkpoint *)(sbi->ckpt);
> }
>
> +static inline struct node_footer *F2FS_NODE_FOOTER(const struct folio *folio)
> +{
> + return folio_address(folio) + F2FS_BLKSIZE -
> + sizeof(struct node_footer);
> +}
> +
> static inline struct f2fs_node *F2FS_NODE(const struct folio *folio)
> {
> return (struct f2fs_node *)folio_address(folio);
> @@ -2307,6 +2317,12 @@ static inline struct f2fs_inode *F2FS_INODE(const struct folio *folio)
> return &((struct f2fs_node *)folio_address(folio))->i;
> }
>
> +static inline __le32 *F2FS_INODE_NIDS(const struct folio *folio)
> +{
> + return folio_address(folio) + F2FS_BLKSIZE - sizeof(struct node_footer) -
> + SIZE_OF_I_NID;
> +}
> +
> static inline struct f2fs_nm_info *NM_I(struct f2fs_sb_info *sbi)
> {
> return (struct f2fs_nm_info *)(sbi->nm_info);
> @@ -3277,13 +3293,11 @@ static inline void f2fs_radix_tree_insert(struct radix_tree_root *root,
> cond_resched();
> }
>
> -#define RAW_IS_INODE(p) ((p)->footer.nid == (p)->footer.ino)
> -
> static inline bool IS_INODE(const struct folio *folio)
> {
> - struct f2fs_node *p = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
>
> - return RAW_IS_INODE(p);
> + return footer->nid == footer->ino;
> }
>
> static inline int offset_in_addr(struct f2fs_inode *i)
> @@ -3292,9 +3306,11 @@ static inline int offset_in_addr(struct f2fs_inode *i)
> (le16_to_cpu(i->i_extra_isize) / sizeof(__le32)) : 0;
> }
>
> -static inline __le32 *blkaddr_in_node(struct f2fs_node *node)
> +static inline __le32 *blkaddr_in_node(const struct folio *folio)
> {
> - return RAW_IS_INODE(node) ? node->i.i_addr : node->dn.addr;
> + struct f2fs_node *node = F2FS_NODE(folio);
> +
> + return IS_INODE(folio) ? node->i.i_addr : node->dn.addr;
> }
>
> static inline int f2fs_has_extra_attr(struct inode *inode);
> @@ -3311,7 +3327,7 @@ static inline unsigned int get_dnode_base(struct inode *inode,
> static inline __le32 *get_dnode_addr(struct inode *inode,
> struct folio *node_folio)
> {
> - return blkaddr_in_node(F2FS_NODE(node_folio)) +
> + return blkaddr_in_node(node_folio) +
> get_dnode_base(inode, node_folio);
> }
>
> @@ -3639,7 +3655,7 @@ void *inline_xattr_addr(struct inode *inode, const struct folio *folio)
> {
> struct f2fs_inode *ri = F2FS_INODE(folio);
>
> - return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
> + return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE_SBI(F2FS_I_SB(inode)) -
> get_inline_xattr_addrs(inode)]);
> }
>
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index c15c6ba91597..f15ab07a7347 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1176,7 +1176,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
>
> if (IS_INODE(node_folio)) {
> base = offset_in_addr(F2FS_INODE(node_folio));
> - max_addrs = DEF_ADDRS_PER_INODE;
> + max_addrs = DEF_ADDRS_PER_INODE_SBI(sbi);
> } else {
> base = 0;
> max_addrs = DEF_ADDRS_PER_BLOCK;
> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> index 718dd785865a..73cd9b6ddcc5 100644
> --- a/fs/f2fs/inline.c
> +++ b/fs/f2fs/inline.c
> @@ -36,14 +36,13 @@ bool f2fs_may_inline_data(struct inode *inode)
>
> static bool inode_has_blocks(struct inode *inode, struct folio *ifolio)
> {
> - struct f2fs_inode *ri = F2FS_INODE(ifolio);
> int i;
>
> if (F2FS_HAS_BLOCKS(inode))
> return true;
>
> for (i = 0; i < DEF_NIDS_PER_INODE; i++) {
> - if (ri->i_nid[i])
> + if (F2FS_INODE_NIDS(ifolio)[i])
> return true;
> }
> return false;
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index 96cc0e777567..fda9ee3bfc61 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -150,9 +150,8 @@ bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct folio *folio)
>
> static __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct folio *folio)
> {
> - struct f2fs_node *node = F2FS_NODE(folio);
> - struct f2fs_inode *ri = &node->i;
> - __le32 ino = node->footer.ino;
> + struct f2fs_inode *ri = F2FS_INODE(folio);
> + __le32 ino = F2FS_NODE_FOOTER(folio)->ino;
> __le32 gen = ri->i_generation;
> __u32 chksum, chksum_seed;
> __u32 dummy_cs = 0;
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index 960c6657d0d6..e3f594f7bcce 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -3001,7 +3001,6 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct folio *folio)
> int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
> unsigned int segno, struct f2fs_summary_block *sum)
> {
> - struct f2fs_node *rn;
> struct f2fs_summary *sum_entry;
> block_t addr;
> int i, idx, last_offset, nrpages;
> @@ -3023,8 +3022,7 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
> if (IS_ERR(folio))
> return PTR_ERR(folio);
>
> - rn = F2FS_NODE(folio);
> - sum_entry->nid = rn->footer.nid;
> + sum_entry->nid = F2FS_NODE_FOOTER(folio)->nid;
> sum_entry->version = 0;
> sum_entry->ofs_in_node = 0;
> sum_entry++;
> diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
> index 0dce97aac5fc..6a2b7c63f4a3 100644
> --- a/fs/f2fs/node.h
> +++ b/fs/f2fs/node.h
> @@ -252,73 +252,68 @@ static inline void set_to_next_nat(struct f2fs_sb_info *sbi,
>
> static inline nid_t ino_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.ino);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->ino);
> }
>
> static inline nid_t nid_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.nid);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->nid);
> }
>
> static inline unsigned int ofs_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - unsigned flag = le32_to_cpu(rn->footer.flag);
> + unsigned int flag = le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->flag);
> return flag >> OFFSET_BIT_SHIFT;
> }
>
> static inline __u64 cpver_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le64_to_cpu(rn->footer.cp_ver);
> + return le64_to_cpu(F2FS_NODE_FOOTER(node_folio)->cp_ver);
> }
>
> static inline block_t next_blkaddr_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.next_blkaddr);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->next_blkaddr);
> }
>
> static inline void fill_node_footer(const struct folio *folio, nid_t nid,
> nid_t ino, unsigned int ofs, bool reset)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> unsigned int old_flag = 0;
>
> if (reset)
> - memset(rn, 0, sizeof(*rn));
> + memset(rn, 0, F2FS_BLKSIZE);
> else
> - old_flag = le32_to_cpu(rn->footer.flag);
> + old_flag = le32_to_cpu(footer->flag);
>
> - rn->footer.nid = cpu_to_le32(nid);
> - rn->footer.ino = cpu_to_le32(ino);
> + footer->nid = cpu_to_le32(nid);
> + footer->ino = cpu_to_le32(ino);
>
> /* should remain old flag bits such as COLD_BIT_SHIFT */
> - rn->footer.flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) |
> + footer->flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) |
> (old_flag & OFFSET_BIT_MASK));
> }
>
> static inline void copy_node_footer(const struct folio *dst,
> const struct folio *src)
> {
> - struct f2fs_node *src_rn = F2FS_NODE(src);
> - struct f2fs_node *dst_rn = F2FS_NODE(dst);
> - memcpy(&dst_rn->footer, &src_rn->footer, sizeof(struct node_footer));
> + memcpy(F2FS_NODE_FOOTER(dst), F2FS_NODE_FOOTER(src),
> + sizeof(struct node_footer));
> }
>
> static inline void fill_node_footer_blkaddr(struct folio *folio, block_t blkaddr)
> {
> struct f2fs_checkpoint *ckpt = F2FS_CKPT(F2FS_F_SB(folio));
> - struct f2fs_node *rn = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> __u64 cp_ver = cur_cp_version(ckpt);
>
> if (__is_set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG))
> cp_ver |= (cur_cp_crc(ckpt) << 32);
>
> - rn->footer.cp_ver = cpu_to_le64(cp_ver);
> - rn->footer.next_blkaddr = cpu_to_le32(blkaddr);
> + footer->cp_ver = cpu_to_le64(cp_ver);
> + footer->next_blkaddr = cpu_to_le32(blkaddr);
> }
>
> static inline bool is_recoverable_dnode(const struct folio *folio)
> @@ -378,11 +373,12 @@ static inline bool IS_DNODE(const struct folio *node_folio)
> static inline int set_nid(struct folio *folio, int off, nid_t nid, bool i)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + __le32 *inode_nids = F2FS_INODE_NIDS(folio);
>
> f2fs_folio_wait_writeback(folio, NODE, true, true);
>
> if (i)
> - rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
> + inode_nids[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
> else
> rn->in.nid[off] = cpu_to_le32(nid);
> return folio_mark_dirty(folio);
> @@ -391,9 +387,10 @@ static inline int set_nid(struct folio *folio, int off, nid_t nid, bool i)
> static inline nid_t get_nid(const struct folio *folio, int off, bool i)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + const __le32 *inode_nids = F2FS_INODE_NIDS(folio);
>
> if (i)
> - return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]);
> + return le32_to_cpu(inode_nids[off - NODE_DIR1_BLOCK]);
> return le32_to_cpu(rn->in.nid[off]);
> }
>
> @@ -406,8 +403,7 @@ static inline nid_t get_nid(const struct folio *folio, int off, bool i)
>
> static inline int is_node(const struct folio *folio, int type)
> {
> - struct f2fs_node *rn = F2FS_NODE(folio);
> - return le32_to_cpu(rn->footer.flag) & BIT(type);
> + return le32_to_cpu(F2FS_NODE_FOOTER(folio)->flag) & BIT(type);
> }
>
> #define is_cold_node(folio) is_node(folio, COLD_BIT_SHIFT)
> @@ -416,14 +412,13 @@ static inline int is_node(const struct folio *folio, int type)
>
> static inline void __set_mark(const struct folio *folio, bool mark, int type)
> {
> - struct f2fs_node *rn = F2FS_NODE(folio);
> - unsigned int flag = le32_to_cpu(rn->footer.flag);
> -
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> + unsigned int flag = le32_to_cpu(footer->flag);
> if (mark)
> flag |= BIT(type);
> else
> flag &= ~BIT(type);
> - rn->footer.flag = cpu_to_le32(flag);
> + footer->flag = cpu_to_le32(flag);
> }
>
> static inline void set_cold_node(const struct folio *folio, bool is_dir)
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 8d2224e585d3..fcaeaacaab33 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4384,6 +4384,11 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
> sbi->blocksize = BIT(sbi->log_blocksize);
> sbi->nat_entries_per_block = sbi->blocksize /
> sizeof(struct f2fs_nat_entry);
> + sbi->addrs_per_inode = (sbi->blocksize - OFFSET_OF_END_OF_I_EXT -
> + SIZE_OF_I_NID - sizeof(struct node_footer)) / sizeof(__le32);
> + sbi->addrs_per_block = (sbi->blocksize -
> + sizeof(struct node_footer)) / sizeof(__le32);
> + sbi->nids_per_block = sbi->addrs_per_block;
> sbi->sit_entries_per_block = sbi->blocksize /
> sizeof(struct f2fs_sit_entry);
> sbi->orphans_per_block = (sbi->blocksize -
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index d1059a27e1b9..3d0fe2c78e12 100644
> --- a/include/linux/f2fs_fs.h
> +++ b/include/linux/f2fs_fs.h
> @@ -16,6 +16,7 @@
> #define F2FS_MAX_LOG_SECTOR_SIZE PAGE_SHIFT /* Max is Block Size */
> #define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */
> #define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */
> +#define F2FS_MAX_BLKSIZE PAGE_SIZE
It's unused in this patch?
> #define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */
> #define F2FS_MAX_EXTENSION 64 /* # of extension entries */
> #define F2FS_EXTENSION_LEN 8 /* max size of extension */
> @@ -343,18 +344,25 @@ struct f2fs_inode {
> */
> __le32 i_extra_end[0]; /* for attribute size calculation */
> } __packed;
> - __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */
> + DECLARE_FLEX_ARRAY(__le32, i_addr); /* data block pointers */
> };
> - __le32 i_nid[DEF_NIDS_PER_INODE]; /* direct(2), indirect(2),
> - double_indirect(1) node id */
Can you please keep the comments?
/* direct(2), indirect(2), double_indirect(1) node id */
> + /*
> + * __le32 i_nid[DEF_NIDS_PER_INODE];
> + *
> + * It is stored immediately before the node footer at the end of the
> + * filesystem block. Its offset depends on the filesystem block size, so
> + * locate it dynamically with F2FS_INODE_NIDS().
> + */
> } __packed;
>
> struct direct_node {
> - __le32 addr[DEF_ADDRS_PER_BLOCK]; /* array of data block address */
> + /* The address count depends on the filesystem block size. */
> + DECLARE_FLEX_ARRAY(__le32, addr); /* array of data block address */
> } __packed;
>
> struct indirect_node {
> - __le32 nid[NIDS_PER_BLOCK]; /* array of data block address */
> + /* The node ID count depends on the filesystem block size. */
> + DECLARE_FLEX_ARRAY(__le32, nid); /* array of data block address */
> } __packed;
>
> enum {
> @@ -373,7 +381,13 @@ struct f2fs_node {
> struct direct_node dn;
> struct indirect_node in;
> };
> - struct node_footer footer;
> + /*
> + * struct node_footer footer;
> + *
> + * It is stored at the end of the filesystem block, after the inode or
> + * direct/indirect node data. Its offset depends on the filesystem block
> + * size, so locate it dynamically with F2FS_NODE_FOOTER().
> + */
> } __packed;
>
> /*
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
WARNING: multiple messages have this Message-ID (diff)
From: Chao Yu <chao@kernel.org>
To: Kelvin Zhang <zhangxp1998@gmail.com>,
linux-f2fs-devel@lists.sourceforge.net
Cc: chao@kernel.org, jaegeuk@kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v7 06/11] f2fs: describe {i,d,id}node block layout dynamically
Date: Tue, 1 Sep 2026 19:48:45 +0800 [thread overview]
Message-ID: <63f1e1ae-444f-406f-b76d-312cd0b76bdb@kernel.org> (raw)
In-Reply-To: <a21bc0d17ce657d0ccd86fd398785b946fa268d6.1788213716.git.zhangxp1998@gmail.com>
On 9/1/26 06:08, Kelvin Zhang wrote:
> An inode block ends with five i_nid entries followed by a node footer.
> Data block address pointers (i_addr[]) precede them. Similarly, direct and
> indirect node blocks contain data addresses or node IDs followed by a node
> footer at the end of the block.
>
> Describe struct f2fs_inode, struct direct_node, and
> struct indirect_node using flexible array members. Compute the locations
> of i_nid and node footers dynamically from the filesystem block size.
> Introduce F2FS_INODE_NIDS() and F2FS_NODE_FOOTER() helpers to access these
> tail fields.
>
> Compute sbi->addrs_per_inode, sbi->addrs_per_block, and
> sbi->nids_per_block in init_sb_info(), and update node management, file
> mapping, and recovery paths accordingly.
>
> Signed-off-by: Kelvin Zhang <zhangxp1998@gmail.com>
> ---
> fs/f2fs/data.c | 2 +-
> fs/f2fs/f2fs.h | 32 ++++++++++++++++++-------
> fs/f2fs/gc.c | 2 +-
> fs/f2fs/inline.c | 3 +--
> fs/f2fs/inode.c | 5 ++--
> fs/f2fs/node.c | 4 +---
> fs/f2fs/node.h | 53 +++++++++++++++++++----------------------
> fs/f2fs/super.c | 5 ++++
> include/linux/f2fs_fs.h | 26 +++++++++++++++-----
> 9 files changed, 79 insertions(+), 53 deletions(-)
>
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 6ae0eb37d20f..751b7a457d9a 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -2027,7 +2027,7 @@ static int f2fs_xattr_fiemap(struct inode *inode,
>
> phys = F2FS_BLK_TO_BYTES(ni.blk_addr);
> offset = offsetof(struct f2fs_inode, i_addr) +
> - sizeof(__le32) * (DEF_ADDRS_PER_INODE -
> + sizeof(__le32) * (DEF_ADDRS_PER_INODE_SBI(sbi) -
> get_inline_xattr_addrs(inode));
>
> phys += offset;
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index d2e54573ed34..247e56522441 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1853,6 +1853,9 @@ struct f2fs_sb_info {
> unsigned int log_blocksize; /* log2 block size */
> unsigned int blocksize; /* block size */
> unsigned int nat_entries_per_block; /* NAT entries in a block */
> + unsigned int addrs_per_inode; /* addresses in an inode block */
> + unsigned int addrs_per_block; /* addresses in a direct node block */
> + unsigned int nids_per_block; /* node IDs in an indirect node block */
> unsigned int sit_entries_per_block; /* SIT entries in a block */
> unsigned int orphans_per_block; /* orphan inodes in a block */
> unsigned int dentries_per_block; /* dentries in a block */
> @@ -2248,6 +2251,7 @@ static inline struct f2fs_sb_info *F2FS_F_SB(const struct folio *folio)
>
> #define SIT_ENTRY_PER_BLOCK(sbi) ((sbi)->sit_entries_per_block)
> #define NAT_ENTRY_PER_BLOCK(sbi) ((sbi)->nat_entries_per_block)
> +#define DEF_ADDRS_PER_INODE_SBI(sbi) ((sbi)->addrs_per_inode)
#define DEF_ADDRS_PER_INODE
> #define F2FS_ORPHANS_PER_BLOCK(sbi) ((sbi)->orphans_per_block)
> #define GET_ORPHAN_BLOCKS(sbi, n) DIV_ROUND_UP((n), \
> F2FS_ORPHANS_PER_BLOCK(sbi))
> @@ -2297,6 +2301,12 @@ static inline struct f2fs_checkpoint *F2FS_CKPT(struct f2fs_sb_info *sbi)
> return (struct f2fs_checkpoint *)(sbi->ckpt);
> }
>
> +static inline struct node_footer *F2FS_NODE_FOOTER(const struct folio *folio)
> +{
> + return folio_address(folio) + F2FS_BLKSIZE -
> + sizeof(struct node_footer);
> +}
> +
> static inline struct f2fs_node *F2FS_NODE(const struct folio *folio)
> {
> return (struct f2fs_node *)folio_address(folio);
> @@ -2307,6 +2317,12 @@ static inline struct f2fs_inode *F2FS_INODE(const struct folio *folio)
> return &((struct f2fs_node *)folio_address(folio))->i;
> }
>
> +static inline __le32 *F2FS_INODE_NIDS(const struct folio *folio)
> +{
> + return folio_address(folio) + F2FS_BLKSIZE - sizeof(struct node_footer) -
> + SIZE_OF_I_NID;
> +}
> +
> static inline struct f2fs_nm_info *NM_I(struct f2fs_sb_info *sbi)
> {
> return (struct f2fs_nm_info *)(sbi->nm_info);
> @@ -3277,13 +3293,11 @@ static inline void f2fs_radix_tree_insert(struct radix_tree_root *root,
> cond_resched();
> }
>
> -#define RAW_IS_INODE(p) ((p)->footer.nid == (p)->footer.ino)
> -
> static inline bool IS_INODE(const struct folio *folio)
> {
> - struct f2fs_node *p = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
>
> - return RAW_IS_INODE(p);
> + return footer->nid == footer->ino;
> }
>
> static inline int offset_in_addr(struct f2fs_inode *i)
> @@ -3292,9 +3306,11 @@ static inline int offset_in_addr(struct f2fs_inode *i)
> (le16_to_cpu(i->i_extra_isize) / sizeof(__le32)) : 0;
> }
>
> -static inline __le32 *blkaddr_in_node(struct f2fs_node *node)
> +static inline __le32 *blkaddr_in_node(const struct folio *folio)
> {
> - return RAW_IS_INODE(node) ? node->i.i_addr : node->dn.addr;
> + struct f2fs_node *node = F2FS_NODE(folio);
> +
> + return IS_INODE(folio) ? node->i.i_addr : node->dn.addr;
> }
>
> static inline int f2fs_has_extra_attr(struct inode *inode);
> @@ -3311,7 +3327,7 @@ static inline unsigned int get_dnode_base(struct inode *inode,
> static inline __le32 *get_dnode_addr(struct inode *inode,
> struct folio *node_folio)
> {
> - return blkaddr_in_node(F2FS_NODE(node_folio)) +
> + return blkaddr_in_node(node_folio) +
> get_dnode_base(inode, node_folio);
> }
>
> @@ -3639,7 +3655,7 @@ void *inline_xattr_addr(struct inode *inode, const struct folio *folio)
> {
> struct f2fs_inode *ri = F2FS_INODE(folio);
>
> - return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE -
> + return (void *)&(ri->i_addr[DEF_ADDRS_PER_INODE_SBI(F2FS_I_SB(inode)) -
> get_inline_xattr_addrs(inode)]);
> }
>
> diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
> index c15c6ba91597..f15ab07a7347 100644
> --- a/fs/f2fs/gc.c
> +++ b/fs/f2fs/gc.c
> @@ -1176,7 +1176,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum,
>
> if (IS_INODE(node_folio)) {
> base = offset_in_addr(F2FS_INODE(node_folio));
> - max_addrs = DEF_ADDRS_PER_INODE;
> + max_addrs = DEF_ADDRS_PER_INODE_SBI(sbi);
> } else {
> base = 0;
> max_addrs = DEF_ADDRS_PER_BLOCK;
> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> index 718dd785865a..73cd9b6ddcc5 100644
> --- a/fs/f2fs/inline.c
> +++ b/fs/f2fs/inline.c
> @@ -36,14 +36,13 @@ bool f2fs_may_inline_data(struct inode *inode)
>
> static bool inode_has_blocks(struct inode *inode, struct folio *ifolio)
> {
> - struct f2fs_inode *ri = F2FS_INODE(ifolio);
> int i;
>
> if (F2FS_HAS_BLOCKS(inode))
> return true;
>
> for (i = 0; i < DEF_NIDS_PER_INODE; i++) {
> - if (ri->i_nid[i])
> + if (F2FS_INODE_NIDS(ifolio)[i])
> return true;
> }
> return false;
> diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c
> index 96cc0e777567..fda9ee3bfc61 100644
> --- a/fs/f2fs/inode.c
> +++ b/fs/f2fs/inode.c
> @@ -150,9 +150,8 @@ bool f2fs_enable_inode_chksum(struct f2fs_sb_info *sbi, struct folio *folio)
>
> static __u32 f2fs_inode_chksum(struct f2fs_sb_info *sbi, struct folio *folio)
> {
> - struct f2fs_node *node = F2FS_NODE(folio);
> - struct f2fs_inode *ri = &node->i;
> - __le32 ino = node->footer.ino;
> + struct f2fs_inode *ri = F2FS_INODE(folio);
> + __le32 ino = F2FS_NODE_FOOTER(folio)->ino;
> __le32 gen = ri->i_generation;
> __u32 chksum, chksum_seed;
> __u32 dummy_cs = 0;
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index 960c6657d0d6..e3f594f7bcce 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -3001,7 +3001,6 @@ int f2fs_recover_inode_page(struct f2fs_sb_info *sbi, struct folio *folio)
> int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
> unsigned int segno, struct f2fs_summary_block *sum)
> {
> - struct f2fs_node *rn;
> struct f2fs_summary *sum_entry;
> block_t addr;
> int i, idx, last_offset, nrpages;
> @@ -3023,8 +3022,7 @@ int f2fs_restore_node_summary(struct f2fs_sb_info *sbi,
> if (IS_ERR(folio))
> return PTR_ERR(folio);
>
> - rn = F2FS_NODE(folio);
> - sum_entry->nid = rn->footer.nid;
> + sum_entry->nid = F2FS_NODE_FOOTER(folio)->nid;
> sum_entry->version = 0;
> sum_entry->ofs_in_node = 0;
> sum_entry++;
> diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
> index 0dce97aac5fc..6a2b7c63f4a3 100644
> --- a/fs/f2fs/node.h
> +++ b/fs/f2fs/node.h
> @@ -252,73 +252,68 @@ static inline void set_to_next_nat(struct f2fs_sb_info *sbi,
>
> static inline nid_t ino_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.ino);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->ino);
> }
>
> static inline nid_t nid_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.nid);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->nid);
> }
>
> static inline unsigned int ofs_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - unsigned flag = le32_to_cpu(rn->footer.flag);
> + unsigned int flag = le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->flag);
> return flag >> OFFSET_BIT_SHIFT;
> }
>
> static inline __u64 cpver_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le64_to_cpu(rn->footer.cp_ver);
> + return le64_to_cpu(F2FS_NODE_FOOTER(node_folio)->cp_ver);
> }
>
> static inline block_t next_blkaddr_of_node(const struct folio *node_folio)
> {
> - struct f2fs_node *rn = F2FS_NODE(node_folio);
> - return le32_to_cpu(rn->footer.next_blkaddr);
> + return le32_to_cpu(F2FS_NODE_FOOTER(node_folio)->next_blkaddr);
> }
>
> static inline void fill_node_footer(const struct folio *folio, nid_t nid,
> nid_t ino, unsigned int ofs, bool reset)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> unsigned int old_flag = 0;
>
> if (reset)
> - memset(rn, 0, sizeof(*rn));
> + memset(rn, 0, F2FS_BLKSIZE);
> else
> - old_flag = le32_to_cpu(rn->footer.flag);
> + old_flag = le32_to_cpu(footer->flag);
>
> - rn->footer.nid = cpu_to_le32(nid);
> - rn->footer.ino = cpu_to_le32(ino);
> + footer->nid = cpu_to_le32(nid);
> + footer->ino = cpu_to_le32(ino);
>
> /* should remain old flag bits such as COLD_BIT_SHIFT */
> - rn->footer.flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) |
> + footer->flag = cpu_to_le32((ofs << OFFSET_BIT_SHIFT) |
> (old_flag & OFFSET_BIT_MASK));
> }
>
> static inline void copy_node_footer(const struct folio *dst,
> const struct folio *src)
> {
> - struct f2fs_node *src_rn = F2FS_NODE(src);
> - struct f2fs_node *dst_rn = F2FS_NODE(dst);
> - memcpy(&dst_rn->footer, &src_rn->footer, sizeof(struct node_footer));
> + memcpy(F2FS_NODE_FOOTER(dst), F2FS_NODE_FOOTER(src),
> + sizeof(struct node_footer));
> }
>
> static inline void fill_node_footer_blkaddr(struct folio *folio, block_t blkaddr)
> {
> struct f2fs_checkpoint *ckpt = F2FS_CKPT(F2FS_F_SB(folio));
> - struct f2fs_node *rn = F2FS_NODE(folio);
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> __u64 cp_ver = cur_cp_version(ckpt);
>
> if (__is_set_ckpt_flags(ckpt, CP_CRC_RECOVERY_FLAG))
> cp_ver |= (cur_cp_crc(ckpt) << 32);
>
> - rn->footer.cp_ver = cpu_to_le64(cp_ver);
> - rn->footer.next_blkaddr = cpu_to_le32(blkaddr);
> + footer->cp_ver = cpu_to_le64(cp_ver);
> + footer->next_blkaddr = cpu_to_le32(blkaddr);
> }
>
> static inline bool is_recoverable_dnode(const struct folio *folio)
> @@ -378,11 +373,12 @@ static inline bool IS_DNODE(const struct folio *node_folio)
> static inline int set_nid(struct folio *folio, int off, nid_t nid, bool i)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + __le32 *inode_nids = F2FS_INODE_NIDS(folio);
>
> f2fs_folio_wait_writeback(folio, NODE, true, true);
>
> if (i)
> - rn->i.i_nid[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
> + inode_nids[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid);
> else
> rn->in.nid[off] = cpu_to_le32(nid);
> return folio_mark_dirty(folio);
> @@ -391,9 +387,10 @@ static inline int set_nid(struct folio *folio, int off, nid_t nid, bool i)
> static inline nid_t get_nid(const struct folio *folio, int off, bool i)
> {
> struct f2fs_node *rn = F2FS_NODE(folio);
> + const __le32 *inode_nids = F2FS_INODE_NIDS(folio);
>
> if (i)
> - return le32_to_cpu(rn->i.i_nid[off - NODE_DIR1_BLOCK]);
> + return le32_to_cpu(inode_nids[off - NODE_DIR1_BLOCK]);
> return le32_to_cpu(rn->in.nid[off]);
> }
>
> @@ -406,8 +403,7 @@ static inline nid_t get_nid(const struct folio *folio, int off, bool i)
>
> static inline int is_node(const struct folio *folio, int type)
> {
> - struct f2fs_node *rn = F2FS_NODE(folio);
> - return le32_to_cpu(rn->footer.flag) & BIT(type);
> + return le32_to_cpu(F2FS_NODE_FOOTER(folio)->flag) & BIT(type);
> }
>
> #define is_cold_node(folio) is_node(folio, COLD_BIT_SHIFT)
> @@ -416,14 +412,13 @@ static inline int is_node(const struct folio *folio, int type)
>
> static inline void __set_mark(const struct folio *folio, bool mark, int type)
> {
> - struct f2fs_node *rn = F2FS_NODE(folio);
> - unsigned int flag = le32_to_cpu(rn->footer.flag);
> -
> + struct node_footer *footer = F2FS_NODE_FOOTER(folio);
> + unsigned int flag = le32_to_cpu(footer->flag);
> if (mark)
> flag |= BIT(type);
> else
> flag &= ~BIT(type);
> - rn->footer.flag = cpu_to_le32(flag);
> + footer->flag = cpu_to_le32(flag);
> }
>
> static inline void set_cold_node(const struct folio *folio, bool is_dir)
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index 8d2224e585d3..fcaeaacaab33 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -4384,6 +4384,11 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
> sbi->blocksize = BIT(sbi->log_blocksize);
> sbi->nat_entries_per_block = sbi->blocksize /
> sizeof(struct f2fs_nat_entry);
> + sbi->addrs_per_inode = (sbi->blocksize - OFFSET_OF_END_OF_I_EXT -
> + SIZE_OF_I_NID - sizeof(struct node_footer)) / sizeof(__le32);
> + sbi->addrs_per_block = (sbi->blocksize -
> + sizeof(struct node_footer)) / sizeof(__le32);
> + sbi->nids_per_block = sbi->addrs_per_block;
> sbi->sit_entries_per_block = sbi->blocksize /
> sizeof(struct f2fs_sit_entry);
> sbi->orphans_per_block = (sbi->blocksize -
> diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
> index d1059a27e1b9..3d0fe2c78e12 100644
> --- a/include/linux/f2fs_fs.h
> +++ b/include/linux/f2fs_fs.h
> @@ -16,6 +16,7 @@
> #define F2FS_MAX_LOG_SECTOR_SIZE PAGE_SHIFT /* Max is Block Size */
> #define F2FS_LOG_SECTORS_PER_BLOCK (PAGE_SHIFT - 9) /* log number for sector/blk */
> #define F2FS_BLKSIZE PAGE_SIZE /* support only block == page */
> +#define F2FS_MAX_BLKSIZE PAGE_SIZE
It's unused in this patch?
> #define F2FS_BLKSIZE_BITS PAGE_SHIFT /* bits for F2FS_BLKSIZE */
> #define F2FS_MAX_EXTENSION 64 /* # of extension entries */
> #define F2FS_EXTENSION_LEN 8 /* max size of extension */
> @@ -343,18 +344,25 @@ struct f2fs_inode {
> */
> __le32 i_extra_end[0]; /* for attribute size calculation */
> } __packed;
> - __le32 i_addr[DEF_ADDRS_PER_INODE]; /* Pointers to data blocks */
> + DECLARE_FLEX_ARRAY(__le32, i_addr); /* data block pointers */
> };
> - __le32 i_nid[DEF_NIDS_PER_INODE]; /* direct(2), indirect(2),
> - double_indirect(1) node id */
Can you please keep the comments?
/* direct(2), indirect(2), double_indirect(1) node id */
> + /*
> + * __le32 i_nid[DEF_NIDS_PER_INODE];
> + *
> + * It is stored immediately before the node footer at the end of the
> + * filesystem block. Its offset depends on the filesystem block size, so
> + * locate it dynamically with F2FS_INODE_NIDS().
> + */
> } __packed;
>
> struct direct_node {
> - __le32 addr[DEF_ADDRS_PER_BLOCK]; /* array of data block address */
> + /* The address count depends on the filesystem block size. */
> + DECLARE_FLEX_ARRAY(__le32, addr); /* array of data block address */
> } __packed;
>
> struct indirect_node {
> - __le32 nid[NIDS_PER_BLOCK]; /* array of data block address */
> + /* The node ID count depends on the filesystem block size. */
> + DECLARE_FLEX_ARRAY(__le32, nid); /* array of data block address */
> } __packed;
>
> enum {
> @@ -373,7 +381,13 @@ struct f2fs_node {
> struct direct_node dn;
> struct indirect_node in;
> };
> - struct node_footer footer;
> + /*
> + * struct node_footer footer;
> + *
> + * It is stored at the end of the filesystem block, after the inode or
> + * direct/indirect node data. Its offset depends on the filesystem block
> + * size, so locate it dynamically with F2FS_NODE_FOOTER().
> + */
> } __packed;
>
> /*
next prev parent reply other threads:[~2026-09-01 11:49 UTC|newest]
Thread overview: 58+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 22:05 [PATCH v7 00/11] f2fs: prepare metadata layouts for runtime block sizes Kelvin Zhang
2026-08-31 22:05 ` [f2fs-dev] " Kelvin Zhang
2026-08-31 22:05 ` [PATCH v7 01/11] f2fs: initialize sb_info early in f2fs_fill_super Kelvin Zhang
2026-08-31 22:05 ` [f2fs-dev] " Kelvin Zhang
2026-09-01 0:48 ` Chao Yu
2026-09-01 0:48 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` [f2fs-dev] " Xinping Zhang
2026-08-31 22:08 ` [PATCH v7 02/11] f2fs: describe SIT block layout dynamically Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] " Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 03/11] f2fs: describe NAT " Kelvin Zhang
2026-08-31 22:08 ` Kelvin Zhang
2026-09-01 0:38 ` [f2fs-dev] " Daeho Jeong
2026-09-01 0:38 ` Daeho Jeong
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-08-31 22:08 ` [PATCH v7 04/11] f2fs: describe orphan " Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] " Kelvin Zhang
2026-09-01 11:34 ` Chao Yu
2026-09-01 11:34 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 05/11] f2fs: describe dentry " Kelvin Zhang
2026-08-31 22:08 ` Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 06/11] f2fs: describe {i, d, id}node " Kelvin Zhang
2026-08-31 22:08 ` [PATCH v7 06/11] f2fs: describe {i,d,id}node " Kelvin Zhang
2026-09-01 0:56 ` [f2fs-dev] [PATCH v7 06/11] f2fs: describe {i, d, id}node " Daeho Jeong
2026-09-01 0:56 ` Daeho Jeong
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 11:48 ` Chao Yu via Linux-f2fs-devel [this message]
2026-09-01 11:48 ` [PATCH v7 06/11] f2fs: describe {i,d,id}node " Chao Yu
2026-09-01 16:38 ` [f2fs-dev] [PATCH v7 06/11] f2fs: describe {i, d, id}node " Xinping Zhang
2026-09-01 16:38 ` [PATCH v7 06/11] f2fs: describe {i,d,id}node " Xinping Zhang
2026-09-02 23:52 ` [f2fs-dev] [PATCH v7 06/11] f2fs: describe {i, d, id}node " Xinping Zhang
2026-09-03 1:55 ` Chao Yu via Linux-f2fs-devel
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 07/11] f2fs: describe xattr " Kelvin Zhang
2026-08-31 22:08 ` Kelvin Zhang
2026-09-01 1:10 ` [f2fs-dev] " Daeho Jeong
2026-09-01 1:10 ` Daeho Jeong
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 08/11] f2fs: parameterize sector conversion macros Kelvin Zhang
2026-08-31 22:08 ` Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] [PATCH v7 09/11] f2fs: parameterize byte and block " Kelvin Zhang
2026-08-31 22:08 ` Kelvin Zhang
2026-09-01 1:14 ` [f2fs-dev] " Daeho Jeong
2026-09-01 1:14 ` Daeho Jeong
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-08-31 22:08 ` [PATCH v7 10/11] f2fs: parameterize block size and mask macros Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] " Kelvin Zhang
2026-09-01 12:03 ` Chao Yu
2026-09-01 12:03 ` [f2fs-dev] " Chao Yu via Linux-f2fs-devel
2026-09-01 16:38 ` Xinping Zhang
2026-09-01 16:38 ` Xinping Zhang
2026-08-31 22:08 ` [PATCH v7 11/11] f2fs: describe node tree geometry dynamically Kelvin Zhang
2026-08-31 22:08 ` [f2fs-dev] " Kelvin Zhang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=63f1e1ae-444f-406f-b76d-312cd0b76bdb@kernel.org \
--to=linux-f2fs-devel@lists.sourceforge.net \
--cc=chao@kernel.org \
--cc=jaegeuk@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=zhangxp1998@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.