mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04: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 */
|
/* structure must be padded to 64 bit alignment */
|
||||||
} xfs_agf_t;
|
} xfs_agf_t;
|
||||||
|
|
||||||
|
#define XFS_AGF_CRC_OFF offsetof(struct xfs_agf, agf_crc)
|
||||||
|
|
||||||
#define XFS_AGF_MAGICNUM 0x00000001
|
#define XFS_AGF_MAGICNUM 0x00000001
|
||||||
#define XFS_AGF_VERSIONNUM 0x00000002
|
#define XFS_AGF_VERSIONNUM 0x00000002
|
||||||
#define XFS_AGF_SEQNO 0x00000004
|
#define XFS_AGF_SEQNO 0x00000004
|
||||||
|
@ -167,6 +169,8 @@ typedef struct xfs_agi {
|
||||||
/* structure must be padded to 64 bit alignment */
|
/* structure must be padded to 64 bit alignment */
|
||||||
} xfs_agi_t;
|
} xfs_agi_t;
|
||||||
|
|
||||||
|
#define XFS_AGI_CRC_OFF offsetof(struct xfs_agi, agi_crc)
|
||||||
|
|
||||||
#define XFS_AGI_MAGICNUM 0x00000001
|
#define XFS_AGI_MAGICNUM 0x00000001
|
||||||
#define XFS_AGI_VERSIONNUM 0x00000002
|
#define XFS_AGI_VERSIONNUM 0x00000002
|
||||||
#define XFS_AGI_SEQNO 0x00000004
|
#define XFS_AGI_SEQNO 0x00000004
|
||||||
|
@ -222,6 +226,8 @@ typedef struct xfs_agfl {
|
||||||
__be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */
|
__be32 agfl_bno[]; /* actually XFS_AGFL_SIZE(mp) */
|
||||||
} xfs_agfl_t;
|
} xfs_agfl_t;
|
||||||
|
|
||||||
|
#define XFS_AGFL_CRC_OFF offsetof(struct xfs_agfl, agfl_crc)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tags for inode radix tree
|
* tags for inode radix tree
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -474,7 +474,6 @@ xfs_agfl_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
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
|
* 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))
|
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
agfl_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
if (!xfs_buf_verify_cksum(bp, XFS_AGFL_CRC_OFF))
|
||||||
offsetof(struct xfs_agfl, agfl_crc));
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
|
else if (!xfs_agfl_verify(bp))
|
||||||
agfl_ok = agfl_ok && xfs_agfl_verify(bp);
|
|
||||||
|
|
||||||
if (!agfl_ok) {
|
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -508,16 +505,15 @@ xfs_agfl_write_verify(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!xfs_agfl_verify(bp)) {
|
if (!xfs_agfl_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bip)
|
if (bip)
|
||||||
XFS_BUF_TO_AGFL(bp)->agfl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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),
|
xfs_buf_update_cksum(bp, XFS_AGFL_CRC_OFF);
|
||||||
offsetof(struct xfs_agfl, agfl_crc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_agfl_buf_ops = {
|
const struct xfs_buf_ops xfs_agfl_buf_ops = {
|
||||||
|
@ -2238,19 +2234,17 @@ xfs_agf_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
int agf_ok = 1;
|
|
||||||
|
|
||||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
agf_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_AGF_CRC_OFF))
|
||||||
offsetof(struct xfs_agf, agf_crc));
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
|
else if (XFS_TEST_ERROR(!xfs_agf_verify(mp, bp), mp,
|
||||||
agf_ok = agf_ok && xfs_agf_verify(mp, bp);
|
XFS_ERRTAG_ALLOC_READ_AGF,
|
||||||
|
XFS_RANDOM_ALLOC_READ_AGF))
|
||||||
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);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2261,8 +2255,8 @@ xfs_agf_write_verify(
|
||||||
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
||||||
|
|
||||||
if (!xfs_agf_verify(mp, bp)) {
|
if (!xfs_agf_verify(mp, bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2272,8 +2266,7 @@ xfs_agf_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
XFS_BUF_TO_AGF(bp)->agf_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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),
|
xfs_buf_update_cksum(bp, XFS_AGF_CRC_OFF);
|
||||||
offsetof(struct xfs_agf, agf_crc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_agf_buf_ops = {
|
const struct xfs_buf_ops xfs_agf_buf_ops = {
|
||||||
|
|
|
@ -355,12 +355,14 @@ static void
|
||||||
xfs_allocbt_read_verify(
|
xfs_allocbt_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (!(xfs_btree_sblock_verify_crc(bp) &&
|
if (!xfs_btree_sblock_verify_crc(bp))
|
||||||
xfs_allocbt_verify(bp))) {
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
else if (!xfs_allocbt_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
|
||||||
bp->b_target->bt_mount, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
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)) {
|
if (!xfs_allocbt_verify(bp)) {
|
||||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
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_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
xfs_btree_sblock_calc_crc(bp);
|
xfs_btree_sblock_calc_crc(bp);
|
||||||
|
|
||||||
|
|
|
@ -213,8 +213,8 @@ xfs_attr3_leaf_write_verify(
|
||||||
struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
|
struct xfs_attr3_leaf_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_attr3_leaf_verify(bp)) {
|
if (!xfs_attr3_leaf_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ xfs_attr3_leaf_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_ATTR3_LEAF_CRC_OFF))
|
||||||
XFS_ATTR3_LEAF_CRC_OFF)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_attr3_leaf_verify(bp)) {
|
else if (!xfs_attr3_leaf_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_attr3_leaf_buf_ops = {
|
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;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int len;
|
int len;
|
||||||
bool corrupt = false;
|
|
||||||
xfs_daddr_t bno;
|
xfs_daddr_t bno;
|
||||||
|
|
||||||
/* no verification of non-crc buffers */
|
/* no verification of non-crc buffers */
|
||||||
|
@ -140,11 +139,11 @@ xfs_attr3_rmt_read_verify(
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
|
if (!xfs_verify_cksum(ptr, XFS_LBSIZE(mp),
|
||||||
XFS_ATTR3_RMT_CRC_OFF)) {
|
XFS_ATTR3_RMT_CRC_OFF)) {
|
||||||
corrupt = true;
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
||||||
corrupt = true;
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
len -= XFS_LBSIZE(mp);
|
len -= XFS_LBSIZE(mp);
|
||||||
|
@ -152,10 +151,9 @@ xfs_attr3_rmt_read_verify(
|
||||||
bno += mp->m_bsize;
|
bno += mp->m_bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (corrupt) {
|
if (bp->b_error)
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
xfs_verifier_error(bp);
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
else
|
||||||
} else
|
|
||||||
ASSERT(len == 0);
|
ASSERT(len == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,9 +178,8 @@ xfs_attr3_rmt_write_verify(
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
if (!xfs_attr3_rmt_verify(mp, ptr, XFS_LBSIZE(mp), bno)) {
|
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_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (bip) {
|
if (bip) {
|
||||||
|
|
|
@ -780,12 +780,14 @@ static void
|
||||||
xfs_bmbt_read_verify(
|
xfs_bmbt_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (!(xfs_btree_lblock_verify_crc(bp) &&
|
if (!xfs_btree_lblock_verify_crc(bp))
|
||||||
xfs_bmbt_verify(bp))) {
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
else if (!xfs_bmbt_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
|
||||||
bp->b_target->bt_mount, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
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)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (!xfs_bmbt_verify(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_);
|
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_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xfs_btree_lblock_calc_crc(bp);
|
xfs_btree_lblock_calc_crc(bp);
|
||||||
|
|
|
@ -234,8 +234,7 @@ xfs_btree_lblock_calc_crc(
|
||||||
return;
|
return;
|
||||||
if (bip)
|
if (bip)
|
||||||
block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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_buf_update_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
|
||||||
XFS_BTREE_LBLOCK_CRC_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -243,8 +242,8 @@ xfs_btree_lblock_verify_crc(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||||
return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
|
||||||
XFS_BTREE_LBLOCK_CRC_OFF);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,8 +266,7 @@ xfs_btree_sblock_calc_crc(
|
||||||
return;
|
return;
|
||||||
if (bip)
|
if (bip)
|
||||||
block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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_buf_update_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
|
||||||
XFS_BTREE_SBLOCK_CRC_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -276,8 +274,8 @@ xfs_btree_sblock_verify_crc(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb))
|
||||||
return xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
|
||||||
XFS_BTREE_SBLOCK_CRC_OFF);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -369,6 +369,20 @@ static inline void xfs_buf_relse(xfs_buf_t *bp)
|
||||||
xfs_buf_rele(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.
|
* Handling of buftargs.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -185,8 +185,8 @@ xfs_da3_node_write_verify(
|
||||||
struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
|
struct xfs_da3_node_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_da3_node_verify(bp)) {
|
if (!xfs_da3_node_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ xfs_da3_node_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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(
|
xfs_da3_node_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
|
||||||
struct xfs_da_blkinfo *info = bp->b_addr;
|
struct xfs_da_blkinfo *info = bp->b_addr;
|
||||||
|
|
||||||
switch (be16_to_cpu(info->magic)) {
|
switch (be16_to_cpu(info->magic)) {
|
||||||
case XFS_DA3_NODE_MAGIC:
|
case XFS_DA3_NODE_MAGIC:
|
||||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
if (!xfs_buf_verify_cksum(bp, XFS_DA3_NODE_CRC_OFF)) {
|
||||||
XFS_DA3_NODE_CRC_OFF))
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case XFS_DA_NODE_MAGIC:
|
case XFS_DA_NODE_MAGIC:
|
||||||
if (!xfs_da3_node_verify(bp))
|
if (!xfs_da3_node_verify(bp)) {
|
||||||
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case XFS_ATTR_LEAF_MAGIC:
|
case XFS_ATTR_LEAF_MAGIC:
|
||||||
case XFS_ATTR3_LEAF_MAGIC:
|
case XFS_ATTR3_LEAF_MAGIC:
|
||||||
|
@ -237,8 +239,7 @@ xfs_da3_node_read_verify(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* corrupt block */
|
/* corrupt block */
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
xfs_verifier_error(bp);
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_da3_node_buf_ops = {
|
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 */
|
/* structure must be padded to 64 bit alignment */
|
||||||
} xfs_dinode_t;
|
} xfs_dinode_t;
|
||||||
|
|
||||||
|
#define XFS_DINODE_CRC_OFF offsetof(struct xfs_dinode, di_crc)
|
||||||
|
|
||||||
#define DI_MAX_FLUSH 0xffff
|
#define DI_MAX_FLUSH 0xffff
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -89,13 +89,14 @@ xfs_dir3_block_read_verify(
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
|
||||||
XFS_DIR3_DATA_CRC_OFF)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_dir3_block_verify(bp)) {
|
else if (!xfs_dir3_block_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -107,8 +108,8 @@ xfs_dir3_block_write_verify(
|
||||||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_dir3_block_verify(bp)) {
|
if (!xfs_dir3_block_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +119,7 @@ xfs_dir3_block_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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 = {
|
const struct xfs_buf_ops xfs_dir3_block_buf_ops = {
|
||||||
|
|
|
@ -241,7 +241,6 @@ static void
|
||||||
xfs_dir3_data_reada_verify(
|
xfs_dir3_data_reada_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
|
||||||
struct xfs_dir2_data_hdr *hdr = bp->b_addr;
|
struct xfs_dir2_data_hdr *hdr = bp->b_addr;
|
||||||
|
|
||||||
switch (hdr->magic) {
|
switch (hdr->magic) {
|
||||||
|
@ -255,8 +254,8 @@ xfs_dir3_data_reada_verify(
|
||||||
xfs_dir3_data_verify(bp);
|
xfs_dir3_data_verify(bp);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, hdr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,13 +266,14 @@ xfs_dir3_data_read_verify(
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_DIR3_DATA_CRC_OFF))
|
||||||
XFS_DIR3_DATA_CRC_OFF)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_dir3_data_verify(bp)) {
|
else if (!xfs_dir3_data_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -285,8 +285,8 @@ xfs_dir3_data_write_verify(
|
||||||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_dir3_data_verify(bp)) {
|
if (!xfs_dir3_data_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ xfs_dir3_data_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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 = {
|
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;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_DIR3_LEAF_CRC_OFF))
|
||||||
XFS_DIR3_LEAF_CRC_OFF)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_dir3_leaf_verify(bp, magic)) {
|
else if (!xfs_dir3_leaf_verify(bp, magic))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -198,8 +199,8 @@ __write_verify(
|
||||||
struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
|
struct xfs_dir3_leaf_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_dir3_leaf_verify(bp, magic)) {
|
if (!xfs_dir3_leaf_verify(bp, magic)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +210,7 @@ __write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->info.lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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
|
static void
|
||||||
|
|
|
@ -115,13 +115,14 @@ xfs_dir3_free_read_verify(
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if ((xfs_sb_version_hascrc(&mp->m_sb) &&
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_DIR3_FREE_CRC_OFF))
|
||||||
XFS_DIR3_FREE_CRC_OFF)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_dir3_free_verify(bp)) {
|
else if (!xfs_dir3_free_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -133,8 +134,8 @@ xfs_dir3_free_write_verify(
|
||||||
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
struct xfs_dir3_blk_hdr *hdr3 = bp->b_addr;
|
||||||
|
|
||||||
if (!xfs_dir3_free_verify(bp)) {
|
if (!xfs_dir3_free_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +145,7 @@ xfs_dir3_free_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
hdr3->lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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 = {
|
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;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if (!xfs_dquot_buf_verify_crc(mp, bp) || !xfs_dquot_buf_verify(mp, bp)) {
|
if (!xfs_dquot_buf_verify_crc(mp, bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
|
else if (!xfs_dquot_buf_verify(mp, bp))
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
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;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
|
|
||||||
if (!xfs_dquot_buf_verify(mp, bp)) {
|
if (!xfs_dquot_buf_verify(mp, bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,7 @@ xfs_error_report(
|
||||||
{
|
{
|
||||||
if (level <= xfs_error_level) {
|
if (level <= xfs_error_level) {
|
||||||
xfs_alert_tag(mp, XFS_PTAG_ERROR_REPORT,
|
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);
|
tag, linenum, filename, ra);
|
||||||
|
|
||||||
xfs_stack_trace();
|
xfs_stack_trace();
|
||||||
|
@ -178,3 +178,28 @@ xfs_corruption_error(
|
||||||
xfs_error_report(tag, level, mp, filename, linenum, ra);
|
xfs_error_report(tag, level, mp, filename, linenum, ra);
|
||||||
xfs_alert(mp, "Corruption detected. Unmount and run xfs_repair");
|
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,
|
extern void xfs_corruption_error(const char *tag, int level,
|
||||||
struct xfs_mount *mp, void *p, const char *filename,
|
struct xfs_mount *mp, void *p, const char *filename,
|
||||||
int linenum, inst_t *ra);
|
int linenum, inst_t *ra);
|
||||||
|
extern void xfs_verifier_error(struct xfs_buf *bp);
|
||||||
|
|
||||||
#define XFS_ERROR_REPORT(e, lvl, mp) \
|
#define XFS_ERROR_REPORT(e, lvl, mp) \
|
||||||
xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
|
xfs_error_report(e, lvl, mp, __FILE__, __LINE__, __return_address)
|
||||||
|
|
|
@ -145,6 +145,8 @@ struct xfs_dsymlink_hdr {
|
||||||
__be64 sl_lsn;
|
__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
|
* 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
|
* 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_buf *bp)
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = bp->b_target->bt_mount;
|
struct xfs_mount *mp = bp->b_target->bt_mount;
|
||||||
int agi_ok = 1;
|
|
||||||
|
|
||||||
if (xfs_sb_version_hascrc(&mp->m_sb))
|
if (xfs_sb_version_hascrc(&mp->m_sb) &&
|
||||||
agi_ok = xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
!xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF))
|
||||||
offsetof(struct xfs_agi, agi_crc));
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
agi_ok = agi_ok && xfs_agi_verify(bp);
|
else if (XFS_TEST_ERROR(!xfs_agi_verify(bp), mp,
|
||||||
|
XFS_ERRTAG_IALLOC_READ_AGI,
|
||||||
if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
|
XFS_RANDOM_IALLOC_READ_AGI))
|
||||||
XFS_RANDOM_IALLOC_READ_AGI))) {
|
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1590,8 +1589,8 @@ xfs_agi_write_verify(
|
||||||
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
struct xfs_buf_log_item *bip = bp->b_fspriv;
|
||||||
|
|
||||||
if (!xfs_agi_verify(bp)) {
|
if (!xfs_agi_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1600,8 +1599,7 @@ xfs_agi_write_verify(
|
||||||
|
|
||||||
if (bip)
|
if (bip)
|
||||||
XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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),
|
xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF);
|
||||||
offsetof(struct xfs_agi, agi_crc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_agi_buf_ops = {
|
const struct xfs_buf_ops xfs_agi_buf_ops = {
|
||||||
|
|
|
@ -243,12 +243,14 @@ static void
|
||||||
xfs_inobt_read_verify(
|
xfs_inobt_read_verify(
|
||||||
struct xfs_buf *bp)
|
struct xfs_buf *bp)
|
||||||
{
|
{
|
||||||
if (!(xfs_btree_sblock_verify_crc(bp) &&
|
if (!xfs_btree_sblock_verify_crc(bp))
|
||||||
xfs_inobt_verify(bp))) {
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
else if (!xfs_inobt_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
|
||||||
bp->b_target->bt_mount, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
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)) {
|
if (!xfs_inobt_verify(bp)) {
|
||||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
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_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
xfs_btree_sblock_calc_crc(bp);
|
xfs_btree_sblock_calc_crc(bp);
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,7 @@ xfs_inode_buf_verify(
|
||||||
}
|
}
|
||||||
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_HIGH,
|
xfs_verifier_error(bp);
|
||||||
mp, dip);
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
xfs_alert(mp,
|
xfs_alert(mp,
|
||||||
"bad inode magic/vsn daddr %lld #%d (magic=%x)",
|
"bad inode magic/vsn daddr %lld #%d (magic=%x)",
|
||||||
|
@ -306,7 +305,7 @@ xfs_dinode_verify(
|
||||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||||
return false;
|
return false;
|
||||||
if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
|
if (!xfs_verify_cksum((char *)dip, mp->m_sb.sb_inodesize,
|
||||||
offsetof(struct xfs_dinode, di_crc)))
|
XFS_DINODE_CRC_OFF))
|
||||||
return false;
|
return false;
|
||||||
if (be64_to_cpu(dip->di_ino) != ip->i_ino)
|
if (be64_to_cpu(dip->di_ino) != ip->i_ino)
|
||||||
return false;
|
return false;
|
||||||
|
@ -327,7 +326,7 @@ xfs_dinode_calc_crc(
|
||||||
|
|
||||||
ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
|
ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
|
||||||
crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
|
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);
|
dip->di_crc = xfs_end_cksum(crc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,7 @@ typedef __uint64_t __psunsigned_t;
|
||||||
#include "xfs_iops.h"
|
#include "xfs_iops.h"
|
||||||
#include "xfs_aops.h"
|
#include "xfs_aops.h"
|
||||||
#include "xfs_super.h"
|
#include "xfs_super.h"
|
||||||
|
#include "xfs_cksum.h"
|
||||||
#include "xfs_buf.h"
|
#include "xfs_buf.h"
|
||||||
#include "xfs_message.h"
|
#include "xfs_message.h"
|
||||||
|
|
||||||
|
@ -178,6 +179,7 @@ typedef __uint64_t __psunsigned_t;
|
||||||
#define ENOATTR ENODATA /* Attribute not found */
|
#define ENOATTR ENODATA /* Attribute not found */
|
||||||
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
|
#define EWRONGFS EINVAL /* Mount with wrong filesystem type */
|
||||||
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
|
#define EFSCORRUPTED EUCLEAN /* Filesystem is corrupted */
|
||||||
|
#define EFSBADCRC EBADMSG /* Bad CRC detected */
|
||||||
|
|
||||||
#define SYNCHRONIZE() barrier()
|
#define SYNCHRONIZE() barrier()
|
||||||
#define __return_address __builtin_return_address(0)
|
#define __return_address __builtin_return_address(0)
|
||||||
|
|
|
@ -611,12 +611,11 @@ xfs_sb_read_verify(
|
||||||
XFS_SB_VERSION_5) ||
|
XFS_SB_VERSION_5) ||
|
||||||
dsb->sb_crc != 0)) {
|
dsb->sb_crc != 0)) {
|
||||||
|
|
||||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
if (!xfs_buf_verify_cksum(bp, XFS_SB_CRC_OFF)) {
|
||||||
offsetof(struct xfs_sb, sb_crc))) {
|
|
||||||
/* Only fail bad secondaries on a known V5 filesystem */
|
/* Only fail bad secondaries on a known V5 filesystem */
|
||||||
if (bp->b_bn == XFS_SB_DADDR ||
|
if (bp->b_bn == XFS_SB_DADDR ||
|
||||||
xfs_sb_version_hascrc(&mp->m_sb)) {
|
xfs_sb_version_hascrc(&mp->m_sb)) {
|
||||||
error = EFSCORRUPTED;
|
error = EFSBADCRC;
|
||||||
goto out_error;
|
goto out_error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -625,10 +624,9 @@ xfs_sb_read_verify(
|
||||||
|
|
||||||
out_error:
|
out_error:
|
||||||
if (error) {
|
if (error) {
|
||||||
if (error == EFSCORRUPTED)
|
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
|
||||||
mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, error);
|
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);
|
error = xfs_sb_verify(bp, false);
|
||||||
if (error) {
|
if (error) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW,
|
|
||||||
mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, error);
|
xfs_buf_ioerror(bp, error);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,8 +672,7 @@ xfs_sb_write_verify(
|
||||||
if (bip)
|
if (bip)
|
||||||
XFS_BUF_TO_SBP(bp)->sb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
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),
|
xfs_buf_update_cksum(bp, XFS_SB_CRC_OFF);
|
||||||
offsetof(struct xfs_sb, sb_crc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_sb_buf_ops = {
|
const struct xfs_buf_ops xfs_sb_buf_ops = {
|
||||||
|
|
|
@ -182,6 +182,8 @@ typedef struct xfs_sb {
|
||||||
/* must be padded to 64 bit alignment */
|
/* must be padded to 64 bit alignment */
|
||||||
} xfs_sb_t;
|
} 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.
|
* Superblock - on disk version. Must match the in core version above.
|
||||||
* Must be padded to 64 bit alignment.
|
* Must be padded to 64 bit alignment.
|
||||||
|
|
|
@ -133,12 +133,13 @@ xfs_symlink_read_verify(
|
||||||
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
if (!xfs_sb_version_hascrc(&mp->m_sb))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!xfs_verify_cksum(bp->b_addr, BBTOB(bp->b_length),
|
if (!xfs_buf_verify_cksum(bp, XFS_SYMLINK_CRC_OFF))
|
||||||
offsetof(struct xfs_dsymlink_hdr, sl_crc)) ||
|
xfs_buf_ioerror(bp, EFSBADCRC);
|
||||||
!xfs_symlink_verify(bp)) {
|
else if (!xfs_symlink_verify(bp))
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
}
|
|
||||||
|
if (bp->b_error)
|
||||||
|
xfs_verifier_error(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -153,8 +154,8 @@ xfs_symlink_write_verify(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!xfs_symlink_verify(bp)) {
|
if (!xfs_symlink_verify(bp)) {
|
||||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp, bp->b_addr);
|
|
||||||
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
xfs_buf_ioerror(bp, EFSCORRUPTED);
|
||||||
|
xfs_verifier_error(bp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +163,7 @@ xfs_symlink_write_verify(
|
||||||
struct xfs_dsymlink_hdr *dsl = bp->b_addr;
|
struct xfs_dsymlink_hdr *dsl = bp->b_addr;
|
||||||
dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
dsl->sl_lsn = cpu_to_be64(bip->bli_item.li_lsn);
|
||||||
}
|
}
|
||||||
xfs_update_cksum(bp->b_addr, BBTOB(bp->b_length),
|
xfs_buf_update_cksum(bp, XFS_SYMLINK_CRC_OFF);
|
||||||
offsetof(struct xfs_dsymlink_hdr, sl_crc));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct xfs_buf_ops xfs_symlink_buf_ops = {
|
const struct xfs_buf_ops xfs_symlink_buf_ops = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue