]> www.infradead.org Git - users/hch/xfs.git/commitdiff
FOLD: keep the code for stale buffers in a single place in xfs_buf_item_release shutdown-deadlock-split
authorChristoph Hellwig <hch@lst.de>
Fri, 23 May 2025 05:01:29 +0000 (07:01 +0200)
committerChristoph Hellwig <hch@lst.de>
Fri, 23 May 2025 05:04:31 +0000 (07:04 +0200)
Keep the stale buffer handling together to make it easier to explain and
easier to follow.

fs/xfs/xfs_buf_item.c

index 37627a30712eeb6ef3d7c0010959cf4219b17ff4..066923a66203a7d5e6e10bad98e53c068f42d766 100644 (file)
@@ -713,21 +713,27 @@ xfs_buf_item_release(
        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
@@ -752,17 +758,8 @@ xfs_buf_item_release(
 
        /* 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