Merge tag 'linux_kselftest-next-6.10-rc1-fixes' of git://git.kernel.org/pub/scm/linux...
[linux.git] / fs / xfs / xfs_extent_busy.c
index 56cfa1498571e3df52bf0f1b2fa3357c5d9a6eac..a73e7c73b664c6bd5bafffb494c1a84924508ab1 100644 (file)
@@ -518,35 +518,26 @@ fail:
        goto out;
 }
 
-STATIC void
+static bool
 xfs_extent_busy_clear_one(
-       struct xfs_mount        *mp,
        struct xfs_perag        *pag,
-       struct xfs_extent_busy  *busyp)
+       struct xfs_extent_busy  *busyp,
+       bool                    do_discard)
 {
        if (busyp->length) {
-               trace_xfs_extent_busy_clear(mp, busyp->agno, busyp->bno,
-                                               busyp->length);
+               if (do_discard &&
+                   !(busyp->flags & XFS_EXTENT_BUSY_SKIP_DISCARD)) {
+                       busyp->flags = XFS_EXTENT_BUSY_DISCARDED;
+                       return false;
+               }
+               trace_xfs_extent_busy_clear(pag->pag_mount, busyp->agno,
+                               busyp->bno, busyp->length);
                rb_erase(&busyp->rb_node, &pag->pagb_tree);
        }
 
        list_del_init(&busyp->list);
        kfree(busyp);
-}
-
-static void
-xfs_extent_busy_put_pag(
-       struct xfs_perag        *pag,
-       bool                    wakeup)
-               __releases(pag->pagb_lock)
-{
-       if (wakeup) {
-               pag->pagb_gen++;
-               wake_up_all(&pag->pagb_wait);
-       }
-
-       spin_unlock(&pag->pagb_lock);
-       xfs_perag_put(pag);
+       return true;
 }
 
 /*
@@ -560,32 +551,33 @@ xfs_extent_busy_clear(
        struct list_head        *list,
        bool                    do_discard)
 {
-       struct xfs_extent_busy  *busyp, *n;
-       struct xfs_perag        *pag = NULL;
-       xfs_agnumber_t          agno = NULLAGNUMBER;
-       bool                    wakeup = false;
-
-       list_for_each_entry_safe(busyp, n, list, list) {
-               if (busyp->agno != agno) {
-                       if (pag)
-                               xfs_extent_busy_put_pag(pag, wakeup);
-                       agno = busyp->agno;
-                       pag = xfs_perag_get(mp, agno);
-                       spin_lock(&pag->pagb_lock);
-                       wakeup = false;
-               }
+       struct xfs_extent_busy  *busyp, *next;
 
-               if (do_discard && busyp->length &&
-                   !(busyp->flags & XFS_EXTENT_BUSY_SKIP_DISCARD)) {
-                       busyp->flags = XFS_EXTENT_BUSY_DISCARDED;
-               } else {
-                       xfs_extent_busy_clear_one(mp, pag, busyp);
-                       wakeup = true;
-               }
-       }
+       busyp = list_first_entry_or_null(list, typeof(*busyp), list);
+       if (!busyp)
+               return;
 
-       if (pag)
-               xfs_extent_busy_put_pag(pag, wakeup);
+       do {
+               bool                    wakeup = false;
+               struct xfs_perag        *pag;
+
+               pag = xfs_perag_get(mp, busyp->agno);
+               spin_lock(&pag->pagb_lock);
+               do {
+                       next = list_next_entry(busyp, list);
+                       if (xfs_extent_busy_clear_one(pag, busyp, do_discard))
+                               wakeup = true;
+                       busyp = next;
+               } while (!list_entry_is_head(busyp, list, list) &&
+                        busyp->agno == pag->pag_agno);
+
+               if (wakeup) {
+                       pag->pagb_gen++;
+                       wake_up_all(&pag->pagb_wait);
+               }
+               spin_unlock(&pag->pagb_lock);
+               xfs_perag_put(pag);
+       } while (!list_entry_is_head(busyp, list, list));
 }
 
 /*
This page took 0.036117 seconds and 4 git commands to generate.