diff options
-rw-r--r-- | fs/xfs/libxfs/xfs_inode_buf.c | 3 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_types.c | 13 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_types.h | 2 | ||||
-rw-r--r-- | fs/xfs/scrub/agheader.c | 8 |
4 files changed, 19 insertions, 7 deletions
diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c index 09d9c8cfa4a0..82c4374acb4c 100644 --- a/fs/xfs/libxfs/xfs_inode_buf.c +++ b/fs/xfs/libxfs/xfs_inode_buf.c | |||
@@ -99,8 +99,7 @@ xfs_inode_buf_verify( | |||
99 | unlinked_ino = be32_to_cpu(dip->di_next_unlinked); | 99 | unlinked_ino = be32_to_cpu(dip->di_next_unlinked); |
100 | di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) && | 100 | di_ok = dip->di_magic == cpu_to_be16(XFS_DINODE_MAGIC) && |
101 | xfs_dinode_good_version(mp, dip->di_version) && | 101 | xfs_dinode_good_version(mp, dip->di_version) && |
102 | (unlinked_ino == NULLAGINO || | 102 | xfs_verify_agino_or_null(mp, agno, unlinked_ino); |
103 | xfs_verify_agino(mp, agno, unlinked_ino)); | ||
104 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, | 103 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
105 | XFS_ERRTAG_ITOBP_INOTOBP))) { | 104 | XFS_ERRTAG_ITOBP_INOTOBP))) { |
106 | if (readahead) { | 105 | if (readahead) { |
diff --git a/fs/xfs/libxfs/xfs_types.c b/fs/xfs/libxfs/xfs_types.c index 451608b5a37b..de310712dd6d 100644 --- a/fs/xfs/libxfs/xfs_types.c +++ b/fs/xfs/libxfs/xfs_types.c | |||
@@ -116,6 +116,19 @@ xfs_verify_agino( | |||
116 | } | 116 | } |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Verify that an AG inode number pointer neither points outside the AG | ||
120 | * nor points at static metadata, or is NULLAGINO. | ||
121 | */ | ||
122 | bool | ||
123 | xfs_verify_agino_or_null( | ||
124 | struct xfs_mount *mp, | ||
125 | xfs_agnumber_t agno, | ||
126 | xfs_agino_t agino) | ||
127 | { | ||
128 | return agino == NULLAGINO || xfs_verify_agino(mp, agno, agino); | ||
129 | } | ||
130 | |||
131 | /* | ||
119 | * Verify that an FS inode number pointer neither points outside the | 132 | * Verify that an FS inode number pointer neither points outside the |
120 | * filesystem nor points at static AG metadata. | 133 | * filesystem nor points at static AG metadata. |
121 | */ | 134 | */ |
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 704b4f308780..c5a25403b4db 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h | |||
@@ -183,6 +183,8 @@ void xfs_agino_range(struct xfs_mount *mp, xfs_agnumber_t agno, | |||
183 | xfs_agino_t *first, xfs_agino_t *last); | 183 | xfs_agino_t *first, xfs_agino_t *last); |
184 | bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno, | 184 | bool xfs_verify_agino(struct xfs_mount *mp, xfs_agnumber_t agno, |
185 | xfs_agino_t agino); | 185 | xfs_agino_t agino); |
186 | bool xfs_verify_agino_or_null(struct xfs_mount *mp, xfs_agnumber_t agno, | ||
187 | xfs_agino_t agino); | ||
186 | bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); | 188 | bool xfs_verify_ino(struct xfs_mount *mp, xfs_ino_t ino); |
187 | bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); | 189 | bool xfs_internal_inum(struct xfs_mount *mp, xfs_ino_t ino); |
188 | bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); | 190 | bool xfs_verify_dir_ino(struct xfs_mount *mp, xfs_ino_t ino); |
diff --git a/fs/xfs/scrub/agheader.c b/fs/xfs/scrub/agheader.c index 90955ab1e895..9d4e8293d37e 100644 --- a/fs/xfs/scrub/agheader.c +++ b/fs/xfs/scrub/agheader.c | |||
@@ -864,19 +864,17 @@ xchk_agi( | |||
864 | 864 | ||
865 | /* Check inode pointers */ | 865 | /* Check inode pointers */ |
866 | agino = be32_to_cpu(agi->agi_newino); | 866 | agino = be32_to_cpu(agi->agi_newino); |
867 | if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino)) | 867 | if (!xfs_verify_agino_or_null(mp, agno, agino)) |
868 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); | 868 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); |
869 | 869 | ||
870 | agino = be32_to_cpu(agi->agi_dirino); | 870 | agino = be32_to_cpu(agi->agi_dirino); |
871 | if (agino != NULLAGINO && !xfs_verify_agino(mp, agno, agino)) | 871 | if (!xfs_verify_agino_or_null(mp, agno, agino)) |
872 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); | 872 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); |
873 | 873 | ||
874 | /* Check unlinked inode buckets */ | 874 | /* Check unlinked inode buckets */ |
875 | for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { | 875 | for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) { |
876 | agino = be32_to_cpu(agi->agi_unlinked[i]); | 876 | agino = be32_to_cpu(agi->agi_unlinked[i]); |
877 | if (agino == NULLAGINO) | 877 | if (!xfs_verify_agino_or_null(mp, agno, agino)) |
878 | continue; | ||
879 | if (!xfs_verify_agino(mp, agno, agino)) | ||
880 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); | 878 | xchk_block_set_corrupt(sc, sc->sa.agi_bp); |
881 | } | 879 | } |
882 | 880 | ||