diff options
author | Darrick J. Wong <djwong@kernel.org> | 2023-11-22 20:13:03 +0100 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2023-12-07 03:45:15 +0100 |
commit | e70fb328d5277297ea2d9169a3a046de6412d777 (patch) | |
tree | f4359168cf1c5207c23c3594951a8a531475d49c /fs/xfs/xfs_extfree_item.c | |
parent | xfs: transfer recovered intent item ownership in ->iop_recover (diff) | |
download | linux-e70fb328d5277297ea2d9169a3a046de6412d777.tar.xz linux-e70fb328d5277297ea2d9169a3a046de6412d777.zip |
xfs: recreate work items when recovering intent items
Recreate work items for each xfs_defer_pending object when we are
recovering intent items.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/xfs/xfs_extfree_item.c')
-rw-r--r-- | fs/xfs/xfs_extfree_item.c | 49 |
1 files changed, 30 insertions, 19 deletions
diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index c9908fb33765..41108a0b60c9 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -651,6 +651,24 @@ xfs_efi_validate_ext( return xfs_verify_fsbext(mp, extp->ext_start, extp->ext_len); } +static inline void +xfs_efi_recover_work( + struct xfs_mount *mp, + struct xfs_defer_pending *dfp, + struct xfs_extent *extp) +{ + struct xfs_extent_free_item *xefi; + + xefi = kmem_cache_zalloc(xfs_extfree_item_cache, + GFP_KERNEL | __GFP_NOFAIL); + xefi->xefi_startblock = extp->ext_start; + xefi->xefi_blockcount = extp->ext_len; + xefi->xefi_agresv = XFS_AG_RESV_NONE; + xefi->xefi_owner = XFS_RMAP_OWN_UNKNOWN; + + xfs_defer_add_item(dfp, &xefi->xefi_list); +} + /* * Process an extent free intent item that was recovered from * the log. We need to free the extents that it describes. @@ -666,6 +684,7 @@ xfs_efi_item_recover( struct xfs_mount *mp = lip->li_log->l_mp; struct xfs_efd_log_item *efdp; struct xfs_trans *tp; + struct xfs_extent_free_item *fake; int i; int error = 0; bool requeue_only = false; @@ -683,6 +702,8 @@ xfs_efi_item_recover( sizeof(efip->efi_format)); return -EFSCORRUPTED; } + + xfs_efi_recover_work(mp, dfp, &efip->efi_format.efi_extents[i]); } resv = xlog_recover_resv(&M_RES(mp)->tr_itruncate); @@ -693,22 +714,11 @@ xfs_efi_item_recover( efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); xlog_recover_transfer_intent(tp, dfp); - for (i = 0; i < efip->efi_format.efi_nextents; i++) { - struct xfs_extent_free_item fake = { - .xefi_owner = XFS_RMAP_OWN_UNKNOWN, - .xefi_agresv = XFS_AG_RESV_NONE, - }; - struct xfs_extent *extp; - - extp = &efip->efi_format.efi_extents[i]; - - fake.xefi_startblock = extp->ext_start; - fake.xefi_blockcount = extp->ext_len; - + list_for_each_entry(fake, &dfp->dfp_work, xefi_list) { if (!requeue_only) { - xfs_extent_free_get_group(mp, &fake); - error = xfs_trans_free_extent(tp, efdp, &fake); - xfs_extent_free_put_group(&fake); + xfs_extent_free_get_group(mp, fake); + error = xfs_trans_free_extent(tp, efdp, fake); + xfs_extent_free_put_group(fake); } /* @@ -717,10 +727,10 @@ xfs_efi_item_recover( * run again later with a new transaction context. */ if (error == -EAGAIN || requeue_only) { - error = xfs_free_extent_later(tp, fake.xefi_startblock, - fake.xefi_blockcount, + error = xfs_free_extent_later(tp, fake->xefi_startblock, + fake->xefi_blockcount, &XFS_RMAP_OINFO_ANY_OWNER, - fake.xefi_agresv); + fake->xefi_agresv); if (!error) { requeue_only = true; continue; @@ -729,7 +739,8 @@ xfs_efi_item_recover( if (error == -EFSCORRUPTED) XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, - extp, sizeof(*extp)); + &efip->efi_format, + sizeof(efip->efi_format)); if (error) goto abort_error; |