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

xfs: make xfs_*read_agf return EAGAIN to ALLOC_FLAG_TRYLOCK callers



Refactor xfs_read_agf and xfs_alloc_read_agf to return EAGAIN if the
caller passed TRYLOCK and we weren't able to get the lock; and change
the callers to recognize this.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
parent ee647f85
Loading
Loading
Loading
Loading
+14 −22
Original line number Diff line number Diff line
@@ -2502,12 +2502,11 @@ xfs_alloc_fix_freelist(

	if (!pag->pagf_init) {
		error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
		if (error)
		if (error) {
			/* Couldn't lock the AGF so skip this AG. */
			if (error == -EAGAIN)
				error = 0;
			goto out_no_agbp;
		if (!pag->pagf_init) {
			ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
			ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
			goto out_agbp_relse;
		}
	}

@@ -2533,11 +2532,10 @@ xfs_alloc_fix_freelist(
	 */
	if (!agbp) {
		error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
		if (error)
			goto out_no_agbp;
		if (!agbp) {
			ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
			ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
		if (error) {
			/* Couldn't lock the AGF so skip this AG. */
			if (error == -EAGAIN)
				error = 0;
			goto out_no_agbp;
		}
	}
@@ -2768,11 +2766,10 @@ xfs_alloc_pagf_init(
	xfs_buf_t		*bp;
	int			error;

	if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
		return error;
	if (bp)
	error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp);
	if (!error)
		xfs_trans_brelse(tp, bp);
	return 0;
	return error;
}

/*
@@ -2961,12 +2958,6 @@ xfs_read_agf(
	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
			XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
			XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
	/*
	 * Callers of xfs_read_agf() currently interpret a NULL bpp as EAGAIN
	 * and need to be converted to check for EAGAIN specifically.
	 */
	if (error == -EAGAIN)
		return 0;
	if (error)
		return error;

@@ -2992,14 +2983,15 @@ xfs_alloc_read_agf(

	trace_xfs_alloc_read_agf(mp, agno);

	/* We don't support trylock when freeing. */
	ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
			(XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK));
	ASSERT(agno != NULLAGNUMBER);
	error = xfs_read_agf(mp, tp, agno,
			(flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
			bpp);
	if (error)
		return error;
	if (!*bpp)
		return 0;
	ASSERT(!(*bpp)->b_error);

	agf = XFS_BUF_TO_AGF(*bpp);
+6 −5
Original line number Diff line number Diff line
@@ -3311,11 +3311,12 @@ xfs_bmap_longest_free_extent(
	pag = xfs_perag_get(mp, ag);
	if (!pag->pagf_init) {
		error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
		if (error)
			goto out;

		if (!pag->pagf_init) {
		if (error) {
			/* Couldn't lock the AGF, so skip this AG. */
			if (error == -EAGAIN) {
				*notinit = 1;
				error = 0;
			}
			goto out;
		}
	}
+5 −6
Original line number Diff line number Diff line
@@ -159,16 +159,15 @@ xfs_filestream_pick_ag(

		if (!pag->pagf_init) {
			err = xfs_alloc_pagf_init(mp, NULL, ag, trylock);
			if (err && !trylock) {
			if (err) {
				xfs_perag_put(pag);
				if (err != -EAGAIN)
					return err;
				/* Couldn't lock the AGF, skip this AG. */
				continue;
			}
		}

		/* Might fail sometimes during the 1st pass with trylock set. */
		if (!pag->pagf_init)
			goto next_ag;

		/* Keep track of the AG with the most free blocks. */
		if (pag->pagf_freeblks > maxfree) {
			maxfree = pag->pagf_freeblks;