diff options
author | Darrick J. Wong <djwong@kernel.org> | 2023-05-31 10:59:21 +0200 |
---|---|---|
committer | Carlos Maiolino <cem@kernel.org> | 2023-06-09 10:27:50 +0200 |
commit | e70bf9ba99546b22a362e58d968e838feb886a6a (patch) | |
tree | eb82f0f789a9a79830450e58765f842778054527 | |
parent | fd1d74cd69383ec7baaee7ad2e5dbe47f0061bbf (diff) | |
download | xfsprogs-dev-e70bf9ba99546b22a362e58d968e838feb886a6a.tar.gz |
xfs: complain about bad records in query_range helpers
Source kernel commit: ee12eaaa435a7be17152ac50943ee77249de624a
For every btree type except for the bmbt, refactor the code that
complains about bad records into a helper and make the ->query_range
helpers call it so that corruptions found via that avenue are logged.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
-rw-r--r-- | libxfs/xfs_alloc.c | 38 | ||||
-rw-r--r-- | libxfs/xfs_ialloc.c | 38 | ||||
-rw-r--r-- | libxfs/xfs_refcount.c | 32 | ||||
-rw-r--r-- | libxfs/xfs_rmap.c | 40 |
4 files changed, 91 insertions, 57 deletions
diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index e3d243ddae..eeac7e8ae1 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -257,6 +257,24 @@ xfs_alloc_check_irec( return NULL; } +static inline int +xfs_alloc_complain_bad_rec( + struct xfs_btree_cur *cur, + xfs_failaddr_t fa, + const struct xfs_alloc_rec_incore *irec) +{ + struct xfs_mount *mp = cur->bc_mp; + + xfs_warn(mp, + "%s Freespace BTree record corruption in AG %d detected at %pS!", + cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", + cur->bc_ag.pag->pag_agno, fa); + xfs_warn(mp, + "start block 0x%x block count 0x%x", irec->ar_startblock, + irec->ar_blockcount); + return -EFSCORRUPTED; +} + /* * Get the data from the pointed-to record. */ @@ -268,8 +286,6 @@ xfs_alloc_get_rec( int *stat) /* output: success/failure */ { struct xfs_alloc_rec_incore irec; - struct xfs_mount *mp = cur->bc_mp; - struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; xfs_failaddr_t fa; int error; @@ -281,21 +297,11 @@ xfs_alloc_get_rec( xfs_alloc_btrec_to_irec(rec, &irec); fa = xfs_alloc_check_irec(cur, &irec); if (fa) - goto out_bad_rec; + return xfs_alloc_complain_bad_rec(cur, fa, &irec); *bno = irec.ar_startblock; *len = irec.ar_blockcount; return 0; - -out_bad_rec: - xfs_warn(mp, - "%s Freespace BTree record corruption in AG %d detected at %pS!", - cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size", - pag->pag_agno, fa); - xfs_warn(mp, - "start block 0x%x block count 0x%x", irec.ar_startblock, - irec.ar_blockcount); - return -EFSCORRUPTED; } /* @@ -3688,10 +3694,12 @@ xfs_alloc_query_range_helper( { struct xfs_alloc_query_range_info *query = priv; struct xfs_alloc_rec_incore irec; + xfs_failaddr_t fa; xfs_alloc_btrec_to_irec(rec, &irec); - if (xfs_alloc_check_irec(cur, &irec) != NULL) - return -EFSCORRUPTED; + fa = xfs_alloc_check_irec(cur, &irec); + if (fa) + return xfs_alloc_complain_bad_rec(cur, fa, &irec); return query->fn(cur, &irec, query->priv); } diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 78634c5a7b..fa5ac81801 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -117,6 +117,25 @@ xfs_inobt_check_irec( return NULL; } +static inline int +xfs_inobt_complain_bad_rec( + struct xfs_btree_cur *cur, + xfs_failaddr_t fa, + const struct xfs_inobt_rec_incore *irec) +{ + struct xfs_mount *mp = cur->bc_mp; + + xfs_warn(mp, + "%s Inode BTree record corruption in AG %d detected at %pS!", + cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free", + cur->bc_ag.pag->pag_agno, fa); + xfs_warn(mp, +"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x", + irec->ir_startino, irec->ir_count, irec->ir_freecount, + irec->ir_free, irec->ir_holemask); + return -EFSCORRUPTED; +} + /* * Get the data from the pointed-to record. */ @@ -138,20 +157,9 @@ xfs_inobt_get_rec( xfs_inobt_btrec_to_irec(mp, rec, irec); fa = xfs_inobt_check_irec(cur, irec); if (fa) - goto out_bad_rec; + return xfs_inobt_complain_bad_rec(cur, fa, irec); return 0; - -out_bad_rec: - xfs_warn(mp, - "%s Inode BTree record corruption in AG %d detected at %pS!", - cur->bc_btnum == XFS_BTNUM_INO ? "Used" : "Free", - cur->bc_ag.pag->pag_agno, fa); - xfs_warn(mp, -"start inode 0x%x, count 0x%x, free 0x%x freemask 0x%llx, holemask 0x%x", - irec->ir_startino, irec->ir_count, irec->ir_freecount, - irec->ir_free, irec->ir_holemask); - return -EFSCORRUPTED; } /* @@ -2697,10 +2705,12 @@ xfs_ialloc_count_inodes_rec( { struct xfs_inobt_rec_incore irec; struct xfs_ialloc_count_inodes *ci = priv; + xfs_failaddr_t fa; xfs_inobt_btrec_to_irec(cur->bc_mp, rec, &irec); - if (xfs_inobt_check_irec(cur, &irec) != NULL) - return -EFSCORRUPTED; + fa = xfs_inobt_check_irec(cur, &irec); + if (fa) + return xfs_inobt_complain_bad_rec(cur, fa, &irec); ci->count += irec.ir_count; ci->freecount += irec.ir_freecount; diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c index 7028342c77..c83074d2ec 100644 --- a/libxfs/xfs_refcount.c +++ b/libxfs/xfs_refcount.c @@ -143,6 +143,23 @@ xfs_refcount_check_irec( return NULL; } +static inline int +xfs_refcount_complain_bad_rec( + struct xfs_btree_cur *cur, + xfs_failaddr_t fa, + const struct xfs_refcount_irec *irec) +{ + struct xfs_mount *mp = cur->bc_mp; + + xfs_warn(mp, + "Refcount BTree record corruption in AG %d detected at %pS!", + cur->bc_ag.pag->pag_agno, fa); + xfs_warn(mp, + "Start block 0x%x, block count 0x%x, references 0x%x", + irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount); + return -EFSCORRUPTED; +} + /* * Get the data from the pointed-to record. */ @@ -152,8 +169,6 @@ xfs_refcount_get_rec( struct xfs_refcount_irec *irec, int *stat) { - struct xfs_mount *mp = cur->bc_mp; - struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; xfs_failaddr_t fa; int error; @@ -165,19 +180,10 @@ xfs_refcount_get_rec( xfs_refcount_btrec_to_irec(rec, irec); fa = xfs_refcount_check_irec(cur, irec); if (fa) - goto out_bad_rec; + return xfs_refcount_complain_bad_rec(cur, fa, irec); - trace_xfs_refcount_get(cur->bc_mp, pag->pag_agno, irec); + trace_xfs_refcount_get(cur->bc_mp, cur->bc_ag.pag->pag_agno, irec); return 0; - -out_bad_rec: - xfs_warn(mp, - "Refcount BTree record corruption in AG %d detected at %pS!", - pag->pag_agno, fa); - xfs_warn(mp, - "Start block 0x%x, block count 0x%x, references 0x%x", - irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount); - return -EFSCORRUPTED; } /* diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c index 5ac2ca509a..a5b48f0ec2 100644 --- a/libxfs/xfs_rmap.c +++ b/libxfs/xfs_rmap.c @@ -234,6 +234,24 @@ xfs_rmap_check_irec( return NULL; } +static inline int +xfs_rmap_complain_bad_rec( + struct xfs_btree_cur *cur, + xfs_failaddr_t fa, + const struct xfs_rmap_irec *irec) +{ + struct xfs_mount *mp = cur->bc_mp; + + xfs_warn(mp, + "Reverse Mapping BTree record corruption in AG %d detected at %pS!", + cur->bc_ag.pag->pag_agno, fa); + xfs_warn(mp, + "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x", + irec->rm_owner, irec->rm_flags, irec->rm_startblock, + irec->rm_blockcount); + return -EFSCORRUPTED; +} + /* * Get the data from the pointed-to record. */ @@ -243,8 +261,6 @@ xfs_rmap_get_rec( struct xfs_rmap_irec *irec, int *stat) { - struct xfs_mount *mp = cur->bc_mp; - struct xfs_perag *pag = cur->bc_ag.pag; union xfs_btree_rec *rec; xfs_failaddr_t fa; int error; @@ -257,18 +273,9 @@ xfs_rmap_get_rec( if (!fa) fa = xfs_rmap_check_irec(cur, irec); if (fa) - goto out_bad_rec; + return xfs_rmap_complain_bad_rec(cur, fa, irec); return 0; -out_bad_rec: - xfs_warn(mp, - "Reverse Mapping BTree record corruption in AG %d detected at %pS!", - pag->pag_agno, fa); - xfs_warn(mp, - "Owner 0x%llx, flags 0x%x, start block 0x%x block count 0x%x", - irec->rm_owner, irec->rm_flags, irec->rm_startblock, - irec->rm_blockcount); - return -EFSCORRUPTED; } struct xfs_find_left_neighbor_info { @@ -2334,10 +2341,13 @@ xfs_rmap_query_range_helper( { struct xfs_rmap_query_range_info *query = priv; struct xfs_rmap_irec irec; + xfs_failaddr_t fa; - if (xfs_rmap_btrec_to_irec(rec, &irec) != NULL || - xfs_rmap_check_irec(cur, &irec) != NULL) - return -EFSCORRUPTED; + fa = xfs_rmap_btrec_to_irec(rec, &irec); + if (!fa) + fa = xfs_rmap_check_irec(cur, &irec); + if (fa) + return xfs_rmap_complain_bad_rec(cur, fa, &irec); return query->fn(cur, &irec, query->priv); } |