xfs: pass xfs_buf lookup flags to xfs_*read_agi
authorDarrick J. Wong <djwong@kernel.org>
Mon, 15 Apr 2024 21:54:03 +0000 (14:54 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 15 Apr 2024 21:54:03 +0000 (14:54 -0700)
Allow callers to pass buffer lookup flags to xfs_read_agi and
xfs_ialloc_read_agi.  This will be used in the next patch to fix a
deadlock in the online fsck inode scanner.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_ialloc.h
fs/xfs/libxfs/xfs_ialloc_btree.c
fs/xfs/scrub/common.c
fs/xfs/scrub/fscounters.c
fs/xfs/scrub/iscan.c
fs/xfs/scrub/repair.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_iwalk.c
fs/xfs/xfs_log_recover.c

index dc1873f76bffd5528d15ba992c635519e761d21b..09fe9412eab49d049c8ac017975ad191a686500e 100644 (file)
@@ -194,7 +194,7 @@ xfs_initialize_perag_data(
                pag = xfs_perag_get(mp, index);
                error = xfs_alloc_read_agf(pag, NULL, 0, NULL);
                if (!error)
-                       error = xfs_ialloc_read_agi(pag, NULL, NULL);
+                       error = xfs_ialloc_read_agi(pag, NULL, 0, NULL);
                if (error) {
                        xfs_perag_put(pag);
                        return error;
@@ -931,7 +931,7 @@ xfs_ag_shrink_space(
        int                     error, err2;
 
        ASSERT(pag->pag_agno == mp->m_sb.sb_agcount - 1);
-       error = xfs_ialloc_read_agi(pag, *tpp, &agibp);
+       error = xfs_ialloc_read_agi(pag, *tpp, 0, &agibp);
        if (error)
                return error;
 
@@ -1062,7 +1062,7 @@ xfs_ag_extend_space(
 
        ASSERT(pag->pag_agno == pag->pag_mount->m_sb.sb_agcount - 1);
 
-       error = xfs_ialloc_read_agi(pag, tp, &bp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &bp);
        if (error)
                return error;
 
@@ -1119,7 +1119,7 @@ xfs_ag_get_geometry(
        int                     error;
 
        /* Lock the AG headers. */
-       error = xfs_ialloc_read_agi(pag, NULL, &agi_bp);
+       error = xfs_ialloc_read_agi(pag, NULL, 0, &agi_bp);
        if (error)
                return error;
        error = xfs_alloc_read_agf(pag, NULL, 0, &agf_bp);
index e5ac3e5430c4efe08c06eac3a9faee2de921532e..cb37f0007731f1248999e165bf8c7c85466e22e1 100644 (file)
@@ -1699,7 +1699,7 @@ xfs_dialloc_good_ag(
                return false;
 
        if (!xfs_perag_initialised_agi(pag)) {
-               error = xfs_ialloc_read_agi(pag, tp, NULL);
+               error = xfs_ialloc_read_agi(pag, tp, 0, NULL);
                if (error)
                        return false;
        }
@@ -1768,7 +1768,7 @@ xfs_dialloc_try_ag(
         * Then read in the AGI buffer and recheck with the AGI buffer
         * lock held.
         */
-       error = xfs_ialloc_read_agi(pag, *tpp, &agbp);
+       error = xfs_ialloc_read_agi(pag, *tpp, 0, &agbp);
        if (error)
                return error;
 
@@ -2286,7 +2286,7 @@ xfs_difree(
        /*
         * Get the allocation group header.
         */
-       error = xfs_ialloc_read_agi(pag, tp, &agbp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
        if (error) {
                xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
                        __func__, error);
@@ -2332,7 +2332,7 @@ xfs_imap_lookup(
        int                     error;
        int                     i;
 
-       error = xfs_ialloc_read_agi(pag, tp, &agbp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
        if (error) {
                xfs_alert(mp,
                        "%s: xfs_ialloc_read_agi() returned error %d, agno %d",
@@ -2675,6 +2675,7 @@ int
 xfs_read_agi(
        struct xfs_perag        *pag,
        struct xfs_trans        *tp,
+       xfs_buf_flags_t         flags,
        struct xfs_buf          **agibpp)
 {
        struct xfs_mount        *mp = pag->pag_mount;
@@ -2684,7 +2685,7 @@ xfs_read_agi(
 
        error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGI_DADDR(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0, agibpp, &xfs_agi_buf_ops);
+                       XFS_FSS_TO_BB(mp, 1), flags, agibpp, &xfs_agi_buf_ops);
        if (xfs_metadata_is_sick(error))
                xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
        if (error)
@@ -2704,6 +2705,7 @@ int
 xfs_ialloc_read_agi(
        struct xfs_perag        *pag,
        struct xfs_trans        *tp,
+       int                     flags,
        struct xfs_buf          **agibpp)
 {
        struct xfs_buf          *agibp;
@@ -2712,7 +2714,9 @@ xfs_ialloc_read_agi(
 
        trace_xfs_ialloc_read_agi(pag->pag_mount, pag->pag_agno);
 
-       error = xfs_read_agi(pag, tp, &agibp);
+       error = xfs_read_agi(pag, tp,
+                       (flags & XFS_IALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
+                       &agibp);
        if (error)
                return error;
 
index f1412183bb44bb2578c5929b67d019cfb123d717..b549627e3a6150a66b9381237bdd649599d4675a 100644 (file)
@@ -63,10 +63,11 @@ xfs_ialloc_log_agi(
        struct xfs_buf  *bp,            /* allocation group header buffer */
        uint32_t        fields);        /* bitmask of fields to log */
 
-int xfs_read_agi(struct xfs_perag *pag, struct xfs_trans *tp,
+int xfs_read_agi(struct xfs_perag *pag, struct xfs_trans *tp, xfs_buf_flags_t flags,
                struct xfs_buf **agibpp);
 int xfs_ialloc_read_agi(struct xfs_perag *pag, struct xfs_trans *tp,
-               struct xfs_buf **agibpp);
+               int flags, struct xfs_buf **agibpp);
+#define        XFS_IALLOC_FLAG_TRYLOCK (1U << 0)  /* use trylock for buffer locking */
 
 /*
  * Lookup a record by ino in the btree given by cur.
index cc661fca6ff5b9f12c664e34ee20a6eabe35ae27..42e9fd47f6c737a175a3b21afd2100e9921cf1b8 100644 (file)
@@ -745,7 +745,7 @@ xfs_finobt_count_blocks(
        struct xfs_btree_cur    *cur;
        int                     error;
 
-       error = xfs_ialloc_read_agi(pag, tp, &agbp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
        if (error)
                return error;
 
@@ -768,7 +768,7 @@ xfs_finobt_read_blocks(
        struct xfs_agi          *agi;
        int                     error;
 
-       error = xfs_ialloc_read_agi(pag, tp, &agbp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &agbp);
        if (error)
                return error;
 
index 47a20cf5205f00f9f99cb77c78fe36bcd6db6407..a27d33b6f4641f5ff00032c2fd572005033bda38 100644 (file)
@@ -445,7 +445,7 @@ xchk_perag_read_headers(
 {
        int                     error;
 
-       error = xfs_ialloc_read_agi(sa->pag, sc->tp, &sa->agi_bp);
+       error = xfs_ialloc_read_agi(sa->pag, sc->tp, 0, &sa->agi_bp);
        if (error && want_ag_read_header_failure(sc, XFS_SCRUB_TYPE_AGI))
                return error;
 
@@ -827,7 +827,7 @@ again:
         * in the iget cache miss path.
         */
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
-       error = xfs_ialloc_read_agi(pag, tp, agi_bpp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, agi_bpp);
        xfs_perag_put(pag);
        if (error)
                return error;
index d310737c88236758db20d8f67fb87b6939aaf8fa..da2f6729699dd43571833be2326a1044986bda7e 100644 (file)
@@ -85,7 +85,7 @@ xchk_fscount_warmup(
                        continue;
 
                /* Lock both AG headers. */
-               error = xfs_ialloc_read_agi(pag, sc->tp, &agi_bp);
+               error = xfs_ialloc_read_agi(pag, sc->tp, 0, &agi_bp);
                if (error)
                        break;
                error = xfs_alloc_read_agf(pag, sc->tp, 0, &agf_bp);
index ec3478bc505ef97fa664794290071c955f6191fe..66ba0fbd059e0a364616a66d134ae94ea433f35a 100644 (file)
@@ -281,7 +281,7 @@ xchk_iscan_advance(
                if (!pag)
                        return -ECANCELED;
 
-               ret = xfs_ialloc_read_agi(pag, sc->tp, &agi_bp);
+               ret = xfs_ialloc_read_agi(pag, sc->tp, 0, &agi_bp);
                if (ret)
                        goto out_pag;
 
index f43dce771cdd26e05d0c6ec0bcbf2fe3573784b5..443e62f7248183dfee70ec634fab08512102bcd7 100644 (file)
@@ -290,7 +290,7 @@ xrep_calc_ag_resblks(
                icount = pag->pagi_count;
        } else {
                /* Try to get the actual counters from disk. */
-               error = xfs_ialloc_read_agi(pag, NULL, &bp);
+               error = xfs_ialloc_read_agi(pag, NULL, 0, &bp);
                if (!error) {
                        icount = pag->pagi_count;
                        xfs_buf_relse(bp);
@@ -908,7 +908,7 @@ xrep_reinit_pagi(
        ASSERT(xfs_perag_initialised_agi(pag));
 
        clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
-       error = xfs_ialloc_read_agi(pag, sc->tp, &bp);
+       error = xfs_ialloc_read_agi(pag, sc->tp, 0, &bp);
        if (error)
                return error;
 
@@ -934,7 +934,7 @@ xrep_ag_init(
 
        ASSERT(!sa->pag);
 
-       error = xfs_ialloc_read_agi(pag, sc->tp, &sa->agi_bp);
+       error = xfs_ialloc_read_agi(pag, sc->tp, 0, &sa->agi_bp);
        if (error)
                return error;
 
index d55b42b2480d6c53f3367e4453cc69c5b80c6870..3e667a19b80bad36f72b1e3e0b58327672f15a6e 100644 (file)
@@ -2167,7 +2167,7 @@ xfs_iunlink(
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
 
        /* Get the agi buffer first.  It ensures lock ordering on the list. */
-       error = xfs_read_agi(pag, tp, &agibp);
+       error = xfs_read_agi(pag, tp, 0, &agibp);
        if (error)
                goto out;
 
@@ -2264,7 +2264,7 @@ xfs_iunlink_remove(
        trace_xfs_iunlink_remove(ip);
 
        /* Get the agi buffer first.  It ensures lock ordering on the list. */
-       error = xfs_read_agi(pag, tp, &agibp);
+       error = xfs_read_agi(pag, tp, 0, &agibp);
        if (error)
                return error;
 
@@ -3142,7 +3142,7 @@ retry:
 
                        pag = xfs_perag_get(mp,
                                        XFS_INO_TO_AGNO(mp, inodes[i]->i_ino));
-                       error = xfs_read_agi(pag, tp, &bp);
+                       error = xfs_read_agi(pag, tp, 0, &bp);
                        xfs_perag_put(pag);
                        if (error)
                                goto out_trans_cancel;
@@ -3814,7 +3814,7 @@ xfs_inode_reload_unlinked_bucket(
 
        /* Grab the first inode in the list */
        pag = xfs_perag_get(mp, agno);
-       error = xfs_ialloc_read_agi(pag, tp, &agibp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, &agibp);
        xfs_perag_put(pag);
        if (error)
                return error;
index 01b55f03a10260c4b58b31eacf06686b8a85d6fa..730c8d48da2827714127324cc5f8954465aef4c4 100644 (file)
@@ -268,7 +268,7 @@ xfs_iwalk_ag_start(
 
        /* Set up a fresh cursor and empty the inobt cache. */
        iwag->nr_recs = 0;
-       error = xfs_ialloc_read_agi(pag, tp, agi_bpp);
+       error = xfs_ialloc_read_agi(pag, tp, 0, agi_bpp);
        if (error)
                return error;
        *curpp = xfs_inobt_init_cursor(pag, tp, *agi_bpp);
@@ -386,7 +386,7 @@ xfs_iwalk_run_callbacks(
        }
 
        /* ...and recreate the cursor just past where we left off. */
-       error = xfs_ialloc_read_agi(iwag->pag, iwag->tp, agi_bpp);
+       error = xfs_ialloc_read_agi(iwag->pag, iwag->tp, 0, agi_bpp);
        if (error)
                return error;
        *curpp = xfs_inobt_init_cursor(iwag->pag, iwag->tp, *agi_bpp);
index 13f1d2e915405e3359211370ecf1c6e39209fbad..1b1f0a4cd49474fd1c1248a520c443236bddabe6 100644 (file)
@@ -2656,7 +2656,7 @@ xlog_recover_clear_agi_bucket(
        if (error)
                goto out_error;
 
-       error = xfs_read_agi(pag, tp, &agibp);
+       error = xfs_read_agi(pag, tp, 0, &agibp);
        if (error)
                goto out_abort;
 
@@ -2772,7 +2772,7 @@ xlog_recover_iunlink_ag(
        int                     bucket;
        int                     error;
 
-       error = xfs_read_agi(pag, NULL, &agibp);
+       error = xfs_read_agi(pag, NULL, 0, &agibp);
        if (error) {
                /*
                 * AGI is b0rked. Don't process it.