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: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
Dave Chinner 2025-06-26 08:48:59 +10:00 committed by Carlos Maiolino
parent d2fe5c4c8d
commit 816c330b60

View File

@ -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;
}