From: Greg Kroah-Hartman Date: Fri, 28 Mar 2025 07:42:16 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v6.1.132~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a0a81baae0d717584d53a5aae1d8b1824324e8e8;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: xfs-give-xfs_extfree_intent-its-own-perag-reference.patch --- diff --git a/queue-6.1/series b/queue-6.1/series index ee88890d69..12625a8cac 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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 index 0000000000..c439a2ed76 --- /dev/null +++ b/queue-6.1/xfs-give-xfs_extfree_intent-its-own-perag-reference.patch @@ -0,0 +1,219 @@ +From f6b384631e1e3482c24e35b53adbd3da50e47e8f Mon Sep 17 00:00:00 2001 +From: "Darrick J. Wong" +Date: Tue, 11 Apr 2023 18:59:54 -0700 +Subject: xfs: give xfs_extfree_intent its own perag reference + +From: Darrick J. Wong + +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 +Reviewed-by: Dave Chinner +Signed-off-by: Leah Rumancik +Acked-by: "Darrick J. Wong" +Signed-off-by: Greg Kroah-Hartman +--- +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));