]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
repair: factor out a ensure_rtgroup_file helper
authorChristoph Hellwig <hch@lst.de>
Wed, 10 Jul 2024 07:35:23 +0000 (09:35 +0200)
committerChristoph Hellwig <hch@lst.de>
Wed, 10 Jul 2024 13:51:42 +0000 (15:51 +0200)
The code to relink/rebuŃ–ld the rtrmap and rtrefcount inodes is
almost entirely duplicated.  Add a common helper for them, which
will also be useful if/when we add more per-rtg inodes.

Signed-off-by: Christoph Hellwig <hch@lst.de>
repair/phase6.c
repair/rmap.h
repair/rtrefcount_repair.c
repair/rtrmap_repair.c

index f6a85c577802c4c0f4d6380a40f94624f659b3bd..f0d8ded8451243003d5c1048188c4f5b516c0363 100644 (file)
@@ -882,36 +882,31 @@ ensure_imeta_dirpath(
 }
 
 static void
-ensure_rtgroup_rmapbt(
+ensure_rtgroup_file(
        struct xfs_rtgroup      *rtg,
-       xfs_filblks_t           est_fdblocks)
+       xfs_ino_t               ino,
+       struct xfs_imeta_path   *path,
+       const char              *name,
+       int                     (*create)(struct xfs_imeta_update *upd),
+       void                    (*populate)(struct xfs_rtgroup *rtg,
+                                           struct xfs_inode *ip,
+                                           void *private),
+       void                    *private)
 {
-       struct xfs_imeta_update upd = { };
        struct xfs_mount        *mp = rtg->rtg_mount;
-       struct xfs_imeta_path   *path;
-       xfs_ino_t               ino;
+       struct xfs_imeta_update upd = { };
        int                     error;
 
-       if (!xfs_has_rtrmapbt(mp))
-               return;
-
-       ino = rtgroup_rmap_ino(rtg);
        if (no_modify) {
                if (ino == NULLFSINO)
-                       do_warn(_("would reset rtgroup %u rmap btree\n"),
-                                       rtg->rtg_rgno);
+                       do_warn(_("would reset rtgroup %u %s btree\n"),
+                               rtg->rtg_rgno, name);
                return;
        }
 
        if (ino == NULLFSINO)
-               do_warn(_("resetting rtgroup %u rmap btree\n"),
-                               rtg->rtg_rgno);
-
-       path = xfs_rtrmapbt_create_path(mp, rtg->rtg_rgno);
-       if (!path)
-               do_error(
- _("Couldn't create rtgroup %u rmap file path\n"),
-                               rtg->rtg_rgno);
+               do_warn(_("resetting rtgroup %u %s btree\n"),
+                       rtg->rtg_rgno, name);
 
        error = ensure_imeta_dirpath(mp, path);
        if (error)
@@ -925,21 +920,21 @@ ensure_rtgroup_rmapbt(
                /*
                 * We're still hanging on to our old inode pointer, so grab it
                 * and reconnect it to the metadata directory tree.  If it
-                * can't be grabbed, create a new rtrmap file.
+                * can't be grabbed, create a new file.
                 */
                error = -libxfs_trans_alloc_empty(mp, &tp);
                if (error)
                        do_error(
- _("Couldn't allocate transaction to iget rtgroup %u rmap inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno, (unsigned long long)ino,
-                                       error);
+ _("Couldn't allocate transaction to iget rtgroup %u %s inode 0x%llx, error %d\n"),
+                               rtg->rtg_rgno, name, (unsigned long long)ino,
+                               error);
                error = -libxfs_imeta_iget(tp, ino, S_IFREG, &upd.ip);
                libxfs_trans_cancel(tp);
                if (error) {
                        do_warn(
- _("Couldn't iget rtgroup %u rmap inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno, (unsigned long long)ino,
-                                       error);
+ _("Couldn't iget rtgroup %u %s inode 0x%llx, error %d\n"),
+                               rtg->rtg_rgno, name, (unsigned long long)ino,
+                               error);
                        goto zap;
                }
 
@@ -953,16 +948,15 @@ ensure_rtgroup_rmapbt(
                error = -libxfs_imeta_start_link(mp, path, upd.ip, &upd);
                if (error)
                        do_error(
- _("Couldn't grab resources to reconnect rtgroup %u rmapbt, error %d\n"),
-                                       rtg->rtg_rgno, error);
+ _("Couldn't grab resources to reconnect rtgroup %u %s, error %d\n"),
+                               rtg->rtg_rgno, name, error);
 
                error = -libxfs_imeta_link(&upd);
                if (error)
                        do_error(
- _("Failed to link rtgroup %u rmapbt inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno,
-                                       (unsigned long long)upd.ip->i_ino,
-                                       error);
+ _("Failed to link rtgroup %u %s inode 0x%llx, error %d\n"),
+                               rtg->rtg_rgno, name,
+                               (unsigned long long)upd.ip->i_ino, error);
 
                /* Reset the link count to something sane. */
                set_nlink(VFS_I(upd.ip), 1);
@@ -970,20 +964,20 @@ ensure_rtgroup_rmapbt(
        } else {
 zap:
                /*
-                * The rtrmap inode was bad or gone, so just make a new one
-                * and give our reference to the rtgroup structure.
+                * The inode was bad or gone, so just make a new one and give
+                * our reference to the rtgroup structure.
                 */
                error = -libxfs_imeta_start_create(mp, path, &upd);
                if (error)
                        do_error(
- _("Couldn't grab resources to recreate rtgroup %u rmapbt, error %d\n"),
-                                       rtg->rtg_rgno, error);
+ _("Couldn't grab resources to recreate rtgroup %u %s, error %d\n"),
+                               rtg->rtg_rgno, name, error);
 
-               error = -libxfs_rtrmapbt_create(&upd);
+               error = -create(&upd);
                if (error)
                        do_error(
- _("Couldn't create rtgroup %u rmap inode, error %d\n"),
-                                       rtg->rtg_rgno, error);
+ _("Couldn't create rtgroup %u %s inode, error %d\n"),
+                               rtg->rtg_rgno, name, error);
        }
 
        /* Mark the inode in use. */
@@ -993,148 +987,59 @@ zap:
        error = -libxfs_imeta_commit(&upd);
        if (error)
                do_error(
- _("Couldn't commit new rtgroup %u rmap inode %llu, error %d\n"),
-                               rtg->rtg_rgno,
-                               (unsigned long long)upd.ip->i_ino,
-                               error);
+ _("Couldn't commit new rtgroup %u %s inode %llu, error %d\n"),
+                       rtg->rtg_rgno, name, (unsigned long long)upd.ip->i_ino,
+                       error);
 
-       /* Copy our incore rmap data to the ondisk rmap inode. */
-       error = populate_rtgroup_rmapbt(rtg, upd.ip, est_fdblocks);
-       if (error)
-               do_error(
- _("rtgroup %u rmap btree could not be rebuilt, error %d\n"),
-                               rtg->rtg_rgno, error);
+       populate(rtg, upd.ip, private);
 
-       libxfs_imeta_free_path(path);
        libxfs_irele(upd.ip);
 }
 
 static void
-ensure_rtgroup_refcountbt(
+ensure_rtgroup_rmapbt(
        struct xfs_rtgroup      *rtg,
        xfs_filblks_t           est_fdblocks)
 {
-       struct xfs_imeta_update upd = { };
-       struct xfs_mount        *mp = rtg->rtg_mount;
        struct xfs_imeta_path   *path;
-       xfs_ino_t               ino;
-       int                     error;
 
-       if (!xfs_has_rtreflink(mp))
+       if (!xfs_has_rtrmapbt(rtg->rtg_mount))
                return;
 
-       ino = rtgroup_refcount_ino(rtg);
-       if (no_modify) {
-               if (ino == NULLFSINO)
-                       do_warn(_("would reset rtgroup %u refcount btree\n"),
-                                       rtg->rtg_rgno);
-               return;
-       }
-
-       if (ino == NULLFSINO)
-               do_warn(_("resetting rtgroup %u refcount btree\n"),
-                               rtg->rtg_rgno);
-
-       path = xfs_rtrefcountbt_create_path(mp, rtg->rtg_rgno);
+       path = xfs_rtrmapbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
        if (!path)
                do_error(
- _("Couldn't create rtgroup %u refcount btree file path\n"), rtg->rtg_rgno);
-
-       error = ensure_imeta_dirpath(mp, path);
-       if (error)
-               do_error(
- _("Couldn't create rtgroup %u metadata directory, error %d\n"),
-                               rtg->rtg_rgno, error);
-
-       if (ino != NULLFSINO) {
-               struct xfs_trans        *tp;
-
-               /*
-                * We're still hanging on to our old inode pointer, so grab it
-                * and reconnect it to the metadata directory tree.  If it
-                * can't be grabbed, create a new rtrefcount file.
-                */
-               error = -libxfs_trans_alloc_empty(mp, &tp);
-               if (error)
-                       do_error(
- _("Couldn't allocate transaction to iget rtgroup %u refcountbt inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno, (unsigned long long)ino,
-                                       error);
-               error = -libxfs_imeta_iget(tp, ino, S_IFREG, &upd.ip);
-               libxfs_trans_cancel(tp);
-               if (error) {
-                       do_warn(
- _("Couldn't iget rtgroup %u refcountbt inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno,
-                                       (unsigned long long)ino,
-                                       error);
-                       goto zap;
-               }
-
-               /*
-                * Since we're reattaching this file to the metadata directory
-                * tree, try to remove all the parent pointers that might be
-                * attached.
-                */
-               try_erase_parent_ptrs(upd.ip);
-
-               error = -libxfs_imeta_start_link(mp, path, upd.ip, &upd);
-               if (error)
-                       do_error(
- _("Couldn't grab resources to reconnect rtgroup %u refcountbt, error %d\n"),
-                                       rtg->rtg_rgno, error);
+ _("Couldn't create rtgroup %u rmap file path\n"),
+                               rtg->rtg_rgno);
 
-               error = -libxfs_imeta_link(&upd);
-               if (error)
-                       do_error(
- _("Failed to link rtgroup %u refcountbt inode 0x%llx, error %d\n"),
-                                       rtg->rtg_rgno,
-                                       (unsigned long long)ino,
-                                       error);
+       ensure_rtgroup_file(rtg, rtgroup_rmap_ino(rtg), path, "rmap",
+                       libxfs_rtrmapbt_create, populate_rtgroup_rmapbt,
+                       &est_fdblocks);
 
-               /* Reset the link count to something sane. */
-               set_nlink(VFS_I(upd.ip), 1);
-               libxfs_trans_log_inode(upd.tp, upd.ip, XFS_ILOG_CORE);
-       } else {
-zap:
-               /*
-                * The rtrefcount inode was bad or gone, so just make a new one
-                * and give our reference to the rtgroup structure.
-                */
-               error = -libxfs_imeta_start_create(mp, path, &upd);
-               if (error)
-                       do_error(
- _("Couldn't grab resources to recreate rtgroup %u refcountbt, error %d\n"),
-                                       rtg->rtg_rgno, error);
+       libxfs_imeta_free_path(path);
+}
 
-               error = -libxfs_rtrefcountbt_create(&upd);
-               if (error)
-                       do_error(
- _("Couldn't create rtgroup %u refcountbt inode, error %d\n"),
-                                       rtg->rtg_rgno, error);
-       }
+static void
+ensure_rtgroup_refcountbt(
+       struct xfs_rtgroup      *rtg,
+       xfs_filblks_t           est_fdblocks)
+{
+       struct xfs_imeta_path   *path;
 
-       /* Mark the inode in use. */
-       mark_ino_inuse(mp, upd.ip->i_ino, S_IFREG, upd.dp->i_ino);
-       mark_ino_metadata(mp, upd.ip->i_ino);
+       if (!xfs_has_rtreflink(rtg->rtg_mount))
+               return;
 
-       error = -libxfs_imeta_commit(&upd);
-       if (error)
+       path = xfs_rtrefcountbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
+       if (!path)
                do_error(
- _("Couldn't commit new rtgroup %u refcountbt inode %llu, error %d\n"),
-                               rtg->rtg_rgno,
-                               (unsigned long long)upd.ip->i_ino,
-                               error);
+ _("Couldn't create rtgroup %u refcount btree file path\n"),
+                       rtg->rtg_rgno);
 
-       /* Copy our incore refcount data to the ondisk refcount inode. */
-       error = populate_rtgroup_refcountbt(rtg, upd.ip, est_fdblocks);
-       if (error)
-               do_error(
- _("rtgroup %u refcount btree could not be rebuilt, error %d\n"),
-                               rtg->rtg_rgno, error);
+       ensure_rtgroup_file(rtg, rtgroup_refcount_ino(rtg), path, "refcount",
+                       libxfs_rtrefcountbt_create, populate_rtgroup_refcountbt,
+                       &est_fdblocks);
 
        libxfs_imeta_free_path(path);
-       libxfs_irele(upd.ip);
 }
 
 /* Initialize a root directory. */
index adc3ae33a31e8b9e924fdc7cdd6b8050c2384697..17336042d7855a64dad75c485db8966b77dec7ab 100644 (file)
@@ -64,16 +64,16 @@ int rmap_get_mem_rec(struct xfs_btree_cur *rmcur, struct xfs_rmap_irec *irec);
 xfs_rgnumber_t rtgroup_for_rtrmap_inode(struct xfs_mount *mp, xfs_ino_t ino);
 bool is_rtrmap_inode(xfs_ino_t ino);
 xfs_ino_t rtgroup_rmap_ino(struct xfs_rtgroup *rtg);
-int populate_rtgroup_rmapbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
-               xfs_filblks_t fdblocks);
+void populate_rtgroup_rmapbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
+               void *private);
 xfs_filblks_t estimate_rtrmapbt_blocks(struct xfs_rtgroup *rtg);
 
 xfs_rgnumber_t rtgroup_for_rtrefcount_inode(struct xfs_mount *mp,
                xfs_ino_t ino);
 bool is_rtrefcount_ino(xfs_ino_t ino);
 xfs_ino_t rtgroup_refcount_ino(struct xfs_rtgroup *rtg);
-int populate_rtgroup_refcountbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
-               xfs_filblks_t fdblocks);
+void populate_rtgroup_refcountbt(struct xfs_rtgroup *rtg, struct xfs_inode *ip,
+               void *private);
 xfs_filblks_t estimate_rtrefcountbt_blocks(struct xfs_rtgroup *rtg);
 
 #endif /* RMAP_H_ */
index 834bab2ecdfe9f248c4de908d7f01e68f0efc8f1..3feaf2fb93d5c60ae6d040895bb1e13f61473cc9 100644 (file)
@@ -219,39 +219,43 @@ err_newbt:
 }
 
 /* Store the realtime reference counts in the rtrefcbt. */
-int
+void
 populate_rtgroup_refcountbt(
        struct xfs_rtgroup      *rtg,
        struct xfs_inode        *ip,
-       xfs_filblks_t           est_fdblocks)
+       void                    *private)
 {
+       struct xfs_mount        *mp = rtg->rtg_mount;
+       xfs_filblks_t           *est_fdblocks = private;
        struct repair_ctx       sc = {
-               .mp             = rtg->rtg_mount,
+               .mp             = mp,
                .ip             = ip,
        };
        struct xrep_rtrefc      rr = {
                .sc             = &sc,
                .rtg            = rtg,
-               .est_fdblocks   = est_fdblocks,
+               .est_fdblocks   = *est_fdblocks,
        };
-       struct xfs_mount        *mp = rtg->rtg_mount;
        int                     error;
 
        if (!xfs_has_rtreflink(mp))
-               return 0;
+               return;
 
        error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
                        &sc.tp);
        if (error)
-               return error;
+               goto out;
 
        error = xrep_rtrefc_build_new_tree(&rr);
-       if (error)
-               goto out_cancel;
-
-       return -libxfs_trans_commit(sc.tp);
+       if (error) {
+               libxfs_trans_cancel(sc.tp);
+               goto out;
+       }
 
-out_cancel:
-       libxfs_trans_cancel(sc.tp);
-       return error;
+       error = -libxfs_trans_commit(sc.tp);
+out:
+       if (error)
+               do_error(
+ _("rtgroup %u refcount btree could not be rebuilt, error %d\n"),
+                       rtg->rtg_rgno, error);
 }
index eab6ebe324d53110ba131c81171b803803e44055..0cfa9d6c8cc2ff25f3cdaf4225a06366aeb08e7f 100644 (file)
@@ -224,39 +224,43 @@ err_newbt:
 }
 
 /* Store the realtime reverse-mappings in the rtrmapbt. */
-int
+void
 populate_rtgroup_rmapbt(
        struct xfs_rtgroup      *rtg,
        struct xfs_inode        *ip,
-       xfs_filblks_t           est_fdblocks)
+       void                    *private)
 {
+       struct xfs_mount        *mp = rtg->rtg_mount;
+       xfs_filblks_t           *est_fdblocks = private;
        struct repair_ctx       sc = {
-               .mp             = rtg->rtg_mount,
+               .mp             = mp,
                .ip             = ip,
        };
        struct xrep_rtrmap      rr = {
                .sc             = &sc,
                .rtg            = rtg,
-               .est_fdblocks   = est_fdblocks,
+               .est_fdblocks   = *est_fdblocks,
        };
-       struct xfs_mount        *mp = rtg->rtg_mount;
        int                     error;
 
        if (!xfs_has_rtrmapbt(mp))
-               return 0;
+               return;
 
        error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
                        &sc.tp);
        if (error)
-               return error;
+               goto out;
 
        error = xrep_rtrmap_build_new_tree(&rr);
-       if (error)
-               goto out_cancel;
-
-       return -libxfs_trans_commit(sc.tp);
+       if (error) {
+               libxfs_trans_cancel(sc.tp);
+               goto out;
+       }
 
-out_cancel:
-       libxfs_trans_cancel(sc.tp);
-       return error;
+       error = -libxfs_trans_commit(sc.tp);
+out:
+       if (error)
+               do_error(
+ _("rtgroup %u rmap btree could not be rebuilt, error %d\n"),
+                       rtg->rtg_rgno, error);
 }