mirror of
https://github.com/torvalds/linux.git
synced 2024-11-30 08:01:59 +00:00
xfs: complain about bad records in query_range helpers
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>
This commit is contained in:
parent
69010fe3ac
commit
ee12eaaa43
@ -261,6 +261,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.
|
||||
*/
|
||||
@ -272,8 +290,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;
|
||||
@ -285,21 +301,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3692,10 +3698,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);
|
||||
}
|
||||
|
@ -122,6 +122,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.
|
||||
*/
|
||||
@ -143,20 +162,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;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2702,10 +2710,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;
|
||||
|
@ -144,6 +144,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.
|
||||
*/
|
||||
@ -153,8 +170,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;
|
||||
@ -166,19 +181,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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -235,6 +235,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.
|
||||
*/
|
||||
@ -244,8 +262,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;
|
||||
@ -258,18 +274,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 {
|
||||
@ -2335,10 +2342,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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user