]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: replace verify_inum with libxfs inode validators
authorDarrick J. Wong <darrick.wong@oracle.com>
Thu, 27 Feb 2020 19:22:19 +0000 (14:22 -0500)
committerEric Sandeen <sandeen@sandeen.net>
Thu, 27 Feb 2020 19:22:19 +0000 (14:22 -0500)
Repair uses the verify_inum function to validate inode numbers that it
finds in the superblock and in directories.  libxfs now has validator
functions to cover that kind of thing, so remove verify_inum().  As a
side bonus, this means that we will flag directories that point to the
quota/realtime metadata inodes.

This fixes a regression found by fuzzing u3.sfdir3.hdr.parent.i4 to
lastbit (aka making a directory's .. point to the user quota inode) in
xfs/384.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_api_defs.h
repair/dino_chunks.c
repair/dinode.c
repair/dinode.h
repair/dir2.c
repair/phase4.c
repair/phase6.c

index 6e09685bf69b0e059b164fe6db861debd9ca145d..9daf2635f368b79cdef11b9e35169613aeddfe4c 100644 (file)
 #define xfs_trans_roll                 libxfs_trans_roll
 
 #define xfs_verify_cksum               libxfs_verify_cksum
+#define xfs_verify_dir_ino             libxfs_verify_dir_ino
 #define xfs_verify_ino                 libxfs_verify_ino
 #define xfs_verify_rtbno               libxfs_verify_rtbno
 #define xfs_zero_extent                        libxfs_zero_extent
index 00b674681f9b87ce1b4063e816de2c18c1dae80e..dbf3d37a675432292e5703ba6fe7762f862fd558 100644 (file)
@@ -65,7 +65,7 @@ check_aginode_block(xfs_mount_t       *mp,
  * inode chunk.  returns number of new inodes if things are good
  * and 0 if bad.  start is the start of the discovered inode chunk.
  * routine assumes that ino is a legal inode number
- * (verified by verify_inum()).  If the inode chunk turns out
+ * (verified by libxfs_verify_ino()).  If the inode chunk turns out
  * to be good, this routine will put the inode chunk into
  * the good inode chunk tree if required.
  *
index 929ec81702c10d27aa385eb1122f83b167b67617..3ee76ea324c12be65606c0e27e6523f53352ed3b 100644 (file)
@@ -171,35 +171,6 @@ verify_ag_bno(xfs_sb_t *sbp,
        return 1;
 }
 
-/*
- * returns 0 if inode number is valid, 1 if bogus
- */
-int
-verify_inum(xfs_mount_t                *mp,
-               xfs_ino_t       ino)
-{
-       xfs_agnumber_t  agno;
-       xfs_agino_t     agino;
-       xfs_agblock_t   agbno;
-       xfs_sb_t        *sbp = &mp->m_sb;;
-
-       /* range check ag #, ag block.  range-checking offset is pointless */
-
-       agno = XFS_INO_TO_AGNO(mp, ino);
-       agino = XFS_INO_TO_AGINO(mp, ino);
-       agbno = XFS_AGINO_TO_AGBNO(mp, agino);
-       if (agbno == 0)
-               return 1;
-
-       if (ino == 0 || ino == NULLFSINO)
-               return(1);
-
-       if (ino != XFS_AGINO_TO_INO(mp, agno, agino))
-               return(1);
-
-       return verify_ag_bno(sbp, agno, agbno);
-}
-
 /*
  * have a separate routine to ensure that we don't accidentally
  * lose illegally set bits in the agino by turning it into an FSINO
index aa177465bbb958bfbea81b031441400e5c1f564b..98238357e3d7e38756266f20d375556cab82ee31 100644 (file)
@@ -77,10 +77,6 @@ verify_uncertain_dinode(xfs_mount_t *mp,
                xfs_agnumber_t agno,
                xfs_agino_t ino);
 
-int
-verify_inum(xfs_mount_t                *mp,
-               xfs_ino_t       ino);
-
 int
 verify_aginum(xfs_mount_t      *mp,
                xfs_agnumber_t  agno,
index e43a97324878d0c9397cd97303f9809ef4c3717d..723aee1fea56ef6157f353cd72684c6324f0bf2a 100644 (file)
@@ -215,7 +215,7 @@ process_sf_dir2(
                if (lino == ino) {
                        junkit = 1;
                        junkreason = _("current");
-               } else if (verify_inum(mp, lino)) {
+               } else if (!libxfs_verify_dir_ino(mp, lino)) {
                        junkit = 1;
                        junkreason = _("invalid");
                } else if (lino == mp->m_sb.sb_rbmino)  {
@@ -486,8 +486,7 @@ _("corrected entry offsets in directory %" PRIu64 "\n"),
         * If the validation fails for the root inode we fix it in
         * the next else case.
         */
-       if (verify_inum(mp, *parent) && ino != mp->m_sb.sb_rootino)  {
-
+       if (!libxfs_verify_dir_ino(mp, *parent) && ino != mp->m_sb.sb_rootino) {
                do_warn(
 _("bogus .. inode number (%" PRIu64 ") in directory inode %" PRIu64 ", "),
                                *parent, ino);
@@ -674,7 +673,7 @@ process_dir2_data(
                         * (or did it ourselves) during phase 3.
                         */
                        clearino = 0;
-               } else if (verify_inum(mp, ent_ino)) {
+               } else if (!libxfs_verify_dir_ino(mp, ent_ino)) {
                        /*
                         * Bad inode number.  Clear the inode number and the
                         * entry will get removed later.  We don't trash the
index e1ba778fdf56c10d985228285693eb318c389451..8197db06c60af1713782882bd80cf3e72298ce4f 100644 (file)
@@ -36,7 +36,7 @@ quotino_check(xfs_mount_t *mp)
        ino_tree_node_t *irec;
 
        if (mp->m_sb.sb_uquotino != NULLFSINO && mp->m_sb.sb_uquotino != 0)  {
-               if (verify_inum(mp, mp->m_sb.sb_uquotino))
+               if (!libxfs_verify_ino(mp, mp->m_sb.sb_uquotino))
                        irec = NULL;
                else
                        irec = find_inode_rec(mp,
@@ -52,7 +52,7 @@ quotino_check(xfs_mount_t *mp)
        }
 
        if (mp->m_sb.sb_gquotino != NULLFSINO && mp->m_sb.sb_gquotino != 0)  {
-               if (verify_inum(mp, mp->m_sb.sb_gquotino))
+               if (!libxfs_verify_ino(mp, mp->m_sb.sb_gquotino))
                        irec = NULL;
                else
                        irec = find_inode_rec(mp,
@@ -68,7 +68,7 @@ quotino_check(xfs_mount_t *mp)
        }
 
        if (mp->m_sb.sb_pquotino != NULLFSINO && mp->m_sb.sb_pquotino != 0)  {
-               if (verify_inum(mp, mp->m_sb.sb_pquotino))
+               if (!libxfs_verify_ino(mp, mp->m_sb.sb_pquotino))
                        irec = NULL;
                else
                        irec = find_inode_rec(mp,
@@ -112,9 +112,9 @@ quota_sb_check(xfs_mount_t *mp)
            (mp->m_sb.sb_pquotino == NULLFSINO || mp->m_sb.sb_pquotino == 0))  {
                lost_quotas = 1;
                fs_quotas = 0;
-       } else if (!verify_inum(mp, mp->m_sb.sb_uquotino) &&
-                       !verify_inum(mp, mp->m_sb.sb_gquotino) &&
-                       !verify_inum(mp, mp->m_sb.sb_pquotino)) {
+       } else if (libxfs_verify_ino(mp, mp->m_sb.sb_uquotino) &&
+                  libxfs_verify_ino(mp, mp->m_sb.sb_gquotino) &&
+                  libxfs_verify_ino(mp, mp->m_sb.sb_pquotino)) {
                fs_quotas = 1;
        }
 }
index 0874b649bdc204eb82da4da2976e1886699add73..701356946d91df4580e25d338797df6925f3c337 100644 (file)
@@ -1814,7 +1814,7 @@ longform_dir2_entry_check_data(
                        }
                        continue;
                }
-               ASSERT(no_modify || !verify_inum(mp, inum));
+               ASSERT(no_modify || libxfs_verify_dir_ino(mp, inum));
                /*
                 * special case the . entry.  we know there's only one
                 * '.' and only '.' points to itself because bogus entries
@@ -1845,7 +1845,7 @@ longform_dir2_entry_check_data(
                /*
                 * skip entries with bogus inumbers if we're in no modify mode
                 */
-               if (no_modify && verify_inum(mp, inum))
+               if (no_modify && !libxfs_verify_dir_ino(mp, inum))
                        continue;
 
                /* validate ftype field if supported */
@@ -2634,14 +2634,14 @@ shortform_dir2_entry_check(xfs_mount_t  *mp,
                fname[sfep->namelen] = '\0';
 
                ASSERT(no_modify || (lino != NULLFSINO && lino != 0));
-               ASSERT(no_modify || !verify_inum(mp, lino));
+               ASSERT(no_modify || libxfs_verify_dir_ino(mp, lino));
 
                /*
                 * Also skip entries with bogus inode numbers if we're
                 * in no modify mode.
                 */
 
-               if (no_modify && verify_inum(mp, lino))  {
+               if (no_modify && !libxfs_verify_dir_ino(mp, lino))  {
                        next_sfep = libxfs_dir2_sf_nextentry(mp, sfp, sfep);
                        continue;
                }