Commit 9d4ca5af authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of...

Merge tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.7-mergeA

xfs: refactor rt extent unit conversions [v1.1]

This series replaces all the open-coded integer division and
multiplication conversions between rt blocks and rt extents with calls
to static inline helpers.  Having cleaned all that up, the helpers are
augmented to skip the expensive operations in favor of bit shifts and
masking if the rt extent size is a power of two.

v1.1: various cleanups suggested by hch

With a bit of luck, this should all go splendidly.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'refactor-rt-unit-conversions-6.7_2023-10-19' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: use shifting and masking when converting rt extents, if possible
  xfs: create rt extent rounding helpers for realtime extent blocks
  xfs: convert do_div calls to xfs_rtb_to_rtx helper calls
  xfs: create helpers to convert rt block numbers to rt extent numbers
  xfs: create a helper to convert extlen to rtextlen
  xfs: create a helper to compute leftovers of realtime extents
  xfs: create a helper to convert rtextents to rtblocks
parents 3ef52c01 ef5a83b7
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -2989,7 +2989,7 @@ xfs_bmap_extsize_align(
	 * If realtime, and the result isn't a multiple of the realtime
	 * extent size we need to remove blocks until it is.
	 */
	if (rt && (temp = (align_alen % mp->m_sb.sb_rextsize))) {
	if (rt && (temp = xfs_extlen_to_rtxmod(mp, align_alen))) {
		/*
		 * We're not covering the original request, or
		 * we won't be able to once we fix the length.
@@ -3016,7 +3016,7 @@ xfs_bmap_extsize_align(
		else {
			align_alen -= orig_off - align_off;
			align_off = orig_off;
			align_alen -= align_alen % mp->m_sb.sb_rextsize;
			align_alen -= xfs_extlen_to_rtxmod(mp, align_alen);
		}
		/*
		 * Result doesn't cover the request, fail it.
@@ -4826,12 +4826,8 @@ xfs_bmap_del_extent_delay(
	ASSERT(got->br_startoff <= del->br_startoff);
	ASSERT(got_endoff >= del_endoff);

	if (isrt) {
		uint64_t	rtexts = del->br_blockcount;

		do_div(rtexts, mp->m_sb.sb_rextsize);
		xfs_mod_frextents(mp, rtexts);
	}
	if (isrt)
		xfs_mod_frextents(mp, xfs_rtb_to_rtx(mp, del->br_blockcount));

	/*
	 * Update the inode delalloc counter now and wait to update the
@@ -5276,7 +5272,6 @@ __xfs_bunmapi(
	int			tmp_logflags;	/* partial logging flags */
	int			wasdel;		/* was a delayed alloc extent */
	int			whichfork;	/* data or attribute fork */
	xfs_fsblock_t		sum;
	xfs_filblks_t		len = *rlen;	/* length to unmap in file */
	xfs_fileoff_t		end;
	struct xfs_iext_cursor	icur;
@@ -5371,8 +5366,8 @@ __xfs_bunmapi(
		if (!isrt)
			goto delete;

		sum = del.br_startblock + del.br_blockcount;
		div_u64_rem(sum, mp->m_sb.sb_rextsize, &mod);
		mod = xfs_rtb_to_rtxoff(mp,
				del.br_startblock + del.br_blockcount);
		if (mod) {
			/*
			 * Realtime extent not lined up at the end.
@@ -5419,7 +5414,8 @@ __xfs_bunmapi(
				goto error0;
			goto nodelete;
		}
		div_u64_rem(del.br_startblock, mp->m_sb.sb_rextsize, &mod);

		mod = xfs_rtb_to_rtxoff(mp, del.br_startblock);
		if (mod) {
			xfs_extlen_t off = mp->m_sb.sb_rextsize - mod;

+2 −2
Original line number Diff line number Diff line
@@ -1024,13 +1024,13 @@ xfs_rtfree_blocks(

	ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);

	len = div_u64_rem(rtlen, mp->m_sb.sb_rextsize, &mod);
	len = xfs_rtb_to_rtxrem(mp, rtlen, &mod);
	if (mod) {
		ASSERT(mod == 0);
		return -EIO;
	}

	start = div_u64_rem(rtbno, mp->m_sb.sb_rextsize, &mod);
	start = xfs_rtb_to_rtxrem(mp, rtbno, &mod);
	if (mod) {
		ASSERT(mod == 0);
		return -EIO;
+125 −0
Original line number Diff line number Diff line
@@ -6,6 +6,131 @@
#ifndef __XFS_RTBITMAP_H__
#define	__XFS_RTBITMAP_H__

static inline xfs_rtblock_t
xfs_rtx_to_rtb(
	struct xfs_mount	*mp,
	xfs_rtxnum_t		rtx)
{
	if (mp->m_rtxblklog >= 0)
		return rtx << mp->m_rtxblklog;

	return rtx * mp->m_sb.sb_rextsize;
}

static inline xfs_extlen_t
xfs_rtxlen_to_extlen(
	struct xfs_mount	*mp,
	xfs_rtxlen_t		rtxlen)
{
	if (mp->m_rtxblklog >= 0)
		return rtxlen << mp->m_rtxblklog;

	return rtxlen * mp->m_sb.sb_rextsize;
}

/* Compute the misalignment between an extent length and a realtime extent .*/
static inline unsigned int
xfs_extlen_to_rtxmod(
	struct xfs_mount	*mp,
	xfs_extlen_t		len)
{
	if (mp->m_rtxblklog >= 0)
		return len & mp->m_rtxblkmask;

	return len % mp->m_sb.sb_rextsize;
}

static inline xfs_rtxlen_t
xfs_extlen_to_rtxlen(
	struct xfs_mount	*mp,
	xfs_extlen_t		len)
{
	if (mp->m_rtxblklog >= 0)
		return len >> mp->m_rtxblklog;

	return len / mp->m_sb.sb_rextsize;
}

/* Convert an rt block number into an rt extent number. */
static inline xfs_rtxnum_t
xfs_rtb_to_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	if (likely(mp->m_rtxblklog >= 0))
		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. */
static inline xfs_extlen_t
xfs_rtb_to_rtxoff(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	if (likely(mp->m_rtxblklog >= 0))
		return rtbno & mp->m_rtxblkmask;

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

/*
 * Crack an rt block number into an rt extent number and an offset within that
 * rt extent.  Returns the rt extent number directly and the offset in @off.
 */
static inline xfs_rtxnum_t
xfs_rtb_to_rtxrem(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno,
	xfs_extlen_t		*off)
{
	if (likely(mp->m_rtxblklog >= 0)) {
		*off = rtbno & mp->m_rtxblkmask;
		return rtbno >> mp->m_rtxblklog;
	}

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

/*
 * Convert an rt block number into an rt extent number, rounding up to the next
 * rt extent if the rt block is not aligned to an rt extent boundary.
 */
static inline xfs_rtxnum_t
xfs_rtb_to_rtxup(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	if (likely(mp->m_rtxblklog >= 0)) {
		if (rtbno & mp->m_rtxblkmask)
			return (rtbno >> mp->m_rtxblklog) + 1;
		return rtbno >> mp->m_rtxblklog;
	}

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

/* Round this rtblock up to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_roundup_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return roundup_64(rtbno, mp->m_sb.sb_rextsize);
}

/* Round this rtblock down to the nearest rt extent size. */
static inline xfs_rtblock_t
xfs_rtb_rounddown_rtx(
	struct xfs_mount	*mp,
	xfs_rtblock_t		rtbno)
{
	return rounddown_64(rtbno, mp->m_sb.sb_rextsize);
}

/*
 * Functions for walking free space rtextents in the realtime bitmap.
 */
+2 −0
Original line number Diff line number Diff line
@@ -975,6 +975,8 @@ 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;
	mp->m_rtxblklog = log2_if_power2(sbp->sb_rextsize);
	mp->m_rtxblkmask = mask64_if_power2(sbp->sb_rextsize);

	mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
	mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "xfs_trans.h"
#include "xfs_qm.h"
#include "xfs_trans_space.h"
#include "xfs_rtbitmap.h"

#define _ALLOC	true
#define _FREE	false
@@ -220,7 +221,7 @@ xfs_rtalloc_block_count(
	unsigned int		blksz = XFS_FSB_TO_B(mp, 1);
	unsigned int		rtbmp_bytes;

	rtbmp_bytes = (XFS_MAX_BMBT_EXTLEN / mp->m_sb.sb_rextsize) / NBBY;
	rtbmp_bytes = xfs_extlen_to_rtxlen(mp, XFS_MAX_BMBT_EXTLEN) / NBBY;
	return (howmany(rtbmp_bytes, blksz) + 1) * num_ops;
}

Loading