diff options
author | Dave Chinner <david@fromorbit.com> | 2023-04-14 07:09:27 +1000 |
---|---|---|
committer | Dave Chinner <dchinner@redhat.com> | 2023-04-14 07:09:27 +1000 |
commit | b764ea207fba692bc8195513ab4a63fbc4af6e66 (patch) | |
tree | ee6a34fd984769c3ce5c08106b6639aa4f682c41 /fs/xfs | |
parent | 01822a74ca5e49dfdc4003be21cb96e4f3d42606 (diff) | |
parent | de1a9ce225e93b22d189f8ffbce20074bc803121 (diff) |
Merge tag 'btree-hoist-scrub-checks-6.4_2023-04-11' of git://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into guilt/xfs-for-next
xfs: hoist scrub record checks into libxfs [v24.5]
There are a few things about btree records that scrub checked but the
libxfs _get_rec functions didn't. Move these bits into libxfs so that
everyone can benefit.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 4 | ||||
-rw-r--r-- | fs/xfs/libxfs/xfs_rmap.c | 27 | ||||
-rw-r--r-- | fs/xfs/scrub/ialloc.c | 6 | ||||
-rw-r--r-- | fs/xfs/scrub/rmap.c | 22 |
4 files changed, 31 insertions, 28 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index b7dc8b81a133..0d2980accd3c 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -103,8 +103,12 @@ xfs_inobt_check_irec( { uint64_t realfree; + /* Record has to be properly aligned within the AG. */ if (!xfs_verify_agino(cur->bc_ag.pag, irec->ir_startino)) return __this_address; + if (!xfs_verify_agino(cur->bc_ag.pag, + irec->ir_startino + XFS_INODES_PER_CHUNK - 1)) + return __this_address; if (irec->ir_count < XFS_INODES_PER_HOLEMASK_BIT || irec->ir_count > XFS_INODES_PER_CHUNK) return __this_address; diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 641114a023f2..da008d317f83 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -212,6 +212,10 @@ xfs_rmap_check_irec( const struct xfs_rmap_irec *irec) { struct xfs_mount *mp = cur->bc_mp; + bool is_inode; + bool is_unwritten; + bool is_bmbt; + bool is_attr; if (irec->rm_blockcount == 0) return __this_address; @@ -232,6 +236,29 @@ xfs_rmap_check_irec( irec->rm_owner >= XFS_RMAP_OWN_MIN))) return __this_address; + /* Check flags. */ + is_inode = !XFS_RMAP_NON_INODE_OWNER(irec->rm_owner); + is_bmbt = irec->rm_flags & XFS_RMAP_BMBT_BLOCK; + is_attr = irec->rm_flags & XFS_RMAP_ATTR_FORK; + is_unwritten = irec->rm_flags & XFS_RMAP_UNWRITTEN; + + if (is_bmbt && irec->rm_offset != 0) + return __this_address; + + if (!is_inode && irec->rm_offset != 0) + return __this_address; + + if (is_unwritten && (is_bmbt || !is_inode || is_attr)) + return __this_address; + + if (!is_inode && (is_bmbt || is_unwritten || is_attr)) + return __this_address; + + /* Check for a valid fork offset, if applicable. */ + if (is_inode && !is_bmbt && + !xfs_verify_fileext(mp, irec->rm_offset, irec->rm_blockcount)) + return __this_address; + return NULL; } diff --git a/fs/xfs/scrub/ialloc.c b/fs/xfs/scrub/ialloc.c index 11afb4c5a161..ca5a7e0f5451 100644 --- a/fs/xfs/scrub/ialloc.c +++ b/fs/xfs/scrub/ialloc.c @@ -413,7 +413,6 @@ xchk_iallocbt_rec( const union xfs_btree_rec *rec) { struct xfs_mount *mp = bs->cur->bc_mp; - struct xfs_perag *pag = bs->cur->bc_ag.pag; struct xchk_iallocbt *iabt = bs->private; struct xfs_inobt_rec_incore irec; uint64_t holes; @@ -431,11 +430,6 @@ xchk_iallocbt_rec( } agino = irec.ir_startino; - /* Record has to be properly aligned within the AG. */ - if (!xfs_verify_agino(pag, agino + XFS_INODES_PER_CHUNK - 1)) { - xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - goto out; - } xchk_iallocbt_rec_alignment(bs, &irec); if (bs->sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) diff --git a/fs/xfs/scrub/rmap.c b/fs/xfs/scrub/rmap.c index 353cf9d90027..ef6e4b8546a6 100644 --- a/fs/xfs/scrub/rmap.c +++ b/fs/xfs/scrub/rmap.c @@ -94,10 +94,6 @@ xchk_rmapbt_rec( const union xfs_btree_rec *rec) { struct xfs_rmap_irec irec; - bool non_inode; - bool is_unwritten; - bool is_bmbt; - bool is_attr; if (xfs_rmap_btrec_to_irec(rec, &irec) != NULL || xfs_rmap_check_irec(bs->cur, &irec) != NULL) { @@ -105,24 +101,6 @@ xchk_rmapbt_rec( return 0; } - /* Check flags. */ - non_inode = XFS_RMAP_NON_INODE_OWNER(irec.rm_owner); - is_bmbt = irec.rm_flags & XFS_RMAP_BMBT_BLOCK; - is_attr = irec.rm_flags & XFS_RMAP_ATTR_FORK; - is_unwritten = irec.rm_flags & XFS_RMAP_UNWRITTEN; - - if (is_bmbt && irec.rm_offset != 0) - xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - - if (non_inode && irec.rm_offset != 0) - xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - - if (is_unwritten && (is_bmbt || non_inode || is_attr)) - xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - - if (non_inode && (is_bmbt || is_unwritten || is_attr)) - xchk_btree_set_corrupt(bs->sc, bs->cur, 0); - xchk_rmapbt_xref(bs->sc, &irec); return 0; } |