Commit a7ade7e1 authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'btree-readahead-cleanups-6.9_2024-02-23' of...

Merge tag 'btree-readahead-cleanups-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.9-mergeC

xfs: btree readahead cleanups

Minor cleanups for the btree block readahead code.

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

* tag 'btree-readahead-cleanups-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: split xfs_buf_rele for cached vs uncached buffers
  xfs: move and rename xfs_btree_read_bufl
  xfs: remove xfs_btree_reada_bufs
  xfs: remove xfs_btree_reada_bufl
parents 169c030a 24f755e4
Loading
Loading
Loading
Loading
+25 −8
Original line number Diff line number Diff line
@@ -226,6 +226,28 @@ xfs_bmap_forkoff_reset(
	}
}

static int
xfs_bmap_read_buf(
	struct xfs_mount	*mp,		/* file system mount point */
	struct xfs_trans	*tp,		/* transaction pointer */
	xfs_fsblock_t		fsbno,		/* file system block number */
	struct xfs_buf		**bpp)		/* buffer for fsbno */
{
	struct xfs_buf		*bp;		/* return value */
	int			error;

	if (!xfs_verify_fsbno(mp, fsbno))
		return -EFSCORRUPTED;
	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
			XFS_FSB_TO_DADDR(mp, fsbno), mp->m_bsize, 0, &bp,
			&xfs_bmbt_buf_ops);
	if (!error) {
		xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF);
		*bpp = bp;
	}
	return error;
}

#ifdef DEBUG
STATIC struct xfs_buf *
xfs_bmap_get_bp(
@@ -365,9 +387,7 @@ xfs_bmap_check_leaf_extents(
		bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
		if (!bp) {
			bp_release = 1;
			error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
						XFS_BMAP_BTREE_REF,
						&xfs_bmbt_buf_ops);
			error = xfs_bmap_read_buf(mp, NULL, bno, &bp);
			if (xfs_metadata_is_sick(error))
				xfs_btree_mark_sick(cur);
			if (error)
@@ -454,9 +474,7 @@ xfs_bmap_check_leaf_extents(
		bp = xfs_bmap_get_bp(cur, XFS_FSB_TO_DADDR(mp, bno));
		if (!bp) {
			bp_release = 1;
			error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
						XFS_BMAP_BTREE_REF,
						&xfs_bmbt_buf_ops);
			error = xfs_bmap_read_buf(mp, NULL, bno, &bp);
			if (xfs_metadata_is_sick(error))
				xfs_btree_mark_sick(cur);
			if (error)
@@ -573,8 +591,7 @@ xfs_bmap_btree_to_extents(
		return -EFSCORRUPTED;
	}
#endif
	error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
				&xfs_bmbt_buf_ops);
	error = xfs_bmap_read_buf(mp, tp, cbno, &cbp);
	if (xfs_metadata_is_sick(error))
		xfs_btree_mark_sick(cur);
	if (error)
+16 −82
Original line number Diff line number Diff line
@@ -859,95 +859,26 @@ xfs_btree_offsets(
	}
}

/*
 * Get a buffer for the block, return it read in.
 * Long-form addressing.
 */
int
xfs_btree_read_bufl(
	struct xfs_mount	*mp,		/* file system mount point */
	struct xfs_trans	*tp,		/* transaction pointer */
	xfs_fsblock_t		fsbno,		/* file system block number */
	struct xfs_buf		**bpp,		/* buffer for fsbno */
	int			refval,		/* ref count value for buffer */
	const struct xfs_buf_ops *ops)
{
	struct xfs_buf		*bp;		/* return value */
	xfs_daddr_t		d;		/* real disk block address */
	int			error;

	if (!xfs_verify_fsbno(mp, fsbno))
		return -EFSCORRUPTED;
	d = XFS_FSB_TO_DADDR(mp, fsbno);
	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
				   mp->m_bsize, 0, &bp, ops);
	if (error)
		return error;
	if (bp)
		xfs_buf_set_ref(bp, refval);
	*bpp = bp;
	return 0;
}

/*
 * Read-ahead the block, don't wait for it, don't return a buffer.
 * Long-form addressing.
 */
/* ARGSUSED */
void
xfs_btree_reada_bufl(
	struct xfs_mount	*mp,		/* file system mount point */
	xfs_fsblock_t		fsbno,		/* file system block number */
	xfs_extlen_t		count,		/* count of filesystem blocks */
	const struct xfs_buf_ops *ops)
{
	xfs_daddr_t		d;

	ASSERT(fsbno != NULLFSBLOCK);
	d = XFS_FSB_TO_DADDR(mp, fsbno);
	xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
}

/*
 * Read-ahead the block, don't wait for it, don't return a buffer.
 * Short-form addressing.
 */
/* ARGSUSED */
void
xfs_btree_reada_bufs(
	struct xfs_mount	*mp,		/* file system mount point */
	xfs_agnumber_t		agno,		/* allocation group number */
	xfs_agblock_t		agbno,		/* allocation group block number */
	xfs_extlen_t		count,		/* count of filesystem blocks */
	const struct xfs_buf_ops *ops)
{
	xfs_daddr_t		d;

	ASSERT(agno != NULLAGNUMBER);
	ASSERT(agbno != NULLAGBLOCK);
	d = XFS_AGB_TO_DADDR(mp, agno, agbno);
	xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
}

STATIC int
xfs_btree_readahead_fsblock(
	struct xfs_btree_cur	*cur,
	int			lr,
	struct xfs_btree_block	*block)
{
	int			rval = 0;
	struct xfs_mount	*mp = cur->bc_mp;
	xfs_fsblock_t		left = be64_to_cpu(block->bb_u.l.bb_leftsib);
	xfs_fsblock_t		right = be64_to_cpu(block->bb_u.l.bb_rightsib);
	int			rval = 0;

	if ((lr & XFS_BTCUR_LEFTRA) && left != NULLFSBLOCK) {
		xfs_btree_reada_bufl(cur->bc_mp, left, 1,
				     cur->bc_ops->buf_ops);
		xfs_buf_readahead(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, left),
				mp->m_bsize, cur->bc_ops->buf_ops);
		rval++;
	}

	if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLFSBLOCK) {
		xfs_btree_reada_bufl(cur->bc_mp, right, 1,
				     cur->bc_ops->buf_ops);
		xfs_buf_readahead(mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, right),
				mp->m_bsize, cur->bc_ops->buf_ops);
		rval++;
	}

@@ -960,20 +891,23 @@ xfs_btree_readahead_agblock(
	int			lr,
	struct xfs_btree_block	*block)
{
	int			rval = 0;
	struct xfs_mount	*mp = cur->bc_mp;
	xfs_agnumber_t		agno = cur->bc_ag.pag->pag_agno;
	xfs_agblock_t		left = be32_to_cpu(block->bb_u.s.bb_leftsib);
	xfs_agblock_t		right = be32_to_cpu(block->bb_u.s.bb_rightsib);

	int			rval = 0;

	if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.pag->pag_agno,
				     left, 1, cur->bc_ops->buf_ops);
		xfs_buf_readahead(mp->m_ddev_targp,
				XFS_AGB_TO_DADDR(mp, agno, left),
				mp->m_bsize, cur->bc_ops->buf_ops);
		rval++;
	}

	if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.pag->pag_agno,
				     right, 1, cur->bc_ops->buf_ops);
		xfs_buf_readahead(mp->m_ddev_targp,
				XFS_AGB_TO_DADDR(mp, agno, right),
				mp->m_bsize, cur->bc_ops->buf_ops);
		rval++;
	}

+0 −36
Original line number Diff line number Diff line
@@ -378,42 +378,6 @@ xfs_btree_offsets(
	int			*first,	/* output: first byte offset */
	int			*last);	/* output: last byte offset */

/*
 * Get a buffer for the block, return it read in.
 * Long-form addressing.
 */
int					/* error */
xfs_btree_read_bufl(
	struct xfs_mount	*mp,	/* file system mount point */
	struct xfs_trans	*tp,	/* transaction pointer */
	xfs_fsblock_t		fsbno,	/* file system block number */
	struct xfs_buf		**bpp,	/* buffer for fsbno */
	int			refval,	/* ref count value for buffer */
	const struct xfs_buf_ops *ops);

/*
 * Read-ahead the block, don't wait for it, don't return a buffer.
 * Long-form addressing.
 */
void					/* error */
xfs_btree_reada_bufl(
	struct xfs_mount	*mp,	/* file system mount point */
	xfs_fsblock_t		fsbno,	/* file system block number */
	xfs_extlen_t		count,	/* count of filesystem blocks */
	const struct xfs_buf_ops *ops);

/*
 * Read-ahead the block, don't wait for it, don't return a buffer.
 * Short-form addressing.
 */
void					/* error */
xfs_btree_reada_bufs(
	struct xfs_mount	*mp,	/* file system mount point */
	xfs_agnumber_t		agno,	/* allocation group number */
	xfs_agblock_t		agbno,	/* allocation group block number */
	xfs_extlen_t		count,	/* count of filesystem blocks */
	const struct xfs_buf_ops *ops);

/*
 * Initialise a new btree block header
 */
+31 −15
Original line number Diff line number Diff line
@@ -60,6 +60,11 @@ xfs_buf_submit(
	return __xfs_buf_submit(bp, !(bp->b_flags & XBF_ASYNC));
}

static inline bool xfs_buf_is_uncached(struct xfs_buf *bp)
{
	return bp->b_rhash_key == XFS_BUF_DADDR_NULL;
}

static inline int
xfs_buf_is_vmapped(
	struct xfs_buf	*bp)
@@ -996,29 +1001,27 @@ xfs_buf_hold(
	atomic_inc(&bp->b_hold);
}

/*
 * Release a hold on the specified buffer. If the hold count is 1, the buffer is
 * placed on LRU or freed (depending on b_lru_ref).
 */
void
xfs_buf_rele(
static void
xfs_buf_rele_uncached(
	struct xfs_buf		*bp)
{
	struct xfs_perag	*pag = bp->b_pag;
	bool			release;
	bool			freebuf = false;

	trace_xfs_buf_rele(bp, _RET_IP_);

	if (!pag) {
	ASSERT(list_empty(&bp->b_lru));
	if (atomic_dec_and_test(&bp->b_hold)) {
		xfs_buf_ioacct_dec(bp);
		xfs_buf_free(bp);
	}
		return;
}

static void
xfs_buf_rele_cached(
	struct xfs_buf		*bp)
{
	struct xfs_perag	*pag = bp->b_pag;
	bool			release;
	bool			freebuf = false;

	trace_xfs_buf_rele(bp, _RET_IP_);

	ASSERT(atomic_read(&bp->b_hold) > 0);

	/*
@@ -1086,6 +1089,19 @@ xfs_buf_rele(
		xfs_buf_free(bp);
}

/*
 * Release a hold on the specified buffer.
 */
void
xfs_buf_rele(
	struct xfs_buf		*bp)
{
	trace_xfs_buf_rele(bp, _RET_IP_);
	if (xfs_buf_is_uncached(bp))
		xfs_buf_rele_uncached(bp);
	else
		xfs_buf_rele_cached(bp);
}

/*
 *	Lock a buffer object, if it is not already locked.
+4 −2
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ xfs_iwalk_ichunk_ra(
	struct xfs_inobt_rec_incore	*irec)
{
	struct xfs_ino_geometry		*igeo = M_IGEO(mp);
	xfs_agnumber_t			agno = pag->pag_agno;
	xfs_agblock_t			agbno;
	struct blk_plug			plug;
	int				i;	/* inode chunk index */
@@ -112,8 +113,9 @@ xfs_iwalk_ichunk_ra(

		imask = xfs_inobt_maskn(i, igeo->inodes_per_cluster);
		if (imask & ~irec->ir_free) {
			xfs_btree_reada_bufs(mp, pag->pag_agno, agbno,
					igeo->blocks_per_cluster,
			xfs_buf_readahead(mp->m_ddev_targp,
					XFS_AGB_TO_DADDR(mp, agno, agbno),
					igeo->blocks_per_cluster * mp->m_bsize,
					&xfs_inode_buf_ops);
		}
		agbno += igeo->blocks_per_cluster;