From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f44.google.com (mail-pj1-f44.google.com [209.85.216.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A431F3C2798 for ; Mon, 31 Aug 2026 22:08:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.44 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788214109; cv=none; b=jVA7v2h0RAOhUQoknJvJxJVe43ZHuh4faAOWPn7EEVfgC3ySgUz4e+r4kQ9e3FkyhVgZgUdJDuOp7xXPAK5srZoXSqOAxWsDhVIVagN9I5KR6MO2MClNGGAwrBhPCnhaz075PQjLJM8ik0tCrDrE4VG2+6hNirwJqHDcla5xJsQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788214109; c=relaxed/simple; bh=MOoD3EidD6YR3ERZ42TYxe/W6fWahswwQZ6tImAc2BM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NcVLPDw+lWDlw7ucEz9lKbVukn4yj3/fEvDPjCPwOQ4Co67+MZ7OApZtL2R2Yqf6Fez8Ng1J5uOcLe7I4GDxNiqDviWqbjKrCek7HYKt2yCB2F72Oy6OGEgLVGsOg+IK/dvkM029EGxPjiwion2O8c+9mSsdt/MlD8BeNJTtBD8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=RaD5KbFL; arc=none smtp.client-ip=209.85.216.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="RaD5KbFL" Received: by mail-pj1-f44.google.com with SMTP id 98e67ed59e1d1-38d489b6b71so4614387a91.0 for ; Mon, 31 Aug 2026 15:08:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788214106; x=1788818906; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=pzD6Qgco6utzkju+m2uoC36z1vRssf5I1H5k3p9Aq34=; b=RaD5KbFLncykwDYb88/ixl24qmEAEKo8TO/EdfjYQBInvVqaArSvmrEeHX60c6rFZb uSeObQa+d99x2r6MckiEwkjGgkUeg8uosZ6+fChhCKfuDgBQxr+s84tdAx2pOsQfrYBk oyghbvprUUfNsC+Ql8OnmN36SfgCXYdhKEUzTzK+EeIqKNb/SUCJoi8EWYiJEhe6jwmu gTbGyoNe/yIs6d7Fmwa7c1294Xlt+d/mRdA5UyeSrH2o55zPLqz79mZS304PNDGf7SXn 7f3HYOCXkbOCQfj7Y0OE3QmNVxK0A979vZHqHtcxsawu5VjPJTeNptJuT85o3vqEMssH u3Yg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788214106; x=1788818906; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=pzD6Qgco6utzkju+m2uoC36z1vRssf5I1H5k3p9Aq34=; b=aAtcy0+gdyWmRYUQpwFMINwMRepz12Sdw8a3hLhEr8wsSDZK330PKxQF48KQuCn1BC 6CMxFlic7NH5fWwlC0XdOQhdf6KnywMp45sVjGYgiAMBySn5JdOHIeExQjWCdERlwWI6 7XH0gkKEatUjzl1ipjTMkse7geyhtkgCiimHb443kILllwXWkfjfV7ZCu+7RPIgC+7/h PVQvp6JT7mWL711H3MUm9d1G4jkyaL1IYt45HPyHHkcitNVt3NDxcyzyWIasXA7aqzD9 WNAz0/RhnElO14iGnzQ/8vQAeRD6T0BEjBKUwwOPIeYWh2Y0PTql1ATnVwGJxBDVurbC BC2Q== X-Forwarded-Encrypted: i=1; AKwUvBwwuYtKPSGP+/G4GPX3esd8NnK9yGc1wG1nvYluRDAFK8K7l/adPzMOhRyDumRjhj4HBJnSVmZ9kUPGs2U=@vger.kernel.org X-Gm-Message-State: AFuF++nOw4RL8MYZaLej8jTR87aE2hCA+KqDqxnC3tYsVVLrGDLRaggr uPl4NTWzPb4FRJzVSZTb95afP2RzrY9cV0w4pmMIkGKkp+CPbAKDUwH+ X-Gm-Gg: AYBFou2ckmIrinC4WqEe5jbrikneYOuxIRPSPoHqQ4j4y7IPV3OIWheSu8yDYOG/mmL Mwjnszmncjb68pIsTBQsvxM7AJQAbkm7cZH8nfJ2UGecnt3+pbqVSv9mm5m8h56k/p9tnW9X9+B 01JpyKspd+J4vJQmNak5Pykc+31eejFMmjrX33F5O9lwpFMEvd139ernRsB+I9xNi7hdL0z+3L4 tXuVrctI3nCyBMvgXf9UPyEjn4eT8r66wXnQIJsXyBAsJ/uPu/yTzrWumk5jays0vxme8E8ZUQr jdV7x00fDF6NGxWatL+Q3CrGJ4+QvNUtKKHcX2y0iAZcFVntbAd9hSRuyeILXHdqXce3aC06hRS ivTjDd8DWdpaUP0X0tSPaSFu1Ip3X7woV2ogZ4Zt2fRMU/gVUVHVyw5x6XW+nAuyhj1Xlp8fSfq WPW344S1RVmuSXPc5ouRM51P89/iE6cg9rQk+pzbSaytrxvdYY3oRJJhHzpKYLS920YA== X-Received: by 2002:a17:90b:384f:b0:396:40e6:f631 with SMTP id 98e67ed59e1d1-39907b6759bmr4619796a91.3.1788214105846; Mon, 31 Aug 2026 15:08:25 -0700 (PDT) Received: from [127.0.1.1] ([2601:647:4184:b3f0:91a4:c2d8:1d54:21ad]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3990d75b540sm1704841a91.10.2026.08.31.15.08.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Aug 2026 15:08:25 -0700 (PDT) From: Kelvin Zhang To: linux-f2fs-devel@lists.sourceforge.net Cc: jaegeuk@kernel.org, chao@kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v7 11/11] f2fs: describe node tree geometry dynamically Date: Mon, 31 Aug 2026 15:08:12 -0700 Message-ID: <48104cd0c1fb5198a8f48e473ce13c4b89d0b5de.1788213716.git.zhangxp1998@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit The file indexing tree boundaries separating direct, indirect, and double-indirect node blocks depend on the number of data block addresses and node IDs contained in each node block. Parameterize index boundary macros (NODE_DIR1_BLOCK, NODE_DIR2_BLOCK, NODE_IND1_BLOCK, NODE_IND2_BLOCK, and NODE_DIND_BLOCK) and address capacity helpers (DEF_ADDRS_PER_BLOCK, NIDS_PER_BLOCK, cur_addrs_per_inode, addrs_per_page, and addrs_per_folio) with struct f2fs_sb_info *sbi. Update file mapping, block allocation, truncate, garbage collection, and recovery paths to compute indexing tree offsets from the runtime geometry. Signed-off-by: Kelvin Zhang --- fs/f2fs/f2fs.h | 19 +++++++++-- fs/f2fs/gc.c | 10 +++--- fs/f2fs/node.c | 74 +++++++++++++++++++++-------------------- fs/f2fs/node.h | 18 ++++++---- fs/f2fs/super.c | 6 ++-- include/linux/f2fs_fs.h | 18 ++-------- 6 files changed, 77 insertions(+), 68 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index f83cdab66f54..e1f33ac24c6e 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -602,8 +602,12 @@ 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) +{ + return DEF_ADDRS_PER_INODE(inode) - get_extra_isize(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)) @@ -2257,11 +2261,19 @@ static inline struct f2fs_sb_info *F2FS_P_SB(struct page *page) #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_BLOCK(sbi) ((sbi)->addrs_per_block) +#define NIDS_PER_BLOCK(sbi) ((sbi)->nids_per_block) #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)) #define CP_CHKSUM_OFFSET(sbi) (F2FS_BLKSIZE(sbi) - sizeof(__le32)) +#define NODE_DIR1_BLOCK(sbi) (DEF_ADDRS_PER_INODE_SBI(sbi) + 1) +#define NODE_DIR2_BLOCK(sbi) (DEF_ADDRS_PER_INODE_SBI(sbi) + 2) +#define NODE_IND1_BLOCK(sbi) (DEF_ADDRS_PER_INODE_SBI(sbi) + 3) +#define NODE_IND2_BLOCK(sbi) (DEF_ADDRS_PER_INODE_SBI(sbi) + 4) +#define NODE_DIND_BLOCK(sbi) (DEF_ADDRS_PER_INODE_SBI(sbi) + 5) + static inline struct f2fs_orphan_footer * f2fs_orphan_footer(void *orphan_block, struct f2fs_sb_info *sbi) { @@ -3650,8 +3662,9 @@ 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) - - get_inline_xattr_addrs(inode)) : DEF_ADDRS_PER_BLOCK; + unsigned int addrs = is_inode ? (cur_addrs_per_inode(inode) - + get_inline_xattr_addrs(inode)) : + DEF_ADDRS_PER_BLOCK(F2FS_I_SB(inode)); if (f2fs_compressed_file(inode)) return ALIGN_DOWN(addrs, F2FS_I(inode)->i_cluster_size); diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c index 299d5310e597..b17e7ce58f2c 100644 --- a/fs/f2fs/gc.c +++ b/fs/f2fs/gc.c @@ -1123,7 +1123,8 @@ static int gc_node_segment(struct f2fs_sb_info *sbi, */ block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode) { - unsigned int indirect_blks = 2 * NIDS_PER_BLOCK + 4; + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); + unsigned int indirect_blks = 2 * NIDS_PER_BLOCK(sbi) + 4; unsigned int bidx; if (node_ofs == 0) @@ -1132,11 +1133,12 @@ block_t f2fs_start_bidx_of_node(unsigned int node_ofs, struct inode *inode) if (node_ofs <= 2) { bidx = node_ofs - 1; } else if (node_ofs <= indirect_blks) { - int dec = (node_ofs - 4) / (NIDS_PER_BLOCK + 1); + int dec = (node_ofs - 4) / (NIDS_PER_BLOCK(sbi) + 1); bidx = node_ofs - 2 - dec; } else { - int dec = (node_ofs - indirect_blks - 3) / (NIDS_PER_BLOCK + 1); + int dec = (node_ofs - indirect_blks - 3) / + (NIDS_PER_BLOCK(sbi) + 1); bidx = node_ofs - 5 - dec; } @@ -1179,7 +1181,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, max_addrs = DEF_ADDRS_PER_INODE_SBI(sbi); } else { base = 0; - max_addrs = DEF_ADDRS_PER_BLOCK; + max_addrs = DEF_ADDRS_PER_BLOCK(sbi); } if (base + ofs_in_node >= max_addrs) { diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c index 8d16715a3aae..68a95d703c4a 100644 --- a/fs/f2fs/node.c +++ b/fs/f2fs/node.c @@ -691,7 +691,7 @@ static void f2fs_ra_node_pages(struct folio *parent, int start, int n) /* Then, try readahead for siblings of the desired node */ end = start + n; - end = min(end, (int)NIDS_PER_BLOCK); + end = min_t(int, end, NIDS_PER_BLOCK(sbi)); for (i = start; i < end; i++) { nid = get_nid(parent, i, false); f2fs_ra_node_page(sbi, nid); @@ -702,9 +702,11 @@ static void f2fs_ra_node_pages(struct folio *parent, int start, int n) pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) { + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); const long direct_index = ADDRS_PER_INODE(dn->inode); const long direct_blks = ADDRS_PER_BLOCK(dn->inode); - const long indirect_blks = ADDRS_PER_BLOCK(dn->inode) * NIDS_PER_BLOCK; + const long indirect_blks = ADDRS_PER_BLOCK(dn->inode) * + NIDS_PER_BLOCK(sbi); unsigned int skipped_unit = ADDRS_PER_BLOCK(dn->inode); int cur_level = dn->cur_level; int max_level = dn->max_level; @@ -714,7 +716,7 @@ pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) return pgofs + 1; while (max_level-- > cur_level) - skipped_unit *= NIDS_PER_BLOCK; + skipped_unit *= NIDS_PER_BLOCK(sbi); switch (dn->max_level) { case 3: @@ -740,11 +742,13 @@ pgoff_t f2fs_get_next_page_offset(struct dnode_of_data *dn, pgoff_t pgofs) static int get_node_path(struct inode *inode, long block, int offset[4], unsigned int noffset[4]) { + struct f2fs_sb_info *sbi = F2FS_I_SB(inode); const long direct_index = ADDRS_PER_INODE(inode); const long direct_blks = ADDRS_PER_BLOCK(inode); - const long dptrs_per_blk = NIDS_PER_BLOCK; - const long indirect_blks = ADDRS_PER_BLOCK(inode) * NIDS_PER_BLOCK; - const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK; + const long dptrs_per_blk = NIDS_PER_BLOCK(sbi); + const long indirect_blks = ADDRS_PER_BLOCK(inode) * + NIDS_PER_BLOCK(sbi); + const long dindirect_blks = indirect_blks * NIDS_PER_BLOCK(sbi); int n = 0; int level = 0; @@ -756,7 +760,7 @@ static int get_node_path(struct inode *inode, long block, } block -= direct_index; if (block < direct_blks) { - offset[n++] = NODE_DIR1_BLOCK; + offset[n++] = NODE_DIR1_BLOCK(sbi); noffset[n] = 1; offset[n] = block; level = 1; @@ -764,7 +768,7 @@ static int get_node_path(struct inode *inode, long block, } block -= direct_blks; if (block < direct_blks) { - offset[n++] = NODE_DIR2_BLOCK; + offset[n++] = NODE_DIR2_BLOCK(sbi); noffset[n] = 2; offset[n] = block; level = 1; @@ -772,7 +776,7 @@ static int get_node_path(struct inode *inode, long block, } block -= direct_blks; if (block < indirect_blks) { - offset[n++] = NODE_IND1_BLOCK; + offset[n++] = NODE_IND1_BLOCK(sbi); noffset[n] = 3; offset[n++] = block / direct_blks; noffset[n] = 4 + offset[n - 1]; @@ -782,7 +786,7 @@ static int get_node_path(struct inode *inode, long block, } block -= indirect_blks; if (block < indirect_blks) { - offset[n++] = NODE_IND2_BLOCK; + offset[n++] = NODE_IND2_BLOCK(sbi); noffset[n] = 4 + dptrs_per_blk; offset[n++] = block / direct_blks; noffset[n] = 5 + dptrs_per_blk + offset[n - 1]; @@ -792,7 +796,7 @@ static int get_node_path(struct inode *inode, long block, } block -= indirect_blks; if (block < dindirect_blks) { - offset[n++] = NODE_DIND_BLOCK; + offset[n++] = NODE_DIND_BLOCK(sbi); noffset[n] = 5 + (dptrs_per_blk * 2); offset[n++] = block / indirect_blks; noffset[n] = 6 + (dptrs_per_blk * 2) + @@ -1054,6 +1058,7 @@ static int truncate_dnode(struct dnode_of_data *dn) static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, int ofs, int depth) { + struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode); struct dnode_of_data rdn = *dn; struct folio *folio; struct f2fs_node *rn; @@ -1063,7 +1068,7 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, int i, ret; if (dn->nid == 0) - return NIDS_PER_BLOCK + 1; + return NIDS_PER_BLOCK(sbi) + 1; trace_f2fs_truncate_nodes_enter(dn->inode, dn->nid, dn->data_blkaddr); @@ -1074,11 +1079,11 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, return PTR_ERR(folio); } - f2fs_ra_node_pages(folio, ofs, NIDS_PER_BLOCK); + f2fs_ra_node_pages(folio, ofs, NIDS_PER_BLOCK(sbi)); rn = F2FS_NODE(folio); if (depth < 3) { - for (i = ofs; i < NIDS_PER_BLOCK; i++, freed++) { + for (i = ofs; i < NIDS_PER_BLOCK(sbi); i++, freed++) { child_nid = le32_to_cpu(rn->in.nid[i]); if (child_nid == 0) continue; @@ -1090,16 +1095,16 @@ static int truncate_nodes(struct dnode_of_data *dn, unsigned int nofs, dn->node_changed = true; } } else { - child_nofs = nofs + ofs * (NIDS_PER_BLOCK + 1) + 1; - for (i = ofs; i < NIDS_PER_BLOCK; i++) { + child_nofs = nofs + ofs * (NIDS_PER_BLOCK(sbi) + 1) + 1; + for (i = ofs; i < NIDS_PER_BLOCK(sbi); i++) { child_nid = le32_to_cpu(rn->in.nid[i]); if (child_nid == 0) { - child_nofs += NIDS_PER_BLOCK + 1; + child_nofs += NIDS_PER_BLOCK(sbi) + 1; continue; } rdn.nid = child_nid; ret = truncate_nodes(&rdn, child_nofs, 0, depth - 1); - if (ret == (NIDS_PER_BLOCK + 1)) { + if (ret == (NIDS_PER_BLOCK(sbi) + 1)) { if (set_nid(folio, i, 0, false)) dn->node_changed = true; child_nofs += ret; @@ -1156,10 +1161,12 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, nid[i + 1] = get_nid(folios[i], offset[i + 1], false); } - f2fs_ra_node_pages(folios[idx], offset[idx + 1], NIDS_PER_BLOCK); + f2fs_ra_node_pages(folios[idx], offset[idx + 1], + NIDS_PER_BLOCK(F2FS_I_SB(dn->inode))); /* free direct nodes linked to a partial indirect node */ - for (i = offset[idx + 1]; i < NIDS_PER_BLOCK; i++) { + for (i = offset[idx + 1]; + i < NIDS_PER_BLOCK(F2FS_I_SB(dn->inode)); i++) { child_nid = get_nid(folios[idx], i, false); if (!child_nid) continue; @@ -1193,7 +1200,9 @@ static int truncate_partial_nodes(struct dnode_of_data *dn, } /* - * All the block addresses of data and nodes should be nullified. + * All the node blocks actually belong to the inode will be released. + * If the level is 0, we will simply truncate the dnode, + * or else we should do dynamic truncate for the node pointers with the depth. */ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from) { @@ -1240,10 +1249,10 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from) err = truncate_partial_nodes(&dn, offset, level); if (err < 0 && err != -ENOENT) goto fail; - nofs += 1 + NIDS_PER_BLOCK; + nofs += 1 + NIDS_PER_BLOCK(sbi); break; case 3: - nofs = 5 + 2 * NIDS_PER_BLOCK; + nofs = 5 + 2 * NIDS_PER_BLOCK(sbi); if (!offset[level - 1]) goto skip_partial; err = truncate_partial_nodes(&dn, offset, level); @@ -1257,23 +1266,16 @@ int f2fs_truncate_inode_blocks(struct inode *inode, pgoff_t from) skip_partial: while (cont) { dn.nid = get_nid(folio, offset[0], true); - switch (offset[0]) { - case NODE_DIR1_BLOCK: - case NODE_DIR2_BLOCK: + if (offset[0] == NODE_DIR1_BLOCK(sbi) || + offset[0] == NODE_DIR2_BLOCK(sbi)) { err = truncate_dnode(&dn); - break; - - case NODE_IND1_BLOCK: - case NODE_IND2_BLOCK: + } else if (offset[0] == NODE_IND1_BLOCK(sbi) || + offset[0] == NODE_IND2_BLOCK(sbi)) { err = truncate_nodes(&dn, nofs, offset[1], 2); - break; - - case NODE_DIND_BLOCK: + } else if (offset[0] == NODE_DIND_BLOCK(sbi)) { err = truncate_nodes(&dn, nofs, offset[1], 3); cont = 0; - break; - - default: + } else { BUG(); } if (err == -ENOENT) { diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h index 32125f8fc753..66898288b961 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -354,17 +354,18 @@ static inline bool is_recoverable_dnode(const struct folio *folio) */ static inline bool IS_DNODE(const struct folio *node_folio) { + struct f2fs_sb_info *sbi = F2FS_F_SB(node_folio); unsigned int ofs = ofs_of_node(node_folio); if (f2fs_has_xattr_block(ofs)) return true; - if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK || - ofs == 5 + 2 * NIDS_PER_BLOCK) + if (ofs == 3 || ofs == 4 + NIDS_PER_BLOCK(sbi) || + ofs == 5 + 2 * NIDS_PER_BLOCK(sbi)) return false; - if (ofs >= 6 + 2 * NIDS_PER_BLOCK) { - ofs -= 6 + 2 * NIDS_PER_BLOCK; - if (!((long int)ofs % (NIDS_PER_BLOCK + 1))) + if (ofs >= 6 + 2 * NIDS_PER_BLOCK(sbi)) { + ofs -= 6 + 2 * NIDS_PER_BLOCK(sbi); + if (!((long)ofs % (NIDS_PER_BLOCK(sbi) + 1))) return false; } return true; @@ -372,13 +373,15 @@ 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_sb_info *sbi = F2FS_F_SB(folio); struct f2fs_node *rn = F2FS_NODE(folio); __le32 *inode_nids = F2FS_INODE_NIDS(folio); f2fs_folio_wait_writeback(folio, NODE, true, true); if (i) - inode_nids[off - NODE_DIR1_BLOCK] = cpu_to_le32(nid); + inode_nids[off - NODE_DIR1_BLOCK(sbi)] = + cpu_to_le32(nid); else rn->in.nid[off] = cpu_to_le32(nid); return folio_mark_dirty(folio); @@ -388,9 +391,10 @@ 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); + int nid_index = off - NODE_DIR1_BLOCK(F2FS_F_SB(folio)); if (i) - return le32_to_cpu(inode_nids[off - NODE_DIR1_BLOCK]); + return le32_to_cpu(inode_nids[nid_index]); return le32_to_cpu(rn->in.nid[off]); } diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index ca6403a0ed88..f6c492f76f0c 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3899,17 +3899,17 @@ loff_t max_file_blocks(struct f2fs_sb_info *sbi, struct inode *inode) if (inode && f2fs_compressed_file(inode)) leaf_count = ADDRS_PER_BLOCK(inode); else - leaf_count = DEF_ADDRS_PER_BLOCK; + leaf_count = DEF_ADDRS_PER_BLOCK(sbi); /* two direct node blocks */ result += (leaf_count * 2); /* two indirect node blocks */ - leaf_count *= NIDS_PER_BLOCK; + leaf_count *= NIDS_PER_BLOCK(sbi); result += (leaf_count * 2); /* one double indirect node block */ - leaf_count *= NIDS_PER_BLOCK; + leaf_count *= NIDS_PER_BLOCK(sbi); result += leaf_count; /* diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 957bb713ff24..e43ac6509550 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -271,27 +271,15 @@ struct node_footer { } __packed; /* Address Pointers in an Inode */ -#define DEF_ADDRS_PER_INODE ((PAGE_SIZE - 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 DEF_ADDRS_PER_INODE(inode) \ + ((i_blocksize(inode) - 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 */ -#define DEF_ADDRS_PER_BLOCK ((PAGE_SIZE - sizeof(struct node_footer)) / sizeof(__le32)) #define ADDRS_PER_BLOCK(inode) addrs_per_page(inode, false) -/* Node IDs in an Indirect Block */ -#define NIDS_PER_BLOCK ((PAGE_SIZE - sizeof(struct node_footer)) / sizeof(__le32)) - #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 F2FS_INLINE_XATTR 0x01 /* file inline xattr flag */ #define F2FS_INLINE_DATA 0x02 /* file inline data flag */ #define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ -- 2.53.0