Commit 816c330b authored by Dave Chinner's avatar Dave Chinner Committed by Carlos Maiolino
Browse files

xfs: factor out stale buffer item completion



The stale buffer item completion handling is currently only done
from BLI unpinning. We need to perform this function from where-ever
the last reference to the BLI is dropped, so first we need to
factor this code out into a helper.

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: default avatarCarlos Maiolino <cem@kernel.org>
parent d2fe5c4c
Loading
Loading
Loading
Loading
+37 −23
Original line number Diff line number Diff line
@@ -444,6 +444,42 @@ xfs_buf_item_pin(
	atomic_inc(&bip->bli_buf->b_pin_count);
}

/*
 * For a stale BLI, process all the necessary completions that must be
 * performed when the final BLI reference goes away. The buffer will be
 * referenced and locked here - we return to the caller with the buffer still
 * referenced and locked for them to finalise processing of the buffer.
 */
static void
xfs_buf_item_finish_stale(
	struct xfs_buf_log_item	*bip)
{
	struct xfs_buf		*bp = bip->bli_buf;
	struct xfs_log_item	*lip = &bip->bli_item;

	ASSERT(bip->bli_flags & XFS_BLI_STALE);
	ASSERT(xfs_buf_islocked(bp));
	ASSERT(bp->b_flags & XBF_STALE);
	ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
	ASSERT(list_empty(&lip->li_trans));
	ASSERT(!bp->b_transp);

	if (bip->bli_flags & XFS_BLI_STALE_INODE) {
		xfs_buf_item_done(bp);
		xfs_buf_inode_iodone(bp);
		ASSERT(list_empty(&bp->b_li_list));
		return;
	}

	/*
	 * We may or may not be on the AIL here, xfs_trans_ail_delete() will do
	 * the right thing regardless of the situation in which we are called.
	 */
	xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
	xfs_buf_item_relse(bip);
	ASSERT(bp->b_log_item == NULL);
}

/*
 * This is called to unpin the buffer associated with the buf log item which was
 * previously pinned with a call to xfs_buf_item_pin().  We enter this function
@@ -493,13 +529,6 @@ xfs_buf_item_unpin(
	}

	if (stale) {
		ASSERT(bip->bli_flags & XFS_BLI_STALE);
		ASSERT(xfs_buf_islocked(bp));
		ASSERT(bp->b_flags & XBF_STALE);
		ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
		ASSERT(list_empty(&lip->li_trans));
		ASSERT(!bp->b_transp);

		trace_xfs_buf_item_unpin_stale(bip);

		/*
@@ -510,22 +539,7 @@ xfs_buf_item_unpin(
		 * processing is complete.
		 */
		xfs_buf_rele(bp);

		/*
		 * If we get called here because of an IO error, we may or may
		 * not have the item on the AIL. xfs_trans_ail_delete() will
		 * take care of that situation. xfs_trans_ail_delete() drops
		 * the AIL lock.
		 */
		if (bip->bli_flags & XFS_BLI_STALE_INODE) {
			xfs_buf_item_done(bp);
			xfs_buf_inode_iodone(bp);
			ASSERT(list_empty(&bp->b_li_list));
		} else {
			xfs_trans_ail_delete(lip, SHUTDOWN_LOG_IO_ERROR);
			xfs_buf_item_relse(bip);
			ASSERT(bp->b_log_item == NULL);
		}
		xfs_buf_item_finish_stale(bip);
		xfs_buf_relse(bp);
		return;
	}