mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
f2fs: describe {i,d,id}node block layout dynamically
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> Reviewed-by: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
b387d0b8ff
commit
87f9a4888f
|
|
@ -1992,7 +1992,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) -
|
||||
get_inline_xattr_addrs(inode));
|
||||
|
||||
phys += offset;
|
||||
|
|
|
|||
|
|
@ -603,8 +603,9 @@ static inline int update_sits_in_cursum(struct f2fs_journal *journal, int i)
|
|||
#define DEF_INLINE_RESERVED_SIZE 1
|
||||
static inline int get_extra_isize(struct inode *inode);
|
||||
static inline int get_inline_xattr_addrs(struct inode *inode);
|
||||
static inline unsigned int cur_addrs_per_inode(struct inode *inode);
|
||||
#define MAX_INLINE_DATA(inode) (sizeof(__le32) * \
|
||||
(CUR_ADDRS_PER_INODE(inode) - \
|
||||
(cur_addrs_per_inode(inode) - \
|
||||
get_inline_xattr_addrs(inode) - \
|
||||
DEF_INLINE_RESERVED_SIZE))
|
||||
|
||||
|
|
@ -1853,6 +1854,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 +2252,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)->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 +2302,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 +2318,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 +3294,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 +3307,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 +3328,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);
|
||||
}
|
||||
|
||||
|
|
@ -3626,7 +3643,7 @@ static inline bool f2fs_need_compress_data(struct inode *inode)
|
|||
static inline unsigned int addrs_per_page(struct inode *inode,
|
||||
bool is_inode)
|
||||
{
|
||||
unsigned int addrs = is_inode ? (CUR_ADDRS_PER_INODE(inode) -
|
||||
unsigned int addrs = is_inode ? (cur_addrs_per_inode(inode) -
|
||||
get_inline_xattr_addrs(inode)) : DEF_ADDRS_PER_BLOCK;
|
||||
|
||||
if (f2fs_compressed_file(inode))
|
||||
|
|
@ -3634,12 +3651,17 @@ static inline unsigned int addrs_per_page(struct inode *inode,
|
|||
return addrs;
|
||||
}
|
||||
|
||||
static inline unsigned int cur_addrs_per_inode(struct inode *inode)
|
||||
{
|
||||
return DEF_ADDRS_PER_INODE(F2FS_I_SB(inode)) - get_extra_isize(inode);
|
||||
}
|
||||
|
||||
static inline
|
||||
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(F2FS_I_SB(inode)) -
|
||||
get_inline_xattr_addrs(inode)]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
} else {
|
||||
base = 0;
|
||||
max_addrs = DEF_ADDRS_PER_BLOCK;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -250,73 +250,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)
|
||||
|
|
@ -376,11 +371,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);
|
||||
|
|
@ -389,9 +385,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]);
|
||||
}
|
||||
|
||||
|
|
@ -404,8 +401,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)
|
||||
|
|
@ -414,14 +410,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)
|
||||
|
|
|
|||
|
|
@ -4384,6 +4384,10 @@ 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 = F2FS_DEF_ADDRS_PER_INODE(sbi->blocksize);
|
||||
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 -
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ struct f2fs_xattr_entry {
|
|||
|
||||
#define MIN_INLINE_XATTR_SIZE (sizeof(struct f2fs_xattr_header) / sizeof(__le32))
|
||||
#define MAX_INLINE_XATTR_SIZE \
|
||||
(DEF_ADDRS_PER_INODE - \
|
||||
(F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) - \
|
||||
F2FS_TOTAL_EXTRA_ATTR_SIZE / sizeof(__le32) - \
|
||||
DEF_INLINE_RESERVED_SIZE - \
|
||||
MIN_INLINE_DENTRY_SIZE / sizeof(__le32))
|
||||
|
|
|
|||
|
|
@ -268,11 +268,9 @@ struct node_footer {
|
|||
} __packed;
|
||||
|
||||
/* Address Pointers in an Inode */
|
||||
#define DEF_ADDRS_PER_INODE ((F2FS_BLKSIZE - OFFSET_OF_END_OF_I_EXT \
|
||||
- SIZE_OF_I_NID \
|
||||
- sizeof(struct node_footer)) / sizeof(__le32))
|
||||
#define CUR_ADDRS_PER_INODE(inode) (DEF_ADDRS_PER_INODE - \
|
||||
get_extra_isize(inode))
|
||||
#define F2FS_DEF_ADDRS_PER_INODE(blocksize) \
|
||||
(((blocksize) - OFFSET_OF_END_OF_I_EXT - SIZE_OF_I_NID - \
|
||||
sizeof(struct node_footer)) / sizeof(__le32))
|
||||
#define DEF_NIDS_PER_INODE 5 /* Node IDs in an Inode */
|
||||
#define ADDRS_PER_INODE(inode) addrs_per_page(inode, true)
|
||||
/* Address Pointers in a Direct Block */
|
||||
|
|
@ -283,11 +281,11 @@ struct node_footer {
|
|||
|
||||
#define ADDRS_PER_PAGE(folio, inode) (addrs_per_page(inode, IS_INODE(folio)))
|
||||
|
||||
#define NODE_DIR1_BLOCK (DEF_ADDRS_PER_INODE + 1)
|
||||
#define NODE_DIR2_BLOCK (DEF_ADDRS_PER_INODE + 2)
|
||||
#define NODE_IND1_BLOCK (DEF_ADDRS_PER_INODE + 3)
|
||||
#define NODE_IND2_BLOCK (DEF_ADDRS_PER_INODE + 4)
|
||||
#define NODE_DIND_BLOCK (DEF_ADDRS_PER_INODE + 5)
|
||||
#define NODE_DIR1_BLOCK (F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) + 1)
|
||||
#define NODE_DIR2_BLOCK (F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) + 2)
|
||||
#define NODE_IND1_BLOCK (F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) + 3)
|
||||
#define NODE_IND2_BLOCK (F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) + 4)
|
||||
#define NODE_DIND_BLOCK (F2FS_DEF_ADDRS_PER_INODE(F2FS_BLKSIZE) + 5)
|
||||
|
||||
#define F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */
|
||||
#define F2FS_INLINE_DATA 0x02 /* file inline data flag */
|
||||
|
|
@ -347,18 +345,26 @@ 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 */
|
||||
/*
|
||||
* __le32 i_nid[DEF_NIDS_PER_INODE];
|
||||
* direct(2), indirect(2), double_indirect(1) node IDs
|
||||
*
|
||||
* 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 {
|
||||
|
|
@ -377,7 +383,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;
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user