]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Mar 2025 07:42:16 +0000 (08:42 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Mar 2025 07:42:16 +0000 (08:42 +0100)
added patches:
xfs-give-xfs_extfree_intent-its-own-perag-reference.patch

queue-6.1/series
queue-6.1/xfs-give-xfs_extfree_intent-its-own-perag-reference.patch [new file with mode: 0644]

index ee88890d69c7fa7d449dd373c1d879450b0b56ae..12625a8cac77da445bde10f894f2dc2afc759a5c 100644 (file)
@@ -195,3 +195,4 @@ fs-ntfs3-change-new-sparse-cluster-processing.patch
 wifi-iwlwifi-mvm-ensure-offloading-tid-queue-exists.patch
 mm-migrate-fix-shmem-xarray-update-during-migration.patch
 block-bfq-fix-re-introduced-uaf-in-bic_set_bfqq.patch
+xfs-give-xfs_extfree_intent-its-own-perag-reference.patch
diff --git a/queue-6.1/xfs-give-xfs_extfree_intent-its-own-perag-reference.patch b/queue-6.1/xfs-give-xfs_extfree_intent-its-own-perag-reference.patch
new file mode 100644 (file)
index 0000000..c439a2e
--- /dev/null
@@ -0,0 +1,219 @@
+From f6b384631e1e3482c24e35b53adbd3da50e47e8f Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <djwong@kernel.org>
+Date: Tue, 11 Apr 2023 18:59:54 -0700
+Subject: xfs: give xfs_extfree_intent its own perag reference
+
+From: Darrick J. Wong <djwong@kernel.org>
+
+commit f6b384631e1e3482c24e35b53adbd3da50e47e8f upstream.
+
+Give the xfs_extfree_intent an passive reference to the perag structure
+data.  This reference will be used to enable scrub intent draining
+functionality in subsequent patches.  The space being freed must already
+be allocated, so we need to able to run even if the AG is being offlined
+or shrunk.
+
+Signed-off-by: Darrick J. Wong <djwong@kernel.org>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com>
+Acked-by: "Darrick J. Wong" <djwong@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+fs/xfs/libxfs/xfs_alloc.c |  7 +++--
+ fs/xfs/libxfs/xfs_alloc.c |    7 +++--
+ fs/xfs/libxfs/xfs_alloc.h |    4 +++
+ fs/xfs/xfs_extfree_item.c |   58 ++++++++++++++++++++++++++++++----------------
+ 3 files changed, 47 insertions(+), 22 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_alloc.c
++++ b/fs/xfs/libxfs/xfs_alloc.c
+@@ -2511,6 +2511,7 @@ xfs_defer_agfl_block(
+       trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
++      xfs_extent_free_get_group(mp, xefi);
+       xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &xefi->xefi_list);
+       return 0;
+ }
+@@ -2529,8 +2530,8 @@ __xfs_free_extent_later(
+       bool                            skip_discard)
+ {
+       struct xfs_extent_free_item     *xefi;
+-#ifdef DEBUG
+       struct xfs_mount                *mp = tp->t_mountp;
++#ifdef DEBUG
+       xfs_agnumber_t                  agno;
+       xfs_agblock_t                   agbno;
+@@ -2569,9 +2570,11 @@ __xfs_free_extent_later(
+       } else {
+               xefi->xefi_owner = XFS_RMAP_OWN_NULL;
+       }
+-      trace_xfs_bmap_free_defer(tp->t_mountp,
++      trace_xfs_bmap_free_defer(mp,
+                       XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
+                       XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
++
++      xfs_extent_free_get_group(mp, xefi);
+       xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &xefi->xefi_list);
+       return 0;
+ }
+--- a/fs/xfs/libxfs/xfs_alloc.h
++++ b/fs/xfs/libxfs/xfs_alloc.h
+@@ -226,10 +226,14 @@ struct xfs_extent_free_item {
+       uint64_t                xefi_owner;
+       xfs_fsblock_t           xefi_startblock;/* starting fs block number */
+       xfs_extlen_t            xefi_blockcount;/* number of blocks in extent */
++      struct xfs_perag        *xefi_pag;
+       unsigned int            xefi_flags;
+       enum xfs_ag_resv_type   xefi_agresv;
+ };
++void xfs_extent_free_get_group(struct xfs_mount *mp,
++              struct xfs_extent_free_item *xefi);
++
+ #define XFS_EFI_SKIP_DISCARD  (1U << 0) /* don't issue discard */
+ #define XFS_EFI_ATTR_FORK     (1U << 1) /* freeing attr fork block */
+ #define XFS_EFI_BMBT_BLOCK    (1U << 2) /* freeing bmap btree block */
+--- a/fs/xfs/xfs_extfree_item.c
++++ b/fs/xfs/xfs_extfree_item.c
+@@ -350,10 +350,7 @@ xfs_trans_free_extent(
+       struct xfs_owner_info           oinfo = { };
+       struct xfs_mount                *mp = tp->t_mountp;
+       struct xfs_extent               *extp;
+-      struct xfs_perag                *pag;
+       uint                            next_extent;
+-      xfs_agnumber_t                  agno = XFS_FSB_TO_AGNO(mp,
+-                                                      xefi->xefi_startblock);
+       xfs_agblock_t                   agbno = XFS_FSB_TO_AGBNO(mp,
+                                                       xefi->xefi_startblock);
+       int                             error;
+@@ -364,14 +361,12 @@ xfs_trans_free_extent(
+       if (xefi->xefi_flags & XFS_EFI_BMBT_BLOCK)
+               oinfo.oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK;
+-      trace_xfs_bmap_free_deferred(tp->t_mountp, agno, 0, agbno,
+-                      xefi->xefi_blockcount);
++      trace_xfs_bmap_free_deferred(tp->t_mountp, xefi->xefi_pag->pag_agno, 0,
++                      agbno, xefi->xefi_blockcount);
+-      pag = xfs_perag_get(mp, agno);
+-      error = __xfs_free_extent(tp, pag, agbno, xefi->xefi_blockcount,
+-                      &oinfo, xefi->xefi_agresv,
++      error = __xfs_free_extent(tp, xefi->xefi_pag, agbno,
++                      xefi->xefi_blockcount, &oinfo, xefi->xefi_agresv,
+                       xefi->xefi_flags & XFS_EFI_SKIP_DISCARD);
+-      xfs_perag_put(pag);
+       /*
+        * Mark the transaction dirty, even on error. This ensures the
+@@ -400,14 +395,13 @@ xfs_extent_free_diff_items(
+       const struct list_head          *a,
+       const struct list_head          *b)
+ {
+-      struct xfs_mount                *mp = priv;
+       struct xfs_extent_free_item     *ra;
+       struct xfs_extent_free_item     *rb;
+       ra = container_of(a, struct xfs_extent_free_item, xefi_list);
+       rb = container_of(b, struct xfs_extent_free_item, xefi_list);
+-      return  XFS_FSB_TO_AGNO(mp, ra->xefi_startblock) -
+-              XFS_FSB_TO_AGNO(mp, rb->xefi_startblock);
++
++      return ra->xefi_pag->pag_agno - rb->xefi_pag->pag_agno;
+ }
+ /* Log a free extent to the intent item. */
+@@ -466,6 +460,26 @@ xfs_extent_free_create_done(
+       return &xfs_trans_get_efd(tp, EFI_ITEM(intent), count)->efd_item;
+ }
++/* Take a passive ref to the AG containing the space we're freeing. */
++void
++xfs_extent_free_get_group(
++      struct xfs_mount                *mp,
++      struct xfs_extent_free_item     *xefi)
++{
++      xfs_agnumber_t                  agno;
++
++      agno = XFS_FSB_TO_AGNO(mp, xefi->xefi_startblock);
++      xefi->xefi_pag = xfs_perag_get(mp, agno);
++}
++
++/* Release a passive AG ref after some freeing work. */
++static inline void
++xfs_extent_free_put_group(
++      struct xfs_extent_free_item     *xefi)
++{
++      xfs_perag_put(xefi->xefi_pag);
++}
++
+ /* Process a free extent. */
+ STATIC int
+ xfs_extent_free_finish_item(
+@@ -480,6 +494,8 @@ xfs_extent_free_finish_item(
+       xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
+       error = xfs_trans_free_extent(tp, EFD_ITEM(done), xefi);
++
++      xfs_extent_free_put_group(xefi);
+       kmem_cache_free(xfs_extfree_item_cache, xefi);
+       return error;
+ }
+@@ -500,6 +516,8 @@ xfs_extent_free_cancel_item(
+       struct xfs_extent_free_item     *xefi;
+       xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
++
++      xfs_extent_free_put_group(xefi);
+       kmem_cache_free(xfs_extfree_item_cache, xefi);
+ }
+@@ -530,24 +548,21 @@ xfs_agfl_free_finish_item(
+       struct xfs_extent               *extp;
+       struct xfs_buf                  *agbp;
+       int                             error;
+-      xfs_agnumber_t                  agno;
+       xfs_agblock_t                   agbno;
+       uint                            next_extent;
+-      struct xfs_perag                *pag;
+       xefi = container_of(item, struct xfs_extent_free_item, xefi_list);
+       ASSERT(xefi->xefi_blockcount == 1);
+-      agno = XFS_FSB_TO_AGNO(mp, xefi->xefi_startblock);
+       agbno = XFS_FSB_TO_AGBNO(mp, xefi->xefi_startblock);
+       oinfo.oi_owner = xefi->xefi_owner;
+-      trace_xfs_agfl_free_deferred(mp, agno, 0, agbno, xefi->xefi_blockcount);
++      trace_xfs_agfl_free_deferred(mp, xefi->xefi_pag->pag_agno, 0, agbno,
++                      xefi->xefi_blockcount);
+-      pag = xfs_perag_get(mp, agno);
+-      error = xfs_alloc_read_agf(pag, tp, 0, &agbp);
++      error = xfs_alloc_read_agf(xefi->xefi_pag, tp, 0, &agbp);
+       if (!error)
+-              error = xfs_free_agfl_block(tp, agno, agbno, agbp, &oinfo);
+-      xfs_perag_put(pag);
++              error = xfs_free_agfl_block(tp, xefi->xefi_pag->pag_agno,
++                              agbno, agbp, &oinfo);
+       /*
+        * Mark the transaction dirty, even on error. This ensures the
+@@ -566,6 +581,7 @@ xfs_agfl_free_finish_item(
+       extp->ext_len = xefi->xefi_blockcount;
+       efdp->efd_next_extent++;
++      xfs_extent_free_put_group(xefi);
+       kmem_cache_free(xfs_extfree_item_cache, xefi);
+       return error;
+ }
+@@ -639,7 +655,9 @@ xfs_efi_item_recover(
+               fake.xefi_startblock = extp->ext_start;
+               fake.xefi_blockcount = extp->ext_len;
++              xfs_extent_free_get_group(mp, &fake);
+               error = xfs_trans_free_extent(tp, efdp, &fake);
++              xfs_extent_free_put_group(&fake);
+               if (error == -EFSCORRUPTED)
+                       XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
+                                       extp, sizeof(*extp));