]> 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, 17 Jul 2024 06:30:06 +0000 (08:30 +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..2b5a9f4d652aaf393ab41c8c2264c7b0a794168c 100644 (file)
@@ -881,37 +881,28 @@ ensure_imeta_dirpath(
        return error;
 }
 
-static void
-ensure_rtgroup_rmapbt(
+static struct xfs_inode *
+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))
 {
-       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);
-               return;
+                       do_warn(_("would reset rtgroup %u %s inode\n"),
+                               rtg->rtg_rgno, name);
+               return NULL;
        }
 
        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 inode\n"),
+                       rtg->rtg_rgno, name);
 
        error = ensure_imeta_dirpath(mp, path);
        if (error)
@@ -925,21 +916,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 +944,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 +960,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 +983,63 @@ 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);
-
-       /* 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);
+ _("Couldn't commit new rtgroup %u %s inode %llu, error %d\n"),
+                       rtg->rtg_rgno, name, (unsigned long long)upd.ip->i_ino,
+                       error);
 
-       libxfs_imeta_free_path(path);
-       libxfs_irele(upd.ip);
+       return 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;
+       struct xfs_inode        *ip;
 
-       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);
-
-               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);
-
-               /* 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);
+ _("Couldn't create rtgroup %u rmap file path\n"),
+                               rtg->rtg_rgno);
 
-               error = -libxfs_rtrefcountbt_create(&upd);
-               if (error)
-                       do_error(
- _("Couldn't create rtgroup %u refcountbt inode, error %d\n"),
-                                       rtg->rtg_rgno, error);
+       ip = ensure_rtgroup_file(rtg, rtgroup_rmap_ino(rtg), path, "rmap",
+                       libxfs_rtrmapbt_create);
+       if (ip) {
+               populate_rtgroup_rmapbt(rtg, ip, est_fdblocks);
+               libxfs_irele(ip);
        }
+       libxfs_imeta_free_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);
+static void
+ensure_rtgroup_refcountbt(
+       struct xfs_rtgroup      *rtg,
+       xfs_filblks_t           est_fdblocks)
+{
+       struct xfs_imeta_path   *path;
+       struct xfs_inode        *ip;
 
-       error = -libxfs_imeta_commit(&upd);
-       if (error)
-               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);
+       if (!xfs_has_rtreflink(rtg->rtg_mount))
+               return;
 
-       /* Copy our incore refcount data to the ondisk refcount inode. */
-       error = populate_rtgroup_refcountbt(rtg, upd.ip, est_fdblocks);
-       if (error)
+       path = xfs_rtrefcountbt_create_path(rtg->rtg_mount, rtg->rtg_rgno);
+       if (!path)
                do_error(
- _("rtgroup %u refcount btree could not be rebuilt, error %d\n"),
-                               rtg->rtg_rgno, error);
+ _("Couldn't create rtgroup %u refcount file path\n"),
+                       rtg->rtg_rgno);
 
+       ip = ensure_rtgroup_file(rtg, rtgroup_refcount_ino(rtg), path,
+                       "refcount", libxfs_rtrefcountbt_create);
+       if (ip) {
+               populate_rtgroup_refcountbt(rtg, ip, est_fdblocks);
+               libxfs_irele(ip);
+       }
        libxfs_imeta_free_path(path);
-       libxfs_irele(upd.ip);
 }
 
 /* Initialize a root directory. */
index adc3ae33a31e8b9e924fdc7cdd6b8050c2384697..49923500d09a474a8442b4e45d6b4adef65b6228 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,
+               xfs_filblks_t est_fdblocks);
 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,
+               xfs_filblks_t est_fdblocks);
 xfs_filblks_t estimate_rtrefcountbt_blocks(struct xfs_rtgroup *rtg);
 
 #endif /* RMAP_H_ */
index 834bab2ecdfe9f248c4de908d7f01e68f0efc8f1..fede5c725b3b6f9140c6c702ea7b3d078b442111 100644 (file)
@@ -219,14 +219,15 @@ 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)
 {
+       struct xfs_mount        *mp = rtg->rtg_mount;
        struct repair_ctx       sc = {
-               .mp             = rtg->rtg_mount,
+               .mp             = mp,
                .ip             = ip,
        };
        struct xrep_rtrefc      rr = {
@@ -234,24 +235,26 @@ populate_rtgroup_refcountbt(
                .rtg            = rtg,
                .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..231213a87f5179d99f832df963eb45f19af97263 100644 (file)
@@ -224,14 +224,15 @@ 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)
 {
+       struct xfs_mount        *mp = rtg->rtg_mount;
        struct repair_ctx       sc = {
-               .mp             = rtg->rtg_mount,
+               .mp             = mp,
                .ip             = ip,
        };
        struct xrep_rtrmap      rr = {
@@ -239,24 +240,26 @@ populate_rtgroup_rmapbt(
                .rtg            = rtg,
                .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);
 }