Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 92ff7285 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: reflink find shared should take a transaction



Adapt _reflink_find_shared to take an optional transaction pointer.  The
inode scrubber code will need to decide (within transaction context) if
a file has shared blocks.  To avoid buffer deadlocks, we must pass the
tp through to this function's utility calls.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent 378f681c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -455,8 +455,8 @@ xfs_getbmap_adjust_shared(

	agno = XFS_FSB_TO_AGNO(mp, map->br_startblock);
	agbno = XFS_FSB_TO_AGBNO(mp, map->br_startblock);
	error = xfs_reflink_find_shared(mp, agno, agbno, map->br_blockcount,
			&ebno, &elen, true);
	error = xfs_reflink_find_shared(mp, NULL, agno, agbno,
			map->br_blockcount, &ebno, &elen, true);
	if (error)
		return error;

+8 −7
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@
int
xfs_reflink_find_shared(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	xfs_agnumber_t		agno,
	xfs_agblock_t		agbno,
	xfs_extlen_t		aglen,
@@ -166,18 +167,18 @@ xfs_reflink_find_shared(
	struct xfs_btree_cur	*cur;
	int			error;

	error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
	error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
	if (error)
		return error;

	cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL);
	cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL);

	error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
			find_end_of_shared);

	xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);

	xfs_buf_relse(agbp);
	xfs_trans_brelse(tp, agbp);
	return error;
}

@@ -217,7 +218,7 @@ xfs_reflink_trim_around_shared(
	agbno = XFS_FSB_TO_AGBNO(ip->i_mount, irec->br_startblock);
	aglen = irec->br_blockcount;

	error = xfs_reflink_find_shared(ip->i_mount, agno, agbno,
	error = xfs_reflink_find_shared(ip->i_mount, NULL, agno, agbno,
			aglen, &fbno, &flen, true);
	if (error)
		return error;
@@ -1373,8 +1374,8 @@ xfs_reflink_dirty_extents(
			agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock);
			aglen = map[1].br_blockcount;

			error = xfs_reflink_find_shared(mp, agno, agbno, aglen,
					&rbno, &rlen, true);
			error = xfs_reflink_find_shared(mp, NULL, agno, agbno,
					aglen, &rbno, &rlen, true);
			if (error)
				goto out;
			if (rbno == NULLAGBLOCK)
@@ -1445,7 +1446,7 @@ xfs_reflink_clear_inode_flag(
		agbno = XFS_FSB_TO_AGBNO(mp, map.br_startblock);
		aglen = map.br_blockcount;

		error = xfs_reflink_find_shared(mp, agno, agbno, aglen,
		error = xfs_reflink_find_shared(mp, *tpp, agno, agbno, aglen,
				&rbno, &rlen, false);
		if (error)
			return error;
+3 −3
Original line number Diff line number Diff line
@@ -20,9 +20,9 @@
#ifndef __XFS_REFLINK_H
#define __XFS_REFLINK_H 1

extern int xfs_reflink_find_shared(struct xfs_mount *mp, xfs_agnumber_t agno,
		xfs_agblock_t agbno, xfs_extlen_t aglen, xfs_agblock_t *fbno,
		xfs_extlen_t *flen, bool find_maximal);
extern int xfs_reflink_find_shared(struct xfs_mount *mp, struct xfs_trans *tp,
		xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t aglen,
		xfs_agblock_t *fbno, xfs_extlen_t *flen, bool find_maximal);
extern int xfs_reflink_trim_around_shared(struct xfs_inode *ip,
		struct xfs_bmbt_irec *irec, bool *shared, bool *trimmed);