diff options
Diffstat (limited to 'fs/xfs/scrub/reap.c')
-rw-r--r-- | fs/xfs/scrub/reap.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/fs/xfs/scrub/reap.c b/fs/xfs/scrub/reap.c index 3da372bc6eaa..79d43b9448a3 100644 --- a/fs/xfs/scrub/reap.c +++ b/fs/xfs/scrub/reap.c @@ -20,6 +20,7 @@ #include "xfs_ialloc_btree.h" #include "xfs_rmap.h" #include "xfs_rmap_btree.h" +#include "xfs_refcount.h" #include "xfs_refcount_btree.h" #include "xfs_extent_busy.h" #include "xfs_ag.h" @@ -313,6 +314,14 @@ xreap_agextent( trace_xreap_dispose_unmap_extent(sc->sa.pag, agbno, *aglenp); rs->force_roll = true; + if (rs->oinfo == &XFS_RMAP_OINFO_COW) { + /* + * If we're unmapping CoW staging extents, remove the + * records from the refcountbt as well. + */ + xfs_refcount_free_cow_extent(sc->tp, fsbno, *aglenp); + return 0; + } return xfs_rmap_free(sc->tp, sc->sa.agf_bp, sc->sa.pag, agbno, *aglenp, rs->oinfo); } @@ -331,6 +340,22 @@ xreap_agextent( return 0; } + /* + * If we're getting rid of CoW staging extents, use deferred work items + * to remove the refcountbt records (which removes the rmap records) + * and free the extent. We're not worried about the system going down + * here because log recovery walks the refcount btree to clean out the + * CoW staging extents. + */ + if (rs->oinfo == &XFS_RMAP_OINFO_COW) { + ASSERT(rs->resv == XFS_AG_RESV_NONE); + + rs->force_roll = true; + xfs_refcount_free_cow_extent(sc->tp, fsbno, *aglenp); + __xfs_free_extent_later(sc->tp, fsbno, *aglenp, NULL, true); + return 0; + } + switch (rs->resv) { case XFS_AG_RESV_AGFL: ASSERT(*aglenp == 1); |