mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
Merge branch 'xfs-verifier-cleanup' into for-next
This commit is contained in:
commit
49ae4b97d7
25 changed files with 202 additions and 155 deletions
|
@ -89,6 +89,8 @@ typedef struct xfs_agf {
|
|||
/* structure must be padded to 64 bit alignment */
|
||||
} xfs_agf_t;
|
||||
|
||||
#define XFS_AGF_CRC_OFF offsetof(struct xfs_agf, agf_crc)
|
||||
|
||||
#define XFS_AGF_MAGICNUM 0x00000001
|
||||
#define XFS_AGF_VERSIONNUM 0x00000002
|
||||
#define XFS_AGF_SEQNO 0x00000004
|
||||
|
@ -167,6 +169,8 @@ typedef struct xfs_agi {
|
|||
/* structure must be padded to 64 bit alignment */
|
||||
} xfs_agi_t;
|
||||
|
||||
#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc)
|
||||
|
||||
#define XFS_AGI_MAGICNUM 0x00000001
|
||||
#define XFS_AGI_VERSIONNUM 0x00000002
|
||||
#define XFS_AGI_SEQNO 0x00000004
|
||||
|
@ -222,6 +226,8 @@ typedef struct xfs_agfl {
|
|||
__be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */
|
||||
} xfs_agfl_t;
|
||||
|
||||
#define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc)
|
||||
|
||||
/*
|
||||
* tags for inode radix tree
|
||||
*/
|
||||
|
|
|
@ -474,7 +474,6 @@ xfs_agfl_read_verify(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
int agfl_ok = 1;
|
||||
|
||||
/*
|
||||
* There is no verification of non-crc AGFLs because mkfs does not
|
||||
|
@ -485,15 +484,13 @@ xfs_agfl_read_verify(
|
|||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
return;
|
||||
|
||||
agfl_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agfl, agfl_crc));
|
||||
|
||||
agfl_ok = agfl_ok && xfs_agfl_verify(bp);
|
||||
|
||||
if (!agfl_ok) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_agfl_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -508,16 +505,15 @@ xfs_agfl_write_verify(
|
|||
return;
|
||||
|
||||
if (!xfs_agfl_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bip)
|
||||
XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agfl, agfl_crc));
|
||||
xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_agfl_buf_ops = {
|
||||
|
@ -2238,19 +2234,17 @@ xfs_agf_read_verify(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
int agf_ok = 1;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
agf_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agf, agf_crc));
|
||||
|
||||
agf_ok = agf_ok && xfs_agf_verify(mp, bp);
|
||||
|
||||
if (unlikely(XFS_TEST_ERROR(!agf_ok, mp, XFS_ERRTAG_ALLOC_READ_AGF,
|
||||
XFS_RANDOM_ALLOC_READ_AGF))) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (XFS_TEST_ERROR(!xfs_agf_verify(mp, bp), mp,
|
||||
XFS_ERRTAG_ALLOC_READ_AGF,
|
||||
XFS_RANDOM_ALLOC_READ_AGF))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2261,8 +2255,8 @@ xfs_agf_write_verify(
|
|||
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
||||
|
||||
if (!xfs_agf_verify(mp, bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2272,8 +2266,7 @@ xfs_agf_write_verify(
|
|||
if (bip)
|
||||
XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agf, agf_crc));
|
||||
xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_agf_buf_ops = {
|
||||
|
|
|
@ -355,12 +355,14 @@ static void
|
|||
xfs_allocbt_read_verify(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
if (!(xfs_btree_sblock_verify_crc(bp) &&
|
||||
xfs_allocbt_verify(bp))) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
if (!xfs_btree_sblock_verify_crc(bp))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_allocbt_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
|
||||
if (bp->b_error) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -370,9 +372,9 @@ xfs_allocbt_write_verify(
|
|||
{
|
||||
if (!xfs_allocbt_verify(bp)) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
xfs_btree_sblock_calc_crc(bp);
|
||||
|
||||
|
|
|
@ -213,8 +213,8 @@ xfs_attr3_leaf_write_verify(
|
|||
struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_attr3_leaf_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ xfs_attr3_leaf_write_verify(
|
|||
if (bip)
|
||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_ATTR3_LEAF_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -239,13 +239,14 @@ xfs_attr3_leaf_read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_ATTR3_LEAF_CRC_OFF)) ||
|
||||
!xfs_attr3_leaf_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_attr3_leaf_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
|
||||
|
|
|
@ -125,7 +125,6 @@ xfs_attr3_rmt_read_verify(
|
|||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
char *ptr;
|
||||
int len;
|
||||
bool corrupt = false;
|
||||
xfs_daddr_t bno;
|
||||
|
||||
/* no verification of non-crc buffers */
|
||||
|
@ -140,11 +139,11 @@ xfs_attr3_rmt_read_verify(
|
|||
while (len > 0) {
|
||||
if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
|
||||
XFS_ATTR3_RMT_CRC_OFF)) {
|
||||
corrupt = true;
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
break;
|
||||
}
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
||||
corrupt = true;
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
break;
|
||||
}
|
||||
len -= XFS_LBSIZE(mp);
|
||||
|
@ -152,10 +151,9 @@ xfs_attr3_rmt_read_verify(
|
|||
bno += mp->m_bsize;
|
||||
}
|
||||
|
||||
if (corrupt) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
} else
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
else
|
||||
ASSERT(len == 0);
|
||||
}
|
||||
|
||||
|
@ -180,9 +178,8 @@ xfs_attr3_rmt_write_verify(
|
|||
|
||||
while (len > 0) {
|
||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
||||
XFS_CORRUPTION_ERROR(__func__,
|
||||
XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
if (bip) {
|
||||
|
|
|
@ -780,12 +780,14 @@ static void
|
|||
xfs_bmbt_read_verify(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
if (!(xfs_btree_lblock_verify_crc(bp) &&
|
||||
xfs_bmbt_verify(bp))) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
if (!xfs_btree_lblock_verify_crc(bp))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_bmbt_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
|
||||
if (bp->b_error) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -794,11 +796,9 @@ xfs_bmbt_write_verify(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
if (!xfs_bmbt_verify(bp)) {
|
||||
xfs_warn(bp->b_target->bt_mount, "bmbt daddr 0x%llx failed", bp->b_bn);
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
xfs_btree_lblock_calc_crc(bp);
|
||||
|
|
|
@ -234,8 +234,7 @@ xfs_btree_lblock_calc_crc(
|
|||
return;
|
||||
if (bip)
|
||||
block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_BTREE_LBLOCK_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -243,8 +242,8 @@ xfs_btree_lblock_verify_crc(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||
return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_BTREE_LBLOCK_CRC_OFF);
|
||||
return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -267,8 +266,7 @@ xfs_btree_sblock_calc_crc(
|
|||
return;
|
||||
if (bip)
|
||||
block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_BTREE_SBLOCK_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -276,8 +274,8 @@ xfs_btree_sblock_verify_crc(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||
return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_BTREE_SBLOCK_CRC_OFF);
|
||||
return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -369,6 +369,20 @@ static inline void xfs_buf_relse(xfs_buf_t *bp)
|
|||
xfs_buf_rele(bp);
|
||||
}
|
||||
|
||||
static inline int
|
||||
xfs_buf_verify_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
|
||||
{
|
||||
return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
cksum_offset);
|
||||
}
|
||||
|
||||
static inline void
|
||||
xfs_buf_update_cksum(struct xfs_buf *bp, unsigned long cksum_offset)
|
||||
{
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
cksum_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling of buftargs.
|
||||
*/
|
||||
|
|
|
@ -185,8 +185,8 @@ xfs_da3_node_write_verify(
|
|||
struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_da3_node_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -196,7 +196,7 @@ xfs_da3_node_write_verify(
|
|||
if (bip)
|
||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DA3_NODE_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_DA3_NODE_CRC_OFF);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -209,18 +209,20 @@ static void
|
|||
xfs_da3_node_read_verify(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
struct xfs_da_blkinfo *info = bp->b_addr;
|
||||
|
||||
switch (be16_to_cpu(info->magic)) {
|
||||
case XFS_DA3_NODE_MAGIC:
|
||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_DA3_NODE_CRC_OFF))
|
||||
if (!xfs_buf_verify_cksum(bp, XFS_DA3_NODE_CRC_OFF)) {
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case XFS_DA_NODE_MAGIC:
|
||||
if (!xfs_da3_node_verify(bp))
|
||||
if (!xfs_da3_node_verify(bp)) {
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case XFS_ATTR_LEAF_MAGIC:
|
||||
case XFS_ATTR3_LEAF_MAGIC:
|
||||
|
@ -237,8 +239,7 @@ xfs_da3_node_read_verify(
|
|||
}
|
||||
|
||||
/* corrupt block */
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_da3_node_buf_ops = {
|
||||
|
|
|
@ -89,6 +89,8 @@ typedef struct xfs_dinode {
|
|||
/* structure must be padded to 64 bit alignment */
|
||||
} xfs_dinode_t;
|
||||
|
||||
#define XFS_DINODE_CRC_OFF offsetof(struct xfs_dinode, di_crc)
|
||||
|
||||
#define DI_MAX_FLUSH 0xffff
|
||||
|
||||
/*
|
||||
|
|
|
@ -89,13 +89,14 @@ xfs_dir3_block_read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_DIR3_DATA_CRC_OFF)) ||
|
||||
!xfs_dir3_block_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_dir3_block_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -107,8 +108,8 @@ xfs_dir3_block_write_verify(
|
|||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_dir3_block_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -118,7 +119,7 @@ xfs_dir3_block_write_verify(
|
|||
if (bip)
|
||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
|
||||
|
|
|
@ -241,7 +241,6 @@ static void
|
|||
xfs_dir3_data_reada_verify(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
struct xfs_dir2_data_hdr *hdr = bp->b_addr;
|
||||
|
||||
switch (hdr->magic) {
|
||||
|
@ -255,8 +254,8 @@ xfs_dir3_data_reada_verify(
|
|||
xfs_dir3_data_verify(bp);
|
||||
return;
|
||||
default:
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -267,13 +266,14 @@ xfs_dir3_data_read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_DIR3_DATA_CRC_OFF)) ||
|
||||
!xfs_dir3_data_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_dir3_data_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -285,8 +285,8 @@ xfs_dir3_data_write_verify(
|
|||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_dir3_data_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -296,7 +296,7 @@ xfs_dir3_data_write_verify(
|
|||
if (bip)
|
||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_DATA_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_DIR3_DATA_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_dir3_data_buf_ops = {
|
||||
|
|
|
@ -179,13 +179,14 @@ __read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_DIR3_LEAF_CRC_OFF)) ||
|
||||
!xfs_dir3_leaf_verify(bp, magic)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_dir3_leaf_verify(bp, magic))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -198,8 +199,8 @@ __write_verify(
|
|||
struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_dir3_leaf_verify(bp, magic)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -209,7 +210,7 @@ __write_verify(
|
|||
if (bip)
|
||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_LEAF_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_DIR3_LEAF_CRC_OFF);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -115,13 +115,14 @@ xfs_dir3_free_read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
XFS_DIR3_FREE_CRC_OFF)) ||
|
||||
!xfs_dir3_free_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_dir3_free_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -133,8 +134,8 @@ xfs_dir3_free_write_verify(
|
|||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||
|
||||
if (!xfs_dir3_free_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -144,7 +145,7 @@ xfs_dir3_free_write_verify(
|
|||
if (bip)
|
||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length), XFS_DIR3_FREE_CRC_OFF);
|
||||
xfs_buf_update_cksum(bp, XFS_DIR3_FREE_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_dir3_free_buf_ops = {
|
||||
|
|
|
@ -257,10 +257,13 @@ xfs_dquot_buf_read_verify(
|
|||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (!xfs_dquot_buf_verify_crc(mp, bp))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_dquot_buf_verify(mp, bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -275,8 +278,8 @@ xfs_dquot_buf_write_verify(
|
|||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
if (!xfs_dquot_buf_verify(mp, bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ xfs_error_report(
|
|||
{
|
||||
if (level <= xfs_error_level) {
|
||||
xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
|
||||
"Internal error %s at line %d of file %s. Caller 0x%p",
|
||||
"Internal error %s at line %d of file %s. Caller %pF",
|
||||
tag, linenum, filename, ra);
|
||||
|
||||
xfs_stack_trace();
|
||||
|
@ -178,3 +178,28 @@ xfs_corruption_error(
|
|||
xfs_error_report(tag, level, mp, filename, linenum, ra);
|
||||
xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
|
||||
}
|
||||
|
||||
/*
|
||||
* Warnings specifically for verifier errors. Differentiate CRC vs. invalid
|
||||
* values, and omit the stack trace unless the error level is tuned high.
|
||||
*/
|
||||
void
|
||||
xfs_verifier_error(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
|
||||
xfs_alert(mp, "Metadata %s detected at %pF, block 0x%llx",
|
||||
bp->b_error == EFSBADCRC ? "CRC error" : "corruption",
|
||||
__return_address, bp->b_bn);
|
||||
|
||||
xfs_alert(mp, "Unmount and run xfs_repair");
|
||||
|
||||
if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
|
||||
xfs_alert(mp, "First 64 bytes of corrupted metadata buffer:");
|
||||
xfs_hex_dump(xfs_buf_offset(bp, 0), 64);
|
||||
}
|
||||
|
||||
if (xfs_error_level >= XFS_ERRLEVEL_HIGH)
|
||||
xfs_stack_trace();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ extern void xfs_error_report(const char *tag, int level, struct xfs_mount *mp,
|
|||
extern void xfs_corruption_error(const char *tag, int level,
|
||||
struct xfs_mount *mp, void *p, const char *filename,
|
||||
int linenum, inst_t *ra);
|
||||
extern void xfs_verifier_error(struct xfs_buf *bp);
|
||||
|
||||
#define XFS_ERROR_REPORT(e, lvl, mp) \
|
||||
xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
|
||||
|
|
|
@ -145,6 +145,8 @@ struct xfs_dsymlink_hdr {
|
|||
__be64 sl_lsn;
|
||||
};
|
||||
|
||||
#define XFS_SYMLINK_CRC_OFF offsetof(struct xfs_dsymlink_hdr, sl_crc)
|
||||
|
||||
/*
|
||||
* The maximum pathlen is 1024 bytes. Since the minimum file system
|
||||
* blocksize is 512 bytes, we can get a max of 3 extents back from
|
||||
|
|
|
@ -1568,18 +1568,17 @@ xfs_agi_read_verify(
|
|||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||
int agi_ok = 1;
|
||||
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
||||
agi_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agi, agi_crc));
|
||||
agi_ok = agi_ok && xfs_agi_verify(bp);
|
||||
|
||||
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
|
||||
XFS_RANDOM_IALLOC_READ_AGI))) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||
!xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (XFS_TEST_ERROR(!xfs_agi_verify(bp), mp,
|
||||
XFS_ERRTAG_IALLOC_READ_AGI,
|
||||
XFS_RANDOM_IALLOC_READ_AGI))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1590,8 +1589,8 @@ xfs_agi_write_verify(
|
|||
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
||||
|
||||
if (!xfs_agi_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1600,8 +1599,7 @@ xfs_agi_write_verify(
|
|||
|
||||
if (bip)
|
||||
XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_agi, agi_crc));
|
||||
xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_agi_buf_ops = {
|
||||
|
|
|
@ -243,12 +243,14 @@ static void
|
|||
xfs_inobt_read_verify(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
if (!(xfs_btree_sblock_verify_crc(bp) &&
|
||||
xfs_inobt_verify(bp))) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
if (!xfs_btree_sblock_verify_crc(bp))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_inobt_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
|
||||
if (bp->b_error) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,9 +260,9 @@ xfs_inobt_write_verify(
|
|||
{
|
||||
if (!xfs_inobt_verify(bp)) {
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
bp->b_target->bt_mount, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
xfs_btree_sblock_calc_crc(bp);
|
||||
|
||||
|
|
|
@ -102,8 +102,7 @@ xfs_inode_buf_verify(
|
|||
}
|
||||
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
|
||||
mp, dip);
|
||||
xfs_verifier_error(bp);
|
||||
#ifdef DEBUG
|
||||
xfs_alert(mp,
|
||||
"bad inode magic/vsn daddr %lld #%d (magic=%x)",
|
||||
|
@ -306,7 +305,7 @@ xfs_dinode_verify(
|
|||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
return false;
|
||||
if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
|
||||
offsetof(struct xfs_dinode, di_crc)))
|
||||
XFS_DINODE_CRC_OFF))
|
||||
return false;
|
||||
if (be64_to_cpu(dip->di_ino) != ip->i_ino)
|
||||
return false;
|
||||
|
@ -327,7 +326,7 @@ xfs_dinode_calc_crc(
|
|||
|
||||
ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
|
||||
crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
|
||||
offsetof(struct xfs_dinode, di_crc));
|
||||
XFS_DINODE_CRC_OFF);
|
||||
dip->di_crc = xfs_end_cksum(crc);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ typedef __uint64_t __psunsigned_t;
|
|||
#include "xfs_iops.h"
|
||||
#include "xfs_aops.h"
|
||||
#include "xfs_super.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_buf.h"
|
||||
#include "xfs_message.h"
|
||||
|
||||
|
@ -178,6 +179,7 @@ typedef __uint64_t __psunsigned_t;
|
|||
#define ENOATTR ENODATA /* Attribute not found */
|
||||
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
|
||||
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
|
||||
#define EFSBADCRC EBADMSG /* Bad CRC detected */
|
||||
|
||||
#define SYNCHRONIZE() barrier()
|
||||
#define __return_address __builtin_return_address(0)
|
||||
|
|
|
@ -611,12 +611,11 @@ xfs_sb_read_verify(
|
|||
XFS_SB_VERSION_5) ||
|
||||
dsb->sb_crc != 0)) {
|
||||
|
||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_sb, sb_crc))) {
|
||||
if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) {
|
||||
/* Only fail bad secondaries on a known V5 filesystem */
|
||||
if (bp->b_bn == XFS_SB_DADDR ||
|
||||
xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||
error = EFSCORRUPTED;
|
||||
error = EFSBADCRC;
|
||||
goto out_error;
|
||||
}
|
||||
}
|
||||
|
@ -625,10 +624,9 @@ xfs_sb_read_verify(
|
|||
|
||||
out_error:
|
||||
if (error) {
|
||||
if (error == EFSCORRUPTED)
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, error);
|
||||
if (error == EFSCORRUPTED || error == EFSBADCRC)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,9 +661,8 @@ xfs_sb_write_verify(
|
|||
|
||||
error = xfs_sb_verify(bp, false);
|
||||
if (error) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
||||
mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, error);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -675,8 +672,7 @@ xfs_sb_write_verify(
|
|||
if (bip)
|
||||
XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_sb, sb_crc));
|
||||
xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_sb_buf_ops = {
|
||||
|
|
|
@ -182,6 +182,8 @@ typedef struct xfs_sb {
|
|||
/* must be padded to 64 bit alignment */
|
||||
} xfs_sb_t;
|
||||
|
||||
#define XFS_SB_CRC_OFF offsetof(struct xfs_sb, sb_crc)
|
||||
|
||||
/*
|
||||
* Superblock - on disk version. Must match the in core version above.
|
||||
* Must be padded to 64 bit alignment.
|
||||
|
|
|
@ -133,12 +133,13 @@ xfs_symlink_read_verify(
|
|||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||
return;
|
||||
|
||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_dsymlink_hdr, sl_crc)) ||
|
||||
!xfs_symlink_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF))
|
||||
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||
else if (!xfs_symlink_verify(bp))
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
}
|
||||
|
||||
if (bp->b_error)
|
||||
xfs_verifier_error(bp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -153,8 +154,8 @@ xfs_symlink_write_verify(
|
|||
return;
|
||||
|
||||
if (!xfs_symlink_verify(bp)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||
xfs_verifier_error(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -162,8 +163,7 @@ xfs_symlink_write_verify(
|
|||
struct xfs_dsymlink_hdr *dsl = bp->b_addr;
|
||||
dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||
}
|
||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
||||
offsetof(struct xfs_dsymlink_hdr, sl_crc));
|
||||
xfs_buf_update_cksum(bp, XFS_SYMLINK_CRC_OFF);
|
||||
}
|
||||
|
||||
const struct xfs_buf_ops xfs_symlink_buf_ops = {
|
||||
|
|
Loading…
Reference in a new issue