Linux XFS filesystem development
 help / color / mirror / Atom feed
From: Andrey Albershteyn <aalbersh@kernel.org>
To: linux-xfs@vger.kernel.org, aalbersh@kernel.org
Cc: bestswngs@gmail.com, brauner@kernel.org, cem@kernel.org,
	chuck.lever@oracle.com, cmaiolino@redhat.com,
	dawei.feng@seu.edu.cn, djwong@kernel.org,
	gaoyingjie@uniontech.com, hch@lst.de, jiapenglin@tencent.com,
	roland.mainz@nrubsig.org, xmei5@asu.edu
Subject: [PATCH 12/21] xfs: store an agbno in struct xfs_imap
Date: Mon, 24 Aug 2026 12:40:10 +0200	[thread overview]
Message-ID: <20260824104022.420566-13-aalbersh@kernel.org> (raw)
In-Reply-To: <20260824104022.420566-1-aalbersh@kernel.org>

From: Christoph Hellwig <hch@lst.de>

Source kernel commit: 9b64ca202f364a6bf8e19bdd20953bc2d776c67f

The xfs_imap structure is embedded into the xfs_inode, which means the
size of it directly affects the inode size.  Replacing the xfs_daddr_t
with an xfs_agbno_t and taking the AG information from other easily
available sources allows us to shrink the structure including the
typical padding from 16 bytes to 8 bytes.

As a side-effect the debugging check in xfs_imap() naturally now
converges to a stricter variant that checks that the cluster is located
inside a single AG, and not just inside the entire device.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
---
 db/iunlink.c             |  4 +++-
 libxfs/inode.c           |  4 +++-
 libxfs/iunlink.c         |  2 +-
 libxfs/libxfs_api_defs.h |  2 +-
 libxfs/logitem.c         |  6 +++++-
 libxfs/xfs_ialloc.c      | 24 +++++++-----------------
 libxfs/xfs_inode_buf.c   | 11 ++++++-----
 libxfs/xfs_inode_buf.h   |  8 ++++----
 repair/bmap_repair.c     |  6 +++++-
 9 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/db/iunlink.c b/db/iunlink.c
index eaf5a812114b..c44917637352 100644
--- a/db/iunlink.c
+++ b/db/iunlink.c
@@ -46,6 +46,7 @@ get_next_unlinked(
 	xfs_ino_t		ino;
 	xfs_agino_t		ret;
 	int			error;
+	struct xfs_perag	*pag = libxfs_perag_get(mp, agno);
 
 	ino = XFS_AGINO_TO_INO(mp, agno, agino);
 	error = -libxfs_iget(mp, NULL, ino, 0, &ip);
@@ -65,7 +66,8 @@ get_next_unlinked(
 		dbprintf("\n");
 	}
 
-	error = -libxfs_imap_to_bp(mp, NULL, &ip->i_imap, &ino_bp);
+	error = -libxfs_read_icluster(pag, NULL, ip->i_imap.im_agbno, &ino_bp);
+	libxfs_perag_put(pag);
 	if (error) {
 		libxfs_irele(ip);
 		goto bad;
diff --git a/libxfs/inode.c b/libxfs/inode.c
index 4608e44658d8..21a76c3229f5 100644
--- a/libxfs/inode.c
+++ b/libxfs/inode.c
@@ -182,7 +182,7 @@ libxfs_iget(
 	} else {
 		struct xfs_buf		*bp;
 
-		error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp);
+		error = xfs_read_icluster(pag, tp, ip->i_imap.im_agbno, &bp);
 		if (error)
 			goto out_destroy;
 
@@ -195,11 +195,13 @@ libxfs_iget(
 		if (error)
 			goto out_destroy;
 	}
+	xfs_perag_put(pag);
 
 	*ipp = ip;
 	return 0;
 
 out_destroy:
+	xfs_perag_put(pag);
 	kmem_cache_free(xfs_inode_cache, ip);
 	*ipp = NULL;
 	return error;
diff --git a/libxfs/iunlink.c b/libxfs/iunlink.c
index 1b96511b6608..aad43dfb27f1 100644
--- a/libxfs/iunlink.c
+++ b/libxfs/iunlink.c
@@ -44,7 +44,7 @@ xfs_iunlink_log_dinode(
 	int			offset;
 	int			error;
 
-	error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &ibp);
+	error = xfs_read_icluster(iup->pag, tp, ip->i_imap.im_agbno, &ibp);
 	if (error)
 		return error;
 	/*
diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
index d7c912e77879..4f542ae7267e 100644
--- a/libxfs/libxfs_api_defs.h
+++ b/libxfs/libxfs_api_defs.h
@@ -200,7 +200,7 @@
 #define xfs_iext_lookup_extent		libxfs_iext_lookup_extent
 #define xfs_iext_next			libxfs_iext_next
 #define xfs_ifork_zap_attr		libxfs_ifork_zap_attr
-#define xfs_imap_to_bp			libxfs_imap_to_bp
+#define xfs_read_icluster		libxfs_read_icluster
 
 #define xfs_initialize_perag		libxfs_initialize_perag
 #define xfs_initialize_perag_data	libxfs_initialize_perag_data
diff --git a/libxfs/logitem.c b/libxfs/logitem.c
index 67b982788061..b3b27f1656b6 100644
--- a/libxfs/logitem.c
+++ b/libxfs/logitem.c
@@ -16,6 +16,7 @@
 #include "xfs_inode.h"
 #include "xfs_trans.h"
 #include "xfs_rtbitmap.h"
+#include "xfs_ag.h"
 
 struct kmem_cache	*xfs_buf_item_cache;
 struct kmem_cache	*xfs_ili_cache;		/* inode log item cache */
@@ -248,6 +249,7 @@ xfs_inode_item_precommit(
 	}
 
 	if (!iip->ili_item.li_buf) {
+		struct xfs_perag	*pag;
 		struct xfs_buf	*bp;
 		int		error;
 
@@ -261,7 +263,9 @@ xfs_inode_item_precommit(
 		 * here.
 		 */
 		spin_unlock(&iip->ili_lock);
-		error = xfs_imap_to_bp(ip->i_mount, tp, &ip->i_imap, &bp);
+		pag = xfs_perag_get(ip->i_mount, XFS_INODE_TO_AGNO(ip));
+		error = xfs_read_icluster(pag, tp, ip->i_imap.im_agbno, &bp);
+		xfs_perag_put(pag);
 		if (error)
 			return error;
 
diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c
index 7ecb7d54577a..f2669dc4907e 100644
--- a/libxfs/xfs_ialloc.c
+++ b/libxfs/xfs_ialloc.c
@@ -1070,7 +1070,7 @@ xfs_dialloc_check_ino(
 	if (error)
 		return -EAGAIN;
 
-	error = xfs_read_icluster(pag_mount(pag), tp, imap.im_blkno, &bp);
+	error = xfs_read_icluster(pag, tp, imap.im_agbno, &bp);
 	if (error)
 		return -EAGAIN;
 
@@ -2546,23 +2546,13 @@ out_map:
 	offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
 		XFS_INO_TO_OFFSET(mp, ino);
 out:
-	imap->im_blkno = xfs_agbno_to_daddr(pag, cluster_agbno);
+	imap->im_agbno = cluster_agbno;
 	imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog);
-
-	/*
-	 * If the inode number maps to a block outside the bounds
-	 * of the file system then return NULL rather than calling
-	 * read_buf and panicing when we get an error from the
-	 * driver.
-	 */
-	if (imap->im_blkno +
-	    XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster) >
-	    XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
-		xfs_alert(mp,
-	"%s: (im_blkno (0x%llx) + len (0x%x)) > sb_dblocks (0x%llx)",
-			__func__, imap->im_blkno,
-			XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster),
-			XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
+	if (imap->im_agbno + M_IGEO(mp)->blocks_per_cluster >
+	    pag_group(pag)->xg_block_count) {
+		xfs_alert(mp, "inode cluster out of range: %u/%u > %u",
+			imap->im_agbno, M_IGEO(mp)->blocks_per_cluster,
+			pag_group(pag)->xg_block_count);
 		return -EINVAL;
 	}
 	return 0;
diff --git a/libxfs/xfs_inode_buf.c b/libxfs/xfs_inode_buf.c
index 6882f7099ab0..9990aaeef5fd 100644
--- a/libxfs/xfs_inode_buf.c
+++ b/libxfs/xfs_inode_buf.c
@@ -124,19 +124,20 @@ const struct xfs_buf_ops xfs_inode_buf_ra_ops = {
  */
 int
 xfs_read_icluster(
-	struct xfs_mount	*mp,
+	struct xfs_perag	*pag,
 	struct xfs_trans	*tp,
-	xfs_daddr_t		bno,
+	xfs_agblock_t		agbno,
 	struct xfs_buf		**bpp)
 {
+	struct xfs_mount	*mp = pag_mount(pag);
 	int			error;
 
-	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, bno,
+	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
+			xfs_agbno_to_daddr(pag, agbno),
 			XFS_FSB_TO_BB(mp, M_IGEO(mp)->blocks_per_cluster),
 			0, bpp, &xfs_inode_buf_ops);
 	if (xfs_metadata_is_sick(error))
-		xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, bno),
-				XFS_SICK_AG_INODES);
+		xfs_agno_mark_sick(mp, pag_agno(pag), XFS_SICK_AG_INODES);
 	return error;
 }
 
diff --git a/libxfs/xfs_inode_buf.h b/libxfs/xfs_inode_buf.h
index bcad22871b5c..57192adc7744 100644
--- a/libxfs/xfs_inode_buf.h
+++ b/libxfs/xfs_inode_buf.h
@@ -14,12 +14,12 @@ struct xfs_dinode;
  * xfs_read_icluster() to get a buffer and dinode for a given inode.
  */
 struct xfs_imap {
-	xfs_daddr_t	im_blkno;	/* starting BB of inode chunk */
-	unsigned short	im_boffset;	/* inode offset in block in bytes */
+	xfs_agblock_t	im_agbno;	/* starting agbno of inode cluster */
+	unsigned short	im_boffset;	/* offset in inode cluster in bytes */
 };
 
-int	xfs_read_icluster(struct xfs_mount *mp, struct xfs_trans *tp,
-		xfs_daddr_t bno, struct xfs_buf **bpp);
+int	xfs_read_icluster(struct xfs_perag *pag, struct xfs_trans *tp,
+		xfs_agblock_t agbno, struct xfs_buf **bpp);
 void	xfs_dinode_calc_crc(struct xfs_mount *mp, struct xfs_dinode *dip);
 void	xfs_inode_to_disk(struct xfs_inode *ip, struct xfs_dinode *to,
 			  xfs_lsn_t lsn);
diff --git a/repair/bmap_repair.c b/repair/bmap_repair.c
index 4812230ecd57..57ec430680c9 100644
--- a/repair/bmap_repair.c
+++ b/repair/bmap_repair.c
@@ -745,6 +745,7 @@ rebuild_bmap(
 	xfs_daddr_t		bp_bn;
 	int			bp_length;
 	int			error, err2;
+	struct xfs_perag	*pag;
 
 	bp_bn = xfs_buf_daddr(*ino_bpp);
 	bp_length = (*ino_bpp)->b_length;
@@ -821,7 +822,10 @@ rebuild_bmap(
 	 * Rebuilding the inode fork rolled the transaction, so we need to
 	 * re-grab the inode cluster buffer and dinode pointer for the caller.
 	 */
-	err2 = -libxfs_imap_to_bp(mp, NULL, &sc.ip->i_imap, ino_bpp);
+	pag = libxfs_perag_get(sc.ip->i_mount, XFS_INODE_TO_AGNO(sc.ip));
+	err2 = -libxfs_read_icluster(pag, NULL, sc.ip->i_imap.im_agbno,
+			ino_bpp);
+	libxfs_perag_put(pag);
 	if (err2)
 		do_error(
  _("Unable to re-grab inode cluster buffer after failed repair of inode %llu, error %d.\n"),
-- 
2.55.0


  parent reply	other threads:[~2026-08-24 11:46 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-24 10:39 [PATCH 00/21] xfsprogs: libxfs sync for v7.2 Andrey Albershteyn
2026-08-24 10:39 ` [PATCH 01/21] xfs: Report case sensitivity in fileattr_get Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 02/21] xfs: fix exchmaps reservation limit check Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 03/21] xfs: add a XFS_INODE_TO_AGNO helper Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 04/21] xfs: add a XFS_INODE_TO_AGINO helper Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 05/21] xfs: add a XFS_INO_TO_FSB helper Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 06/21] xfs: add a xfs_rmap_inode_bmbt_owner Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 07/21] xfs: add a xfs_rmap_inode_owner helper Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 08/21] xfs: remove the i_ino field in struct xfs_inode Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 09/21] xfs: cleanup xfs_imap Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 10/21] xfs: remove im_len field in struct xfs_imap Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 11/21] xfs: massage xfs_imap_to_bp into xfs_read_icluster Andrey Albershteyn
2026-08-24 10:40 ` Andrey Albershteyn [this message]
2026-08-24 10:40 ` [PATCH 13/21] xfs: mark struct xfs_imap as __packed Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 14/21] xfs: fix pointer arithmetic error on 32-bit systems Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 15/21] xfs: pass back updated nb from xfs_growfs_compute_deltas Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 16/21] xfs: cleanup xfs_growfs_compute_deltas Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 17/21] xfs: fix memory leak in xfs_dqinode_metadir_create() Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 18/21] xfs: fix null pointer dereference in tracepoint Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 19/21] xfs: fix off-by-one in rtrefcount btree root level validation Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 20/21] xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN Andrey Albershteyn
2026-08-24 10:40 ` [PATCH 21/21] xfs: check v5 superblock features early Andrey Albershteyn
2026-08-24 18:14 ` [PATCH 00/21] xfsprogs: libxfs sync for v7.2 Darrick J. Wong
2026-08-26  5:13 ` Christoph Hellwig

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=20260824104022.420566-13-aalbersh@kernel.org \
    --to=aalbersh@kernel.org \
    --cc=bestswngs@gmail.com \
    --cc=brauner@kernel.org \
    --cc=cem@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=cmaiolino@redhat.com \
    --cc=dawei.feng@seu.edu.cn \
    --cc=djwong@kernel.org \
    --cc=gaoyingjie@uniontech.com \
    --cc=hch@lst.de \
    --cc=jiapenglin@tencent.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=roland.mainz@nrubsig.org \
    --cc=xmei5@asu.edu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox