]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_repair: dont check metadata directory dirent inumbers
authorDarrick J. Wong <djwong@kernel.org>
Wed, 3 Jul 2024 21:21:52 +0000 (14:21 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:13:18 +0000 (17:13 -0700)
Phase 6 always rebuilds the entire metadata directory tree, and repair
quietly ignores all the DIFLAG2_METADATA directory inodes that it finds.
As a result, none of the metadata directories are marked inuse in the
incore data.  Therefore, the is_inode_free checks are not valid for
anything we find in a metadata directory.

Therefore, avoid checking is_inode_free when scanning metadata directory
dirents.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
libxfs/libxfs_api_defs.h
repair/dir2.c

index ced1e50dd82310e0b317d7fd0ec236a1bdfb63cc..80c195383c17c1b30d33114c99fe2475890521f4 100644 (file)
 #define xfs_dinode_calc_crc            libxfs_dinode_calc_crc
 #define xfs_dinode_good_version                libxfs_dinode_good_version
 #define xfs_dinode_verify              libxfs_dinode_verify
+#define xfs_dinode_verify_metadir      libxfs_dinode_verify_metadir
 
 #define xfs_dir2_data_bestfree_p       libxfs_dir2_data_bestfree_p
 #define xfs_dir2_data_entry_tag_p      libxfs_dir2_data_entry_tag_p
index bfeaddd07d205806a4ee2645c1c4d1239eba3a4e..dab6523f676a34ce5a6ff289b4953dd32a5ec00a 100644 (file)
@@ -136,6 +136,29 @@ process_sf_dir2_fixoff(
        }
 }
 
+static inline bool
+is_metadata_directory(
+       struct xfs_mount        *mp,
+       struct xfs_dinode       *dip)
+{
+       xfs_failaddr_t          fa;
+       uint16_t                mode;
+       uint16_t                flags;
+       uint64_t                flags2;
+
+       if (!xfs_has_metadir(mp))
+               return false;
+       if (dip->di_version < 3 ||
+           !(dip->di_flags2 & cpu_to_be64(XFS_DIFLAG2_METADATA)))
+               return false;
+
+       mode = be16_to_cpu(dip->di_mode);
+       flags = be16_to_cpu(dip->di_flags);
+       flags2 = be64_to_cpu(dip->di_flags2);
+       fa = libxfs_dinode_verify_metadir(mp, dip, mode, flags, flags2);
+       return fa == NULL;
+}
+
 /*
  * this routine performs inode discovery and tries to fix things
  * in place.  available redundancy -- inode data size should match
@@ -227,6 +250,12 @@ process_sf_dir2(
                } else if (!libxfs_verify_dir_ino(mp, lino)) {
                        junkit = 1;
                        junkreason = _("invalid");
+               } else if (is_metadata_directory(mp, dip)) {
+                       /*
+                        * Metadata directories are always rebuilt, so don't
+                        * bother checking if the child inode is free or not.
+                        */
+                       junkit = 0;
                } else if (lino == mp->m_sb.sb_rbmino)  {
                        junkit = 1;
                        junkreason = _("realtime bitmap");
@@ -698,6 +727,12 @@ process_dir2_data(
                         * directory since it's still structurally intact.
                         */
                        clearreason = _("invalid");
+               } else if (is_metadata_directory(mp, dip)) {
+                       /*
+                        * Metadata directories are always rebuilt, so don't
+                        * bother checking if the child inode is free or not.
+                        */
+                       clearino = 0;
                } else if (ent_ino == mp->m_sb.sb_rbmino) {
                        clearreason = _("realtime bitmap");
                } else if (ent_ino == mp->m_sb.sb_rsumino) {