]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - repair/rmap.c
xfs: perags need atomic operational state
[thirdparty/xfsprogs-dev.git] / repair / rmap.c
index 51691fcceaae040a97963d532bf5f00e0066914c..9013daa2ecd61fdbd7efa6475260e0b9ced38953 100644 (file)
@@ -551,13 +551,15 @@ rmap_store_ag_btree_rec(
                if (error)
                        goto err_slab;
 
-               error = -libxfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
-               if (error)
+               pag = libxfs_perag_get(mp, agno);
+               error = -libxfs_alloc_read_agf(pag, tp, 0, &agbp);
+               if (error) {
+                       libxfs_perag_put(pag);
                        goto err_trans;
+               }
 
                ASSERT(XFS_RMAP_NON_INODE_OWNER(rm_rec->rm_owner));
                oinfo.oi_owner = rm_rec->rm_owner;
-               pag = libxfs_perag_get(mp, agno);
                error = -libxfs_rmap_alloc(tp, agbp, pag, rm_rec->rm_startblock,
                                rm_rec->rm_blockcount, &oinfo);
                libxfs_perag_put(pag);
@@ -732,6 +734,8 @@ refcount_emit(
        rlrec.rc_startblock = agbno;
        rlrec.rc_blockcount = len;
        rlrec.rc_refcount = REFCOUNT_CLAMP(nr_rmaps);
+       rlrec.rc_domain = XFS_REFC_DOMAIN_SHARED;
+
        error = slab_add(rlslab, &rlrec);
        if (error)
                do_error(
@@ -995,21 +999,21 @@ rmaps_verify_btree(
                return;
        }
 
-       error = -libxfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
+       pag = libxfs_perag_get(mp, agno);
+       error = -libxfs_alloc_read_agf(pag, NULL, 0, &agbp);
        if (error) {
                do_warn(_("Could not read AGF %u to check rmap btree.\n"),
                                agno);
-               goto err;
+               goto err_pag;
        }
 
        /* Leave the per-ag data "uninitialized" since we rewrite it later */
-       pag = libxfs_perag_get(mp, agno);
-       pag->pagf_init = 0;
+       clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
 
        bt_cur = libxfs_rmapbt_init_cursor(mp, NULL, agbp, pag);
        if (!bt_cur) {
                do_warn(_("Not enough memory to check reverse mappings.\n"));
-               goto err;
+               goto err_agf;
        }
 
        rm_rec = pop_slab_cursor(rm_cur);
@@ -1019,7 +1023,7 @@ rmaps_verify_btree(
                        do_warn(
 _("Could not read reverse-mapping record for (%u/%u).\n"),
                                        agno, rm_rec->rm_startblock);
-                       goto err;
+                       goto err_cur;
                }
 
                /*
@@ -1035,7 +1039,7 @@ _("Could not read reverse-mapping record for (%u/%u).\n"),
                                do_warn(
 _("Could not read reverse-mapping record for (%u/%u).\n"),
                                                agno, rm_rec->rm_startblock);
-                               goto err;
+                               goto err_cur;
                        }
                }
                if (!have) {
@@ -1086,13 +1090,12 @@ next_loop:
                rm_rec = pop_slab_cursor(rm_cur);
        }
 
-err:
-       if (bt_cur)
-               libxfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR);
-       if (pag)
-               libxfs_perag_put(pag);
-       if (agbp)
-               libxfs_buf_relse(agbp);
+err_cur:
+       libxfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR);
+err_agf:
+       libxfs_buf_relse(agbp);
+err_pag:
+       libxfs_perag_put(pag);
        free_slab_cursor(&rm_cur);
 }
 
@@ -1370,33 +1373,34 @@ check_refcounts(
                return;
        }
 
-       error = -libxfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
+       pag = libxfs_perag_get(mp, agno);
+       error = -libxfs_alloc_read_agf(pag, NULL, 0, &agbp);
        if (error) {
                do_warn(_("Could not read AGF %u to check refcount btree.\n"),
                                agno);
-               goto err;
+               goto err_pag;
        }
 
        /* Leave the per-ag data "uninitialized" since we rewrite it later */
-       pag = libxfs_perag_get(mp, agno);
-       pag->pagf_init = 0;
+       clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
 
        bt_cur = libxfs_refcountbt_init_cursor(mp, NULL, agbp, pag);
        if (!bt_cur) {
                do_warn(_("Not enough memory to check refcount data.\n"));
-               goto err;
+               goto err_agf;
        }
 
        rl_rec = pop_slab_cursor(rl_cur);
        while (rl_rec) {
                /* Look for a refcount record in the btree */
                error = -libxfs_refcount_lookup_le(bt_cur,
-                               rl_rec->rc_startblock, &have);
+                               XFS_REFC_DOMAIN_SHARED, rl_rec->rc_startblock,
+                               &have);
                if (error) {
                        do_warn(
 _("Could not read reference count record for (%u/%u).\n"),
                                        agno, rl_rec->rc_startblock);
-                       goto err;
+                       goto err_cur;
                }
                if (!have) {
                        do_warn(
@@ -1411,7 +1415,7 @@ _("Missing reference count record for (%u/%u) len %u count %u\n"),
                        do_warn(
 _("Could not read reference count record for (%u/%u).\n"),
                                        agno, rl_rec->rc_startblock);
-                       goto err;
+                       goto err_cur;
                }
                if (!i) {
                        do_warn(
@@ -1422,26 +1426,31 @@ _("Missing reference count record for (%u/%u) len %u count %u\n"),
                }
 
                /* Compare each refcount observation against the btree's */
-               if (tmp.rc_startblock != rl_rec->rc_startblock ||
+               if (tmp.rc_domain != rl_rec->rc_domain ||
+                   tmp.rc_startblock != rl_rec->rc_startblock ||
                    tmp.rc_blockcount != rl_rec->rc_blockcount ||
-                   tmp.rc_refcount != rl_rec->rc_refcount)
+                   tmp.rc_refcount != rl_rec->rc_refcount) {
+                       unsigned int    start;
+
+                       start = xfs_refcount_encode_startblock(
+                                       tmp.rc_startblock, tmp.rc_domain);
+
                        do_warn(
 _("Incorrect reference count: saw (%u/%u) len %u nlinks %u; should be (%u/%u) len %u nlinks %u\n"),
-                               agno, tmp.rc_startblock, tmp.rc_blockcount,
+                               agno, start, tmp.rc_blockcount,
                                tmp.rc_refcount, agno, rl_rec->rc_startblock,
                                rl_rec->rc_blockcount, rl_rec->rc_refcount);
+               }
 next_loop:
                rl_rec = pop_slab_cursor(rl_cur);
        }
 
-err:
-       if (bt_cur)
-               libxfs_btree_del_cursor(bt_cur, error ? XFS_BTREE_ERROR :
-                                                       XFS_BTREE_NOERROR);
-       if (pag)
-               libxfs_perag_put(pag);
-       if (agbp)
-               libxfs_buf_relse(agbp);
+err_cur:
+       libxfs_btree_del_cursor(bt_cur, error);
+err_agf:
+       libxfs_buf_relse(agbp);
+err_pag:
+       libxfs_perag_put(pag);
        free_slab_cursor(&rl_cur);
 }