]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_repair: refactor fixing dotdot
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:24:18 +0000 (16:24 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Thu, 28 Nov 2024 02:33:12 +0000 (18:33 -0800)
Pull the code that fixes a directory's dot-dot entry into a separate
helper function so that we can call it on the rootdir and (later) the
metadir.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
repair/phase6.c

index 630617ef8ab8fe589e7940fc29f20366bef87977..0f13d996fe726a2e8873ac19c9ddcfcfd02a2d3e 100644 (file)
@@ -2649,6 +2649,62 @@ dir_hash_add_parent_ptrs(
        }
 }
 
+/*
+ * If we have to create a .. for /, do it now *before* we delete the bogus
+ * entries, otherwise the directory could transform into a shortform dir which
+ * would probably cause the simulation to choke.  Even if the illegal entries
+ * get shifted around, it's ok because the entries are structurally intact and
+ * in in hash-value order so the simulation won't get confused if it has to
+ * move them around.
+ */
+static void
+fix_dotdot(
+       struct xfs_mount        *mp,
+       xfs_ino_t               ino,
+       struct xfs_inode        *ip,
+       xfs_ino_t               rootino,
+       const char              *tag,
+       int                     *need_dotdot)
+{
+       struct xfs_trans        *tp;
+       int                     nres;
+       int                     error;
+
+       if (ino != rootino || !*need_dotdot)
+               return;
+
+       if (no_modify) {
+               do_warn(_("would recreate %s directory .. entry\n"), tag);
+               return;
+       }
+
+       ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_LOCAL);
+
+       do_warn(_("recreating %s directory .. entry\n"), tag);
+
+       nres = libxfs_mkdir_space_res(mp, 2);
+       error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir, nres, 0, 0, &tp);
+       if (error)
+               res_failed(error);
+
+       libxfs_trans_ijoin(tp, ip, 0);
+
+       error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot, ip->i_ino,
+                       nres);
+       if (error)
+               do_error(
+_("can't make \"..\" entry in %s inode %" PRIu64 ", createname error %d\n"),
+                       tag ,ino, error);
+
+       libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
+       error = -libxfs_trans_commit(tp);
+       if (error)
+               do_error(
+_("%s inode \"..\" entry recreation failed (%d)\n"), tag, error);
+
+       *need_dotdot = 0;
+}
+
 /*
  * processes all reachable inodes in directories
  */
@@ -2778,45 +2834,7 @@ _("error %d fixing shortform directory %llu\n"),
        dir_hash_add_parent_ptrs(ip, hashtab);
        dir_hash_done(hashtab);
 
-       /*
-        * if we have to create a .. for /, do it now *before*
-        * we delete the bogus entries, otherwise the directory
-        * could transform into a shortform dir which would
-        * probably cause the simulation to choke.  Even
-        * if the illegal entries get shifted around, it's ok
-        * because the entries are structurally intact and in
-        * in hash-value order so the simulation won't get confused
-        * if it has to move them around.
-        */
-       if (!no_modify && need_root_dotdot && ino == mp->m_sb.sb_rootino)  {
-               ASSERT(ip->i_df.if_format != XFS_DINODE_FMT_LOCAL);
-
-               do_warn(_("recreating root directory .. entry\n"));
-
-               nres = libxfs_mkdir_space_res(mp, 2);
-               error = -libxfs_trans_alloc(mp, &M_RES(mp)->tr_mkdir,
-                                           nres, 0, 0, &tp);
-               if (error)
-                       res_failed(error);
-
-               libxfs_trans_ijoin(tp, ip, 0);
-
-               error = -libxfs_dir_createname(tp, ip, &xfs_name_dotdot,
-                                       ip->i_ino, nres);
-               if (error)
-                       do_error(
-       _("can't make \"..\" entry in root inode %" PRIu64 ", createname error %d\n"), ino, error);
-
-               libxfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
-               error = -libxfs_trans_commit(tp);
-               if (error)
-                       do_error(
-       _("root inode \"..\" entry recreation failed (%d)\n"), error);
-
-               need_root_dotdot = 0;
-       } else if (need_root_dotdot && ino == mp->m_sb.sb_rootino)  {
-               do_warn(_("would recreate root directory .. entry\n"));
-       }
+       fix_dotdot(mp, ino, ip, mp->m_sb.sb_rootino, "root", &need_root_dotdot);
 
        /*
         * if we need to create the '.' entry, do so only if