]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
xfs: convert the ifork reap code to use xreap_state
authorDarrick J. Wong <djwong@kernel.org>
Tue, 8 Apr 2025 23:14:31 +0000 (16:14 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Fri, 5 Sep 2025 15:48:22 +0000 (08:48 -0700)
Convert the file fork reaping code to use struct xreap_state so that we
can reuse the dynamic state tracking code.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/scrub/reap.c

index 16bd298330a4ccccbba945aadaa8b0a6957c6d3b..33272729249f647912aba3df82cc76503f958296 100644 (file)
 struct xreap_state {
        struct xfs_scrub                *sc;
 
-       /* Reverse mapping owner and metadata reservation type. */
-       const struct xfs_owner_info     *oinfo;
-       enum xfs_ag_resv_type           resv;
+       union {
+               struct {
+                       /*
+                        * For AG blocks, this is reverse mapping owner and
+                        * metadata reservation type.
+                        */
+                       const struct xfs_owner_info     *oinfo;
+                       enum xfs_ag_resv_type           resv;
+               };
+               struct {
+                       /* For file blocks, this is the inode and fork. */
+                       struct xfs_inode                *ip;
+                       int                             whichfork;
+               };
+       };
 
        /* Number of invalidated buffers logged to the current transaction. */
        unsigned int                    nr_binval;
@@ -965,13 +977,12 @@ xrep_reap_metadir_fsblocks(
  */
 STATIC int
 xreap_bmapi_select(
-       struct xfs_scrub        *sc,
-       struct xfs_inode        *ip,
-       int                     whichfork,
+       struct xreap_state      *rs,
        struct xfs_bmbt_irec    *imap,
        bool                    *crosslinked)
 {
        struct xfs_owner_info   oinfo;
+       struct xfs_scrub        *sc = rs->sc;
        struct xfs_btree_cur    *cur;
        xfs_filblks_t           len = 1;
        xfs_agblock_t           bno;
@@ -985,7 +996,8 @@ xreap_bmapi_select(
        cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp,
                        sc->sa.pag);
 
-       xfs_rmap_ino_owner(&oinfo, ip->i_ino, whichfork, imap->br_startoff);
+       xfs_rmap_ino_owner(&oinfo, rs->ip->i_ino, rs->whichfork,
+                       imap->br_startoff);
        error = xfs_rmap_has_other_keys(cur, agbno, 1, &oinfo, crosslinked);
        if (error)
                goto out_cur;
@@ -1048,21 +1060,19 @@ xreap_buf_loggable(
  */
 STATIC int
 xreap_bmapi_binval(
-       struct xfs_scrub        *sc,
-       struct xfs_inode        *ip,
-       int                     whichfork,
+       struct xreap_state      *rs,
        struct xfs_bmbt_irec    *imap)
 {
+       struct xfs_scrub        *sc = rs->sc;
        struct xfs_mount        *mp = sc->mp;
        struct xfs_perag        *pag = sc->sa.pag;
-       int                     bmap_flags = xfs_bmapi_aflag(whichfork);
+       int                     bmap_flags = xfs_bmapi_aflag(rs->whichfork);
        xfs_fileoff_t           off;
        xfs_fileoff_t           max_off;
        xfs_extlen_t            scan_blocks;
        xfs_agblock_t           bno;
        xfs_agblock_t           agbno;
        xfs_agblock_t           agbno_next;
-       unsigned int            invalidated = 0;
        int                     error;
 
        /*
@@ -1089,7 +1099,7 @@ xreap_bmapi_binval(
                struct xfs_bmbt_irec    hmap;
                int                     nhmaps = 1;
 
-               error = xfs_bmapi_read(ip, off, max_off - off, &hmap,
+               error = xfs_bmapi_read(rs->ip, off, max_off - off, &hmap,
                                &nhmaps, bmap_flags);
                if (error)
                        return error;
@@ -1130,14 +1140,13 @@ xreap_bmapi_binval(
                                xfs_buf_stale(bp);
                                xfs_buf_relse(bp);
                        }
-                       invalidated++;
 
                        /*
                         * Stop invalidating if we've hit the limit; we should
                         * still have enough reservation left to free however
-                        * much of the mapping we've seen so far.
+                        * far we've gotten.
                         */
-                       if (invalidated > XREAP_MAX_BINVAL) {
+                       if (!xreap_inc_binval(rs)) {
                                imap->br_blockcount = agbno_next - bno;
                                goto out;
                        }
@@ -1159,12 +1168,11 @@ out:
  */
 STATIC int
 xrep_reap_bmapi_iter(
-       struct xfs_scrub                *sc,
-       struct xfs_inode                *ip,
-       int                             whichfork,
+       struct xreap_state              *rs,
        struct xfs_bmbt_irec            *imap,
        bool                            crosslinked)
 {
+       struct xfs_scrub                *sc = rs->sc;
        int                             error;
 
        if (crosslinked) {
@@ -1185,10 +1193,10 @@ xrep_reap_bmapi_iter(
                 * deferred log intents in this function to control the exact
                 * sequence of metadata updates.
                 */
-               xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap);
-               xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT,
+               xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap);
+               xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT,
                                -(int64_t)imap->br_blockcount);
-               xfs_rmap_unmap_extent(sc->tp, ip, whichfork, imap);
+               xfs_rmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap);
                return 0;
        }
 
@@ -1209,7 +1217,7 @@ xrep_reap_bmapi_iter(
         * transaction is full of logged buffer invalidations, so we need to
         * return early so that we can roll and retry.
         */
-       error = xreap_bmapi_binval(sc, ip, whichfork, imap);
+       error = xreap_bmapi_binval(rs, imap);
        if (error || imap->br_blockcount == 0)
                return error;
 
@@ -1218,8 +1226,8 @@ xrep_reap_bmapi_iter(
         * intents in this function to control the exact sequence of metadata
         * updates.
         */
-       xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap);
-       xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT,
+       xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap);
+       xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT,
                        -(int64_t)imap->br_blockcount);
        return xfs_free_extent_later(sc->tp, imap->br_startblock,
                        imap->br_blockcount, NULL, XFS_AG_RESV_NONE,
@@ -1232,18 +1240,17 @@ xrep_reap_bmapi_iter(
  */
 STATIC int
 xreap_ifork_extent(
-       struct xfs_scrub                *sc,
-       struct xfs_inode                *ip,
-       int                             whichfork,
+       struct xreap_state              *rs,
        struct xfs_bmbt_irec            *imap)
 {
+       struct xfs_scrub                *sc = rs->sc;
        xfs_agnumber_t                  agno;
        bool                            crosslinked;
        int                             error;
 
        ASSERT(sc->sa.pag == NULL);
 
-       trace_xreap_ifork_extent(sc, ip, whichfork, imap);
+       trace_xreap_ifork_extent(sc, rs->ip, rs->whichfork, imap);
 
        agno = XFS_FSB_TO_AGNO(sc->mp, imap->br_startblock);
        sc->sa.pag = xfs_perag_get(sc->mp, agno);
@@ -1258,11 +1265,11 @@ xreap_ifork_extent(
         * Decide the fate of the blocks at the beginning of the mapping, then
         * update the mapping to use it with the unmap calls.
         */
-       error = xreap_bmapi_select(sc, ip, whichfork, imap, &crosslinked);
+       error = xreap_bmapi_select(rs, imap, &crosslinked);
        if (error)
                goto out_agf;
 
-       error = xrep_reap_bmapi_iter(sc, ip, whichfork, imap, crosslinked);
+       error = xrep_reap_bmapi_iter(rs, imap, crosslinked);
        if (error)
                goto out_agf;
 
@@ -1286,6 +1293,12 @@ xrep_reap_ifork(
        struct xfs_inode        *ip,
        int                     whichfork)
 {
+       struct xreap_state      rs = {
+               .sc             = sc,
+               .ip             = ip,
+               .whichfork      = whichfork,
+               .max_binval     = XREAP_MAX_BINVAL,
+       };
        xfs_fileoff_t           off = 0;
        int                     bmap_flags = xfs_bmapi_aflag(whichfork);
        int                     error;
@@ -1313,13 +1326,14 @@ xrep_reap_ifork(
                 * can in a single transaction.
                 */
                if (xfs_bmap_is_real_extent(&imap)) {
-                       error = xreap_ifork_extent(sc, ip, whichfork, &imap);
+                       error = xreap_ifork_extent(&rs, &imap);
                        if (error)
                                return error;
 
                        error = xfs_defer_finish(&sc->tp);
                        if (error)
                                return error;
+                       xreap_defer_finish_reset(&rs);
                }
 
                off = imap.br_startoff + imap.br_blockcount;