Commit 7195f240 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: make xfs_rtblock_t a segmented address like xfs_fsblock_t



Now that we've finished adding allocation groups to the realtime volume,
let's make the file block mapping address (xfs_rtblock_t) a segmented
value just like we do on the data device.  This means that group number
and block number conversions can be done with shifting and masking
instead of integer division.

While in theory we could continue caching the rgno shift value in
m_rgblklog, the fact that we now always use the shift value means that
we have an opportunity to increase the redundancy of the rt geometry by
storing it in the ondisk superblock and adding more sb verifier code.
Extend the sueprblock to store the rgblklog value.

Now that we have segmented addresses, set the correct values in
m_groups[XG_TYPE_RTG] so that the xfs_group helpers work correctly.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 3f0205eb
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -3152,10 +3152,8 @@ xfs_bmap_adjacent_valid(

	if (XFS_IS_REALTIME_INODE(ap->ip) &&
	    (ap->datatype & XFS_ALLOC_USERDATA)) {
		if (x >= mp->m_sb.sb_rblocks)
			return false;
		if (!xfs_has_rtgroups(mp))
			return true;
			return x < mp->m_sb.sb_rblocks;

		return xfs_rtb_to_rgno(mp, x) == xfs_rtb_to_rgno(mp, y) &&
			xfs_rtb_to_rgno(mp, x) < mp->m_sb.sb_rgcount &&
+6 −0
Original line number Diff line number Diff line
@@ -179,6 +179,9 @@ typedef struct xfs_sb {
	xfs_rgnumber_t	sb_rgcount;	/* number of realtime groups */
	xfs_rtxlen_t	sb_rgextents;	/* size of a realtime group in rtx */

	uint8_t		sb_rgblklog;    /* rt group number shift */
	uint8_t		sb_pad[7];	/* zeroes */

	/* must be padded to 64 bit alignment */
} xfs_sb_t;

@@ -268,6 +271,9 @@ struct xfs_dsb {
	__be32		sb_rgcount;	/* # of realtime groups */
	__be32		sb_rgextents;	/* size of rtgroup in rtx */

	__u8		sb_rgblklog;    /* rt group number shift */
	__u8		sb_pad[7];	/* zeroes */

	/*
	 * The size of this structure must be padded to 64 bit alignment.
	 *
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ xfs_check_ondisk_structs(void)
	XFS_CHECK_STRUCT_SIZE(struct xfs_dinode,		176);
	XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot,		104);
	XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk,			136);
	XFS_CHECK_STRUCT_SIZE(struct xfs_dsb,			280);
	XFS_CHECK_STRUCT_SIZE(struct xfs_dsb,			288);
	XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr,		56);
	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key,		4);
	XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec,		16);
+7 −6
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ xfs_rtx_to_rtb(
	xfs_rtxnum_t		rtx)
{
	struct xfs_mount	*mp = rtg_mount(rtg);
	xfs_rtblock_t		start = xfs_rgno_start_rtb(mp, rtg_rgno(rtg));
	xfs_rtblock_t		start = xfs_group_start_fsb(rtg_group(rtg));

	if (mp->m_rtxblklog >= 0)
		return start + (rtx << mp->m_rtxblklog);
@@ -128,11 +128,11 @@ xfs_rtb_to_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	uint64_t		__rgbno = __xfs_rtb_to_rgbno(mp, rtbno);

	/* open-coded 64-bit masking operation */
	rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask;
	if (likely(mp->m_rtxblklog >= 0))
		return __rgbno >> mp->m_rtxblklog;
	return div_u64(__rgbno, mp->m_sb.sb_rextsize);
		return rtbno >> mp->m_rtxblklog;
	return div_u64(rtbno, mp->m_sb.sb_rextsize);
}

/* Return the offset of an rt block number within an rt extent. */
@@ -141,9 +141,10 @@ xfs_rtb_to_rtxoff(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	/* open-coded 64-bit masking operation */
	rtbno &= mp->m_groups[XG_TYPE_RTG].blkmask;
	if (likely(mp->m_rtxblklog >= 0))
		return rtbno & mp->m_rtxblkmask;

	return do_div(rtbno, mp->m_sb.sb_rextsize);
}

+21 −48
Original line number Diff line number Diff line
@@ -122,31 +122,12 @@ xfs_rtgroup_next(
	return xfs_rtgroup_next_range(mp, rtg, 0, mp->m_sb.sb_rgcount - 1);
}

static inline xfs_rtblock_t
xfs_rgno_start_rtb(
	struct xfs_mount	*mp,
	xfs_rgnumber_t		rgno)
{
	if (mp->m_rgblklog >= 0)
		return ((xfs_rtblock_t)rgno << mp->m_rgblklog);
	return ((xfs_rtblock_t)rgno * mp->m_rgblocks);
}

static inline xfs_rtblock_t
__xfs_rgbno_to_rtb(
	struct xfs_mount	*mp,
	xfs_rgnumber_t		rgno,
	xfs_rgblock_t		rgbno)
{
	return xfs_rgno_start_rtb(mp, rgno) + rgbno;
}

static inline xfs_rtblock_t
xfs_rgbno_to_rtb(
	struct xfs_rtgroup	*rtg,
	xfs_rgblock_t		rgbno)
{
	return __xfs_rgbno_to_rtb(rtg_mount(rtg), rtg_rgno(rtg), rgbno);
	return xfs_gbno_to_fsb(rtg_group(rtg), rgbno);
}

static inline xfs_rgnumber_t
@@ -154,30 +135,7 @@ xfs_rtb_to_rgno(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	if (!xfs_has_rtgroups(mp))
		return 0;

	if (mp->m_rgblklog >= 0)
		return rtbno >> mp->m_rgblklog;

	return div_u64(rtbno, mp->m_rgblocks);
}

static inline uint64_t
__xfs_rtb_to_rgbno(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	uint32_t		rem;

	if (!xfs_has_rtgroups(mp))
		return rtbno;

	if (mp->m_rgblklog >= 0)
		return rtbno & mp->m_rgblkmask;

	div_u64_rem(rtbno, mp->m_rgblocks, &rem);
	return rem;
	return xfs_fsb_to_gno(mp, rtbno, XG_TYPE_RTG);
}

static inline xfs_rgblock_t
@@ -185,7 +143,7 @@ xfs_rtb_to_rgbno(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return __xfs_rtb_to_rgbno(mp, rtbno);
	return xfs_fsb_to_gbno(mp, rtbno, XG_TYPE_RTG);
}

/* Is rtbno the start of a RT group? */
@@ -194,7 +152,7 @@ xfs_rtbno_is_group_start(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return (rtbno & mp->m_rgblkmask) == 0;
	return (rtbno & mp->m_groups[XG_TYPE_RTG].blkmask) == 0;
}

static inline xfs_daddr_t
@@ -202,7 +160,11 @@ xfs_rtb_to_daddr(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return rtbno << mp->m_blkbb_log;
	struct xfs_groups	*g = &mp->m_groups[XG_TYPE_RTG];
	xfs_rgnumber_t		rgno = xfs_rtb_to_rgno(mp, rtbno);
	uint64_t		start_bno = (xfs_rtblock_t)rgno * g->blocks;

	return XFS_FSB_TO_BB(mp, start_bno + (rtbno & g->blkmask));
}

static inline xfs_rtblock_t
@@ -210,7 +172,18 @@ xfs_daddr_to_rtb(
	struct xfs_mount	*mp,
	xfs_daddr_t		daddr)
{
	return daddr >> mp->m_blkbb_log;
	xfs_rfsblock_t		bno = XFS_BB_TO_FSBT(mp, daddr);

	if (xfs_has_rtgroups(mp)) {
		struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG];
		xfs_rgnumber_t	rgno;
		uint32_t	rgbno;

		rgno = div_u64_rem(bno, g->blocks, &rgbno);
		return ((xfs_rtblock_t)rgno << g->blklog) + rgbno;
	}

	return bno;
}

#ifdef CONFIG_XFS_RT
Loading