]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: add group based bno conversion helpers
authorChristoph Hellwig <hch@lst.de>
Mon, 4 Nov 2024 04:18:45 +0000 (20:18 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 5 Nov 2024 21:38:29 +0000 (13:38 -0800)
Add/move the blocks, blklog and blkmask fields to the generic groups
structure so that code can work with AGs and RTGs by just using the
right index into the array.

Then, add convenience helpers to convert block numbers based on the
generic group.  This will allow writing code that doesn't care if it is
used on AGs or the upcoming realtime groups.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
fs/xfs/libxfs/xfs_group.c
fs/xfs/libxfs/xfs_group.h
fs/xfs/libxfs/xfs_sb.c
fs/xfs/xfs_mount.h

index 5c6fa5d76a91b1e9be9cfd7d54a6b4466a1c3f4a..e9d76bcdc820ddcb7ac02485bdda69f7b719862b 100644 (file)
@@ -214,3 +214,12 @@ out_drain:
 #endif
        return error;
 }
+
+struct xfs_group *
+xfs_group_get_by_fsb(
+       struct xfs_mount        *mp,
+       xfs_fsblock_t           fsbno,
+       enum xfs_group_type     type)
+{
+       return xfs_group_get(mp, xfs_fsb_to_gno(mp, fsbno, type), type);
+}
index 0ff6e1d5635cb19924db2db03cf4dd0023b44979..5b7362277c3f7ab6b3cc1e65cc7022031bca31fc 100644 (file)
@@ -46,6 +46,8 @@ struct xfs_group {
 
 struct xfs_group *xfs_group_get(struct xfs_mount *mp, uint32_t index,
                enum xfs_group_type type);
+struct xfs_group *xfs_group_get_by_fsb(struct xfs_mount *mp,
+               xfs_fsblock_t fsbno, enum xfs_group_type type);
 struct xfs_group *xfs_group_hold(struct xfs_group *xg);
 void xfs_group_put(struct xfs_group *xg);
 
@@ -72,4 +74,58 @@ int xfs_group_insert(struct xfs_mount *mp, struct xfs_group *xg,
 #define xfs_group_marked(_mp, _type, _mark) \
        xa_marked(&(_mp)->m_groups[(_type)].xa, (_mark))
 
+static inline xfs_agblock_t
+xfs_group_max_blocks(
+       struct xfs_group        *xg)
+{
+       return xg->xg_mount->m_groups[xg->xg_type].blocks;
+}
+
+static inline xfs_fsblock_t
+xfs_group_start_fsb(
+       struct xfs_group        *xg)
+{
+       return ((xfs_fsblock_t)xg->xg_gno) <<
+               xg->xg_mount->m_groups[xg->xg_type].blklog;
+}
+
+static inline xfs_fsblock_t
+xfs_gbno_to_fsb(
+       struct xfs_group        *xg,
+       xfs_agblock_t           gbno)
+{
+       return xfs_group_start_fsb(xg) | gbno;
+}
+
+static inline xfs_daddr_t
+xfs_gbno_to_daddr(
+       struct xfs_group        *xg,
+       xfs_agblock_t           gbno)
+{
+       struct xfs_mount        *mp = xg->xg_mount;
+       uint32_t                blocks = mp->m_groups[xg->xg_type].blocks;
+
+       return XFS_FSB_TO_BB(mp, (xfs_fsblock_t)xg->xg_gno * blocks + gbno);
+}
+
+static inline uint32_t
+xfs_fsb_to_gno(
+       struct xfs_mount        *mp,
+       xfs_fsblock_t           fsbno,
+       enum xfs_group_type     type)
+{
+       if (!mp->m_groups[type].blklog)
+               return 0;
+       return fsbno >> mp->m_groups[type].blklog;
+}
+
+static inline xfs_agblock_t
+xfs_fsb_to_gbno(
+       struct xfs_mount        *mp,
+       xfs_fsblock_t           fsbno,
+       enum xfs_group_type     type)
+{
+       return fsbno & mp->m_groups[type].blkmask;
+}
+
 #endif /* __LIBXFS_GROUP_H */
index 061c8c961d5bc9b473b31dc9aeb8447199eafc6a..f7a07e61341ded9e0ad6aebfafa665479c2e70d2 100644 (file)
@@ -988,6 +988,8 @@ xfs_sb_mount_common(
        struct xfs_mount        *mp,
        struct xfs_sb           *sbp)
 {
+       struct xfs_groups       *ags = &mp->m_groups[XG_TYPE_AG];
+
        mp->m_agfrotor = 0;
        atomic_set(&mp->m_agirotor, 0);
        mp->m_maxagi = mp->m_sb.sb_agcount;
@@ -998,6 +1000,11 @@ xfs_sb_mount_common(
        mp->m_blockmask = sbp->sb_blocksize - 1;
        mp->m_blockwsize = sbp->sb_blocksize >> XFS_WORDLOG;
        mp->m_blockwmask = mp->m_blockwsize - 1;
+
+       ags->blocks = mp->m_sb.sb_agblocks;
+       ags->blklog = mp->m_sb.sb_agblklog;
+       ags->blkmask = xfs_mask32lo(mp->m_sb.sb_agblklog);
+
        xfs_mount_sb_set_rextsize(mp, sbp);
 
        mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, true);
index 530d7f025506ce3b5d318511e04de85e0403caf2..1b698878f40cb1b931e58ab5488cc5864aea3112 100644 (file)
@@ -71,8 +71,38 @@ struct xfs_inodegc {
        unsigned int            cpu;
 };
 
+/*
+ * Container for each type of groups, used to look up individual groups and
+ * describes the geometry.
+ */
 struct xfs_groups {
        struct xarray           xa;
+
+       /*
+        * Maximum capacity of the group in FSBs.
+        *
+        * Each group is laid out densely in the daddr space.  For the
+        * degenerate case of a pre-rtgroups filesystem, the incore rtgroup
+        * pretends to have a zero-block and zero-blklog rtgroup.
+        */
+       uint32_t                blocks;
+
+       /*
+        * Log(2) of the logical size of each group.
+        *
+        * Compared to the blocks field above this is rounded up to the next
+        * power of two, and thus lays out the xfs_fsblock_t/xfs_rtblock_t
+        * space sparsely with a hole from blocks to (1 << blklog) at the end
+        * of each group.
+        */
+       uint8_t                 blklog;
+
+       /*
+        * Mask to extract the group-relative block number from a FSB.
+        * For a pre-rtgroups filesystem we pretend to have one very large
+        * rtgroup, so this mask must be 64-bit.
+        */
+       uint64_t                blkmask;
 };
 
 /*