]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: verify AGI unlinked list contains valid blocks
authorDave Chinner <dchinner@redhat.com>
Thu, 28 Jun 2018 20:11:57 +0000 (15:11 -0500)
committerEric Sandeen <sandeen@redhat.com>
Thu, 28 Jun 2018 20:11:57 +0000 (15:11 -0500)
Source kernel commit: 9f96cc958e8ae9864e6d597a5f3e80b5fca35ae4

The heads of tha AGI unlinked list are only scanned on debug
kernels when the verifier runs. Change that to always scan the heads
and validate that the inode numbers are valid.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_ialloc.c

index 4bf270ed77270238f5940a5eb42d5de970dbf377..2eeded274cc92a23db1e98522926ad8620a7c463 100644 (file)
@@ -2471,26 +2471,13 @@ xfs_ialloc_log_agi(
        }
 }
 
-#ifdef DEBUG
-STATIC void
-xfs_check_agi_unlinked(
-       struct xfs_agi          *agi)
-{
-       int                     i;
-
-       for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
-               ASSERT(agi->agi_unlinked[i]);
-}
-#else
-#define xfs_check_agi_unlinked(agi)
-#endif
-
 static xfs_failaddr_t
 xfs_agi_verify(
        struct xfs_buf  *bp)
 {
        struct xfs_mount *mp = bp->b_target->bt_mount;
        struct xfs_agi  *agi = XFS_BUF_TO_AGI(bp);
+       int             i;
 
        if (xfs_sb_version_hascrc(&mp->m_sb)) {
                if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
@@ -2526,7 +2513,13 @@ xfs_agi_verify(
        if (bp->b_pag && be32_to_cpu(agi->agi_seqno) != bp->b_pag->pag_agno)
                return __this_address;
 
-       xfs_check_agi_unlinked(agi);
+       for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
+               if (agi->agi_unlinked[i] == NULLAGINO)
+                       continue;
+               if (!xfs_verify_ino(mp, be32_to_cpu(agi->agi_unlinked[i])))
+                       return __this_address;
+       }
+
        return NULL;
 }