bp->b_transp = NULL;
bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD | XFS_BLI_ORDERED);
+ /*
+ * Stale buffer completion frees the BLI, unlocks and releases the
+ * buffer. Neither the BLI or buffer are safe to reference after this
+ * call, so there's nothing more we need to do here.
+ *
+ * If we get here with a stale buffer and references to the BLI still
+ * remaining, we must not unlock the buffer as we've handed the lock
+ * context to the last BLI reference to process.
+ */
+ if (stale) {
+ if (atomic_dec_and_test(&bip->bli_refcount))
+ xfs_buf_item_finish_stale(bp);
+ return;
+ }
+
/*
* If this is the last reference to the BLI, we must clean it up
* before freeing it and releasing the buffer attached to it.
*/
if (atomic_dec_and_test(&bip->bli_refcount)) {
- if (stale) {
- /*
- * Stale buffer completion frees the BLI, unlocks and
- * releases the buffer. Neither the BLI or buffer are
- * safe to reference after this call, so there's nothing
- * more we need to do here.
- */
- xfs_buf_item_finish_stale(bp);
- return;
- } else if (aborted || xlog_is_shutdown(lip->li_log)) {
+ if (aborted || xlog_is_shutdown(lip->li_log)) {
/*
* Dirty or clean, aborted items are done and need to be
* removed from the AIL and released. This frees the
/* Not safe to reference the BLI from here */
- /*
- * If we get here with a stale buffer, there are references to the BLI
- * still remaining. We mus tnot unlock the buffer in this case as we've
- * handed the lock context to the last BLI reference to process.
- *
- * Hence if the buffer is stale or the transaction owner wants the
- * buffer to remain locked across the commit call, do not release it.
- */
- if (hold || stale)
- return;
- xfs_buf_relse(bp);
+ if (!hold)
+ xfs_buf_relse(bp);
}
STATIC void