xfs: grab the per-ag structure whenever relevant
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 30 May 2018 05:24:44 +0000 (22:24 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 30 May 2018 15:03:14 +0000 (08:03 -0700)
Grab and hold the per-AG data across a scrub run whenever relevant.
This helps us avoid repeated trips through rcu and the radix tree
in the repair code.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
fs/xfs/scrub/common.c
fs/xfs/scrub/common.h
fs/xfs/scrub/scrub.h

index 518bff2..d3e5adc 100644 (file)
@@ -541,6 +541,10 @@ xfs_scrub_ag_free(
                xfs_trans_brelse(sc->tp, sa->agi_bp);
                sa->agi_bp = NULL;
        }
+       if (sa->pag) {
+               xfs_perag_put(sa->pag);
+               sa->pag = NULL;
+       }
        sa->agno = NULLAGNUMBER;
 }
 
@@ -568,6 +572,19 @@ xfs_scrub_ag_init(
        return xfs_scrub_ag_btcur_init(sc, sa);
 }
 
+/*
+ * Grab the per-ag structure if we haven't already gotten it.  Teardown of the
+ * xfs_scrub_ag will release it for us.
+ */
+void
+xfs_scrub_perag_get(
+       struct xfs_mount        *mp,
+       struct xfs_scrub_ag     *sa)
+{
+       if (!sa->pag)
+               sa->pag = xfs_perag_get(mp, sa->agno);
+}
+
 /* Per-scrubber setup functions */
 
 /*
index a660087..fbb91a7 100644 (file)
@@ -123,6 +123,7 @@ xfs_scrub_setup_quota(struct xfs_scrub_context *sc, struct xfs_inode *ip)
 void xfs_scrub_ag_free(struct xfs_scrub_context *sc, struct xfs_scrub_ag *sa);
 int xfs_scrub_ag_init(struct xfs_scrub_context *sc, xfs_agnumber_t agno,
                      struct xfs_scrub_ag *sa);
+void xfs_scrub_perag_get(struct xfs_mount *mp, struct xfs_scrub_ag *sa);
 int xfs_scrub_ag_read_headers(struct xfs_scrub_context *sc, xfs_agnumber_t agno,
                              struct xfs_buf **agi, struct xfs_buf **agf,
                              struct xfs_buf **agfl);
index 2f89a84..636424d 100644 (file)
@@ -51,6 +51,7 @@ struct xfs_scrub_meta_ops {
 /* Buffer pointers and btree cursors for an entire AG. */
 struct xfs_scrub_ag {
        xfs_agnumber_t                  agno;
+       struct xfs_perag                *pag;
 
        /* AG btree roots */
        struct xfs_buf                  *agf_bp;