From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pl1-f172.google.com (mail-pl1-f172.google.com [209.85.214.172]) (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 4E356386C13 for ; Thu, 3 Sep 2026 23:11:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788477115; cv=none; b=tZO0Pt96YVns5VX7vzMzVC1MlGjoDmZ4Gi8G4+uojkBlfic0GnDKk08xM8KbGzTHeDabQob6Vm9rlHfgM/hFdNNyaEoksKU0tfU7jNXObuvAikh86F0iMNf2Ik3PRHIp98unjvjl0uccWUbl52N5x4AK9nmy6RyH5rWV7jbqwLU= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788477115; c=relaxed/simple; bh=mqtfP0i8XGy/hBN15B4uWSSaMudv0JPOfNB78SntzjE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=agdHugkXFmXcrYqBCrz37o0Zu1CghCMCUMbMbosXPCjnWKBwioQrXR1raV4CkurVQf22ejh7SZDZv2xJ4E5kdsw2irpoScy3Pag5sL7zTk6nayhMAcUf4adsLUpIgIIqc3Oa0vA/BIarpNQjpqju4mCSTr9a7ojeU8SAxq3Xol4= 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=iNbIYC4K; arc=none smtp.client-ip=209.85.214.172 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="iNbIYC4K" Received: by mail-pl1-f172.google.com with SMTP id d9443c01a7336-2caced6038eso4253195ad.0 for ; Thu, 03 Sep 2026 16:11:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788477112; x=1789081912; 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=BtydBFXs7CRcOTOCX1YpFxCvg86LjXn5nkZhhKF1CLw=; b=iNbIYC4KwKHS1C5r/V9TegzZHtYtTguf53M9CsOZcKbISuE03d0f1wap+8SpRiadh7 PIpS2L/LYbtCrMnb9Xg8obJF+foPsWciexpOioQ6IJyR1EYwxCBwa9Eipxkgfut7XdIa GD6+w4711s0exHDz8T1HmrfsLbbNnVOtusBUOqsXpXgq5R+jyTz7oNRtmlXOyLSz/phW nGjIuayCHPqpfgHTpHBFAm4FqX7ppkXE8FWdP1/PGCd/wgHJmuUIEJ3OdOCA2tkYDx+r lywegrvMbQueZLVYk+GvxsEh30Ywmt8hN44FjsI1usstKWD6gQlCO1eN/TnqB83odDzi 70rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788477112; x=1789081912; 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=BtydBFXs7CRcOTOCX1YpFxCvg86LjXn5nkZhhKF1CLw=; b=Lu8M12jh5dUN8g9ghUN8ceF9J5JxpYMWS6S5DC2ugyM2E3dwoUAM+DUDsH0R5tpLPx CWKokZN3Zqac2C/vgLqh/FFSwjFRKrZym6HgHzEMuDJfE+9JB0kvBsz3D2eQskLqt7tN 8EFdGI3h3RkK+0aqJFx4E9EZiwWR2IXh6nejFErgkED2SAuwfCbyzz8oJjjUY8r13hJe Pk0Mko2qoDH9QGH+wuUW3UFiWZXeIjt/9UDxK32SxilTG52WwbMUWS/j06bPKumiR5Ib R1QvWtT3iF28+VoFSdzalO8A9muankm3a7k/1FrFdB/XmKBwSSXVATPh0ifkcRw1WVZw EdaQ== X-Forwarded-Encrypted: i=1; AKwUvBw5zzmtc7C7YtKyaYaS8Azj85TFrfooI1Ls32FIvVh+/trsyA/EEiMW4TlmEcp5PW031gRccRHudAGBZFg=@vger.kernel.org X-Gm-Message-State: AFuF++nc1SoNPXIEMSSpia4lu5vlFA2WgrKFUmoUcnH71M1yBvwX5jH3 x7gjhwKTmIMXFqbUBPtb+WV3vRKgy8eDrOAGLwOABMIDZPaQHUuMpPPK+U7G9DisRDs= X-Gm-Gg: AYBFou2r2M498HBitxnKayK4mc4KtdM9hMbAscO5gqHy3dEliH2mUlXuXm8MKQOxBjq 63DhW/AKrNM7o9R2RftJ9sfMN8MtryTRRsXPYLirIJNJGcH+k3hrnN78e/udksvMn/C6nkjHalL AERDxnUDTBAbsapvKIgDU9DPNXnXK/8BVKUYde0cnTdtjJz+4P8XZVp57X/efxL801S+oa6Qztf d8letNwcGc5Qx1W9ondLup1SJCVWyXJvPP/Dz4BxtZvWoOTAJyuv7IyYZjMinddZ5BTQM6pDbug Fwq6hZRCccxL77kKC8E54N72ZopDJ/9bLGXAiokS2Rl76TNavMjTPOLokrZwm+RJsx8lefd9aY8 A/00vX5RuLYBkJSRmgQLG31sTh4WjlZ1LAKIxKJY8Ins4Qmc7VzKAs3It/zxdp3VBboyr0KxHGb 7XJ4d972XvXy02BIuYjjltQPRReYdebwQyzT6Hr+k29GvgbfspE+Sg4JezNCepAT+ifw== X-Received: by 2002:a17:902:d48b:b0:2d8:d4d2:d139 with SMTP id d9443c01a7336-2dafb1820bcmr82014165ad.21.1788477112433; Thu, 03 Sep 2026 16:11:52 -0700 (PDT) Received: from [127.0.1.1] ([2601:647:4184:b3f0:29c4:4984:db20:3bb4]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2db148404b8sm1942205ad.2.2026.09.03.16.11.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Sep 2026 16:11:51 -0700 (PDT) From: Kelvin Zhang To: linux-f2fs-devel@lists.sourceforge.net Cc: Jaegeuk Kim , Chao Yu , Daeho Jeong , linux-kernel@vger.kernel.org Subject: [PATCH v8 10/11] f2fs: describe node tree geometry dynamically Date: Thu, 3 Sep 2026 16:11:37 -0700 Message-ID: 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 | 11 +++++- fs/f2fs/gc.c | 10 +++--- fs/f2fs/node.c | 74 +++++++++++++++++++++-------------------- fs/f2fs/node.h | 18 ++++++---- fs/f2fs/super.c | 8 ++--- include/linux/f2fs_fs.h | 10 ------ 6 files changed, 69 insertions(+), 62 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 2b8bb42e235a..f293bdd2baca 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -2253,10 +2253,18 @@ 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 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 NODE_DIR1_BLOCK(sbi) (DEF_ADDRS_PER_INODE(sbi) + 1) +#define NODE_DIR2_BLOCK(sbi) (DEF_ADDRS_PER_INODE(sbi) + 2) +#define NODE_IND1_BLOCK(sbi) (DEF_ADDRS_PER_INODE(sbi) + 3) +#define NODE_IND2_BLOCK(sbi) (DEF_ADDRS_PER_INODE(sbi) + 4) +#define NODE_DIND_BLOCK(sbi) (DEF_ADDRS_PER_INODE(sbi) + 5) + static inline struct f2fs_orphan_footer * f2fs_orphan_footer(void *orphan_block, struct f2fs_sb_info *sbi) { @@ -3645,7 +3653,8 @@ 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; + 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 164612dbe2c6..39fa4776404e 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); } 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 e7aa3b790214..7bb99988833a 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 911c3d336533..2766ced7bef7 100644 --- a/fs/f2fs/node.h +++ b/fs/f2fs/node.h @@ -352,17 +352,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; @@ -370,13 +371,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); @@ -386,9 +389,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 3aa8a2198471..0bb8b8048d78 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -3890,7 +3890,7 @@ loff_t max_file_blocks(struct f2fs_sb_info *sbi, struct inode *inode) loff_t leaf_count; /* - * note: previously, result is equal to (DEF_ADDRS_PER_INODE - + * note: previously, result is equal to (DEF_ADDRS_PER_INODE(sbi) - * DEFAULT_INLINE_XATTR_ADDRS), but now f2fs try to reserve more * space in inode.i_addr, it will be more safe to reassign * result as zero. @@ -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 4c9540981db4..9036cc6c2a2c 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -282,19 +282,9 @@ struct node_footer { #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 ((F2FS_BLKSIZE - 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 ((F2FS_BLKSIZE - sizeof(struct node_footer)) / sizeof(__le32)) - #define ADDRS_PER_PAGE(folio, inode) (addrs_per_page(inode, IS_INODE(folio))) -#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 */ #define F2FS_INLINE_DENTRY 0x04 /* file inline dentry flag */ -- 2.53.0