mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 16:07:17 -04:00
Merge tag 'corruption-health-reports-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.9-mergeC
xfs: report corruption to the health trackers Any time that the runtime code thinks it has found corrupt metadata, it should tell the health tracking subsystem that the corresponding part of the filesystem is sick. These reports come primarily from two places -- code that is reading a buffer that fails validation, and higher level pieces that observe a conflict involving multiple buffers. This patchset uses automated scanning to update all such callsites with a mark_sick call. Doing this enables the health system to record problem observed at runtime, which (for now) can prompt the sysadmin to run xfs_scrub, and (later) may enable more targetted fixing of the filesystem. Note: Earlier reviewers of this patchset suggested that the verifier functions themselves should be responsible for calling _mark_sick. In a higher level language this would be easily accomplished with lambda functions and closures. For the kernel, however, we'd have to create the necessary closures by hand, pass them to the buf_read calls, and then implement necessary state tracking to detach the xfs_buf from the closure at the necessary time. This is far too much work and complexity and will not be pursued further. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandanbabu@kernel.org> * tag 'corruption-health-reports-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: report XFS_IS_CORRUPT errors to the health system xfs: report realtime metadata corruption errors to the health system xfs: report quota block corruption errors to the health system xfs: report inode corruption errors to the health system xfs: report symlink block corruption errors to the health system xfs: report dir/attr block corruption errors to the health system xfs: report btree block corruption errors to the health system xfs: report block map corruption errors to the health tracking system xfs: report ag header corruption errors to the health tracking system xfs: report fs corruption errors to the health tracking system xfs: separate the marking of sick and checked metadata
This commit is contained in:
@@ -217,6 +217,7 @@ xfs_initialize_perag_data(
|
||||
*/
|
||||
if (fdblocks > sbp->sb_dblocks || ifree > ialloc) {
|
||||
xfs_alert(mp, "AGF corruption. Please run xfs_repair.");
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_COUNTERS);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -950,8 +951,10 @@ xfs_ag_shrink_space(
|
||||
agf = agfbp->b_addr;
|
||||
aglen = be32_to_cpu(agi->agi_length);
|
||||
/* some extra paranoid checks before we shrink the ag */
|
||||
if (XFS_IS_CORRUPT(mp, agf->agf_length != agi->agi_length))
|
||||
if (XFS_IS_CORRUPT(mp, agf->agf_length != agi->agi_length)) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (delta >= aglen)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_ag_resv.h"
|
||||
#include "xfs_bmap.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
struct kmem_cache *xfs_extfree_item_cache;
|
||||
|
||||
@@ -274,6 +275,7 @@ xfs_alloc_complain_bad_rec(
|
||||
xfs_warn(mp,
|
||||
"start block 0x%x block count 0x%x", irec->ar_startblock,
|
||||
irec->ar_blockcount);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -497,14 +499,18 @@ xfs_alloc_fixup_trees(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
i != 1 ||
|
||||
nfbno1 != fbno ||
|
||||
nflen1 != flen))
|
||||
nflen1 != flen)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, fbno, flen, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Look up the record in the by-block tree if necessary.
|
||||
@@ -516,14 +522,18 @@ xfs_alloc_fixup_trees(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
i != 1 ||
|
||||
nfbno1 != fbno ||
|
||||
nflen1 != flen))
|
||||
nflen1 != flen)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if ((error = xfs_alloc_lookup_eq(bno_cur, fbno, flen, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
@@ -536,8 +546,10 @@ xfs_alloc_fixup_trees(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
bnoblock->bb_numrecs !=
|
||||
cntblock->bb_numrecs))
|
||||
cntblock->bb_numrecs)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -567,30 +579,40 @@ xfs_alloc_fixup_trees(
|
||||
*/
|
||||
if ((error = xfs_btree_delete(cnt_cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
/*
|
||||
* Add new by-size btree entry(s).
|
||||
*/
|
||||
if (nfbno1 != NULLAGBLOCK) {
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno1, nflen1, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0))
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if ((error = xfs_btree_insert(cnt_cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
if (nfbno2 != NULLAGBLOCK) {
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, nfbno2, nflen2, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0))
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if ((error = xfs_btree_insert(cnt_cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Fix up the by-block btree entry(s).
|
||||
@@ -601,8 +623,10 @@ xfs_alloc_fixup_trees(
|
||||
*/
|
||||
if ((error = xfs_btree_delete(bno_cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Update the by-block entry to start later|be shorter.
|
||||
@@ -616,12 +640,16 @@ xfs_alloc_fixup_trees(
|
||||
*/
|
||||
if ((error = xfs_alloc_lookup_eq(bno_cur, nfbno2, nflen2, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0))
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if ((error = xfs_btree_insert(bno_cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -755,6 +783,8 @@ xfs_alloc_read_agfl(
|
||||
mp, tp, mp->m_ddev_targp,
|
||||
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGFL_DADDR(mp)),
|
||||
XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_agfl_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGFL);
|
||||
if (error)
|
||||
return error;
|
||||
xfs_buf_set_ref(bp, XFS_AGFL_REF);
|
||||
@@ -776,6 +806,7 @@ xfs_alloc_update_counters(
|
||||
if (unlikely(be32_to_cpu(agf->agf_freeblks) >
|
||||
be32_to_cpu(agf->agf_length))) {
|
||||
xfs_buf_mark_corrupt(agbp);
|
||||
xfs_ag_mark_sick(agbp->b_pag, XFS_SICK_AG_AGF);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -891,8 +922,10 @@ xfs_alloc_cur_check(
|
||||
error = xfs_alloc_get_rec(cur, &bno, &len, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check minlen and deactivate a cntbt cursor if out of acceptable size
|
||||
@@ -1098,6 +1131,7 @@ xfs_alloc_ag_vextent_small(
|
||||
if (error)
|
||||
goto error;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(ccur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -1132,6 +1166,7 @@ xfs_alloc_ag_vextent_small(
|
||||
*fbnop = args->agbno = fbno;
|
||||
*flenp = args->len = 1;
|
||||
if (XFS_IS_CORRUPT(args->mp, fbno >= be32_to_cpu(agf->agf_length))) {
|
||||
xfs_btree_mark_sick(ccur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -1218,6 +1253,7 @@ xfs_alloc_ag_vextent_exact(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1497,8 +1533,10 @@ xfs_alloc_ag_vextent_lastblock(
|
||||
error = xfs_alloc_get_rec(acur->cnt, bno, len, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(acur->cnt);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (*len >= args->minlen)
|
||||
break;
|
||||
error = xfs_btree_increment(acur->cnt, 0, &i);
|
||||
@@ -1710,6 +1748,7 @@ xfs_alloc_ag_vextent_size(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1756,6 +1795,7 @@ xfs_alloc_ag_vextent_size(
|
||||
rlen != 0 &&
|
||||
(rlen > flen ||
|
||||
rbno + rlen > fbno + flen))) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1778,6 +1818,7 @@ xfs_alloc_ag_vextent_size(
|
||||
&i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1790,6 +1831,7 @@ xfs_alloc_ag_vextent_size(
|
||||
rlen != 0 &&
|
||||
(rlen > flen ||
|
||||
rbno + rlen > fbno + flen))) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1806,6 +1848,7 @@ xfs_alloc_ag_vextent_size(
|
||||
&i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(args->mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1844,6 +1887,7 @@ xfs_alloc_ag_vextent_size(
|
||||
|
||||
rlen = args->len;
|
||||
if (XFS_IS_CORRUPT(args->mp, rlen > flen)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1863,6 +1907,7 @@ xfs_alloc_ag_vextent_size(
|
||||
if (XFS_IS_CORRUPT(args->mp,
|
||||
args->agbno + args->len >
|
||||
be32_to_cpu(agf->agf_length))) {
|
||||
xfs_ag_mark_sick(args->pag, XFS_SICK_AG_BNOBT);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1938,6 +1983,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_get_rec(bno_cur, <bno, <len, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1953,6 +1999,7 @@ xfs_free_ag_extent(
|
||||
* Very bad.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(mp, ltbno + ltlen > bno)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1971,6 +2018,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_get_rec(bno_cur, >bno, >len, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1986,6 +2034,7 @@ xfs_free_ag_extent(
|
||||
* Very bad.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(mp, bno + len > gtbno)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2006,12 +2055,14 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cnt_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2021,12 +2072,14 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cnt_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2036,6 +2089,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_btree_delete(bno_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2045,6 +2099,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2064,6 +2119,7 @@ xfs_free_ag_extent(
|
||||
i != 1 ||
|
||||
xxbno != ltbno ||
|
||||
xxlen != ltlen)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2088,12 +2144,14 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, ltbno, ltlen, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cnt_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2104,6 +2162,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_btree_decrement(bno_cur, 0, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2123,12 +2182,14 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, gtbno, gtlen, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cnt_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2151,6 +2212,7 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_btree_insert(bno_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bno_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2163,12 +2225,14 @@ xfs_free_ag_extent(
|
||||
if ((error = xfs_alloc_lookup_eq(cnt_cur, nbno, nlen, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
if ((error = xfs_btree_insert(cnt_cur, &i)))
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2698,6 +2762,7 @@ xfs_exact_minlen_extent_available(
|
||||
goto out;
|
||||
|
||||
if (*stat == 0) {
|
||||
xfs_btree_mark_sick(cnt_cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -3268,6 +3333,8 @@ xfs_read_agf(
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
|
||||
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGF_DADDR(mp)),
|
||||
XFS_FSS_TO_BB(mp, 1), flags, agfbpp, &xfs_agf_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGF);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -3895,17 +3962,23 @@ __xfs_free_extent(
|
||||
return -EIO;
|
||||
|
||||
error = xfs_free_extent_fix_freelist(tp, pag, &agbp);
|
||||
if (error)
|
||||
if (error) {
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
|
||||
return error;
|
||||
}
|
||||
|
||||
agf = agbp->b_addr;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, agbno >= mp->m_sb.sb_agblocks)) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
|
||||
error = -EFSCORRUPTED;
|
||||
goto err_release;
|
||||
}
|
||||
|
||||
/* validate the extent size is legal now we have the agf locked */
|
||||
if (XFS_IS_CORRUPT(mp, agbno + len > be32_to_cpu(agf->agf_length))) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_BNOBT);
|
||||
error = -EFSCORRUPTED;
|
||||
goto err_release;
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_errortag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
|
||||
/*
|
||||
@@ -2343,6 +2344,7 @@ xfs_attr3_leaf_lookup_int(
|
||||
entries = xfs_attr3_leaf_entryp(leaf);
|
||||
if (ichdr.count >= args->geo->blksize / 8) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -2362,10 +2364,12 @@ xfs_attr3_leaf_lookup_int(
|
||||
}
|
||||
if (!(probe >= 0 && (!ichdr.count || probe < ichdr.count))) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (!(span <= 4 || be32_to_cpu(entry->hashval) == hashval)) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "xfs_attr_remote.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
#define ATTR_RMTVALUE_MAPSIZE 1 /* # of map entries at once */
|
||||
|
||||
@@ -276,17 +277,18 @@ xfs_attr3_rmt_hdr_set(
|
||||
*/
|
||||
STATIC int
|
||||
xfs_attr_rmtval_copyout(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_buf *bp,
|
||||
xfs_ino_t ino,
|
||||
int *offset,
|
||||
int *valuelen,
|
||||
uint8_t **dst)
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_buf *bp,
|
||||
struct xfs_inode *dp,
|
||||
int *offset,
|
||||
int *valuelen,
|
||||
uint8_t **dst)
|
||||
{
|
||||
char *src = bp->b_addr;
|
||||
xfs_daddr_t bno = xfs_buf_daddr(bp);
|
||||
int len = BBTOB(bp->b_length);
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
char *src = bp->b_addr;
|
||||
xfs_ino_t ino = dp->i_ino;
|
||||
xfs_daddr_t bno = xfs_buf_daddr(bp);
|
||||
int len = BBTOB(bp->b_length);
|
||||
int blksize = mp->m_attr_geo->blksize;
|
||||
|
||||
ASSERT(len >= blksize);
|
||||
|
||||
@@ -302,6 +304,7 @@ xfs_attr_rmtval_copyout(
|
||||
xfs_alert(mp,
|
||||
"remote attribute header mismatch bno/off/len/owner (0x%llx/0x%x/Ox%x/0x%llx)",
|
||||
bno, *offset, byte_cnt, ino);
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
hdr_size = sizeof(struct xfs_attr3_rmt_hdr);
|
||||
@@ -418,10 +421,12 @@ xfs_attr_rmtval_get(
|
||||
dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
|
||||
error = xfs_buf_read(mp->m_ddev_targp, dblkno, dblkcnt,
|
||||
0, &bp, &xfs_attr3_rmt_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dirattr_mark_sick(args->dp, XFS_ATTR_FORK);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino,
|
||||
error = xfs_attr_rmtval_copyout(mp, bp, args->dp,
|
||||
&offset, &valuelen,
|
||||
&dst);
|
||||
xfs_buf_relse(bp);
|
||||
@@ -548,8 +553,10 @@ xfs_attr_rmtval_stale(
|
||||
xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, map->br_startblock == DELAYSTARTBLOCK) ||
|
||||
XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK))
|
||||
XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK)) {
|
||||
xfs_bmap_mark_sick(ip, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_buf_incore(mp->m_ddev_targp,
|
||||
XFS_FSB_TO_DADDR(mp, map->br_startblock),
|
||||
@@ -659,8 +666,10 @@ xfs_attr_rmtval_invalidate(
|
||||
blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1))
|
||||
if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1)) {
|
||||
xfs_bmap_mark_sick(args->dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
error = xfs_attr_rmtval_stale(args->dp, &map, XBF_TRYLOCK);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "xfs_refcount.h"
|
||||
#include "xfs_icache.h"
|
||||
#include "xfs_iomap.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
struct kmem_cache *xfs_bmap_intent_cache;
|
||||
|
||||
@@ -367,6 +368,8 @@ xfs_bmap_check_leaf_extents(
|
||||
error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
|
||||
XFS_BMAP_BTREE_REF,
|
||||
&xfs_bmbt_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_btree_mark_sick(cur);
|
||||
if (error)
|
||||
goto error_norelse;
|
||||
}
|
||||
@@ -383,6 +386,7 @@ xfs_bmap_check_leaf_extents(
|
||||
pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]);
|
||||
bno = be64_to_cpu(*pp);
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, bno))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -453,6 +457,8 @@ xfs_bmap_check_leaf_extents(
|
||||
error = xfs_btree_read_bufl(mp, NULL, bno, &bp,
|
||||
XFS_BMAP_BTREE_REF,
|
||||
&xfs_bmbt_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_btree_mark_sick(cur);
|
||||
if (error)
|
||||
goto error_norelse;
|
||||
}
|
||||
@@ -562,11 +568,15 @@ xfs_bmap_btree_to_extents(
|
||||
pp = XFS_BMAP_BROOT_PTR_ADDR(mp, rblock, 1, ifp->if_broot_bytes);
|
||||
cbno = be64_to_cpu(*pp);
|
||||
#ifdef DEBUG
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1)))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, !xfs_btree_check_lptr(cur, cbno, 1))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
#endif
|
||||
error = xfs_btree_read_bufl(mp, tp, cbno, &cbp, XFS_BMAP_BTREE_REF,
|
||||
&xfs_bmbt_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_btree_mark_sick(cur);
|
||||
if (error)
|
||||
return error;
|
||||
cblock = XFS_BUF_TO_BLOCK(cbp);
|
||||
@@ -878,6 +888,7 @@ xfs_bmap_add_attrfork_btree(
|
||||
goto error0;
|
||||
/* must be at least one entry */
|
||||
if (XFS_IS_CORRUPT(mp, stat != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -960,6 +971,7 @@ xfs_bmap_add_attrfork_local(
|
||||
|
||||
/* should only be called for types that support local format data */
|
||||
ASSERT(0);
|
||||
xfs_bmap_mark_sick(ip, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1143,6 +1155,7 @@ xfs_iread_bmbt_block(
|
||||
(unsigned long long)ip->i_ino);
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, block,
|
||||
sizeof(*block), __this_address);
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1158,6 +1171,7 @@ xfs_iread_bmbt_block(
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
|
||||
"xfs_iread_extents(2)", frp,
|
||||
sizeof(*frp), fa);
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return xfs_bmap_complain_bad_rec(ip, whichfork, fa,
|
||||
&new);
|
||||
}
|
||||
@@ -1201,6 +1215,7 @@ xfs_iread_extents(
|
||||
goto out;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, ir.loaded != ifp->if_nextents)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -1213,6 +1228,8 @@ xfs_iread_extents(
|
||||
smp_store_release(&ifp->if_needextents, 0);
|
||||
return 0;
|
||||
out:
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
xfs_iext_destroy(ifp);
|
||||
return error;
|
||||
}
|
||||
@@ -1292,6 +1309,7 @@ xfs_bmap_last_before(
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1388,8 +1406,10 @@ xfs_bmap_last_offset(
|
||||
if (ifp->if_format == XFS_DINODE_FMT_LOCAL)
|
||||
return 0;
|
||||
|
||||
if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp)))
|
||||
if (XFS_IS_CORRUPT(ip->i_mount, !xfs_ifork_has_extents(ifp))) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_bmap_last_extent(NULL, ip, whichfork, &rec, &is_empty);
|
||||
if (error || is_empty)
|
||||
@@ -1528,6 +1548,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1535,6 +1556,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1542,6 +1564,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1571,6 +1594,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1604,6 +1628,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1632,6 +1657,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1639,6 +1665,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1673,6 +1700,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1698,6 +1726,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1705,6 +1734,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1749,6 +1779,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1785,6 +1816,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1792,6 +1824,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1871,6 +1904,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1878,6 +1912,7 @@ xfs_bmap_add_extent_delay_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(bma->cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2074,30 +2109,35 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_decrement(cur, 0, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_decrement(cur, 0, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2126,18 +2166,21 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_decrement(cur, 0, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2169,18 +2212,21 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_decrement(cur, 0, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2207,6 +2253,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2240,6 +2287,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2277,6 +2325,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2287,6 +2336,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if ((error = xfs_btree_insert(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2317,6 +2367,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2353,6 +2404,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2363,12 +2415,14 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if ((error = xfs_btree_insert(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2405,6 +2459,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2417,6 +2472,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if ((error = xfs_btree_insert(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2429,6 +2485,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2436,6 +2493,7 @@ xfs_bmap_add_extent_unwritten_real(
|
||||
if ((error = xfs_btree_insert(cur, &i)))
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2721,6 +2779,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2728,6 +2787,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2735,6 +2795,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2764,6 +2825,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2794,6 +2856,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2820,6 +2883,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2827,6 +2891,7 @@ xfs_bmap_add_extent_hole_real(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -3900,12 +3965,16 @@ xfs_bmapi_read(
|
||||
ASSERT(!(flags & ~(XFS_BMAPI_ATTRFORK | XFS_BMAPI_ENTIRE)));
|
||||
xfs_assert_ilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
|
||||
|
||||
if (WARN_ON_ONCE(!ifp))
|
||||
if (WARN_ON_ONCE(!ifp)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT))
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (xfs_is_shutdown(mp))
|
||||
return -EIO;
|
||||
@@ -4386,6 +4455,7 @@ xfs_bmapi_write(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -4613,9 +4683,11 @@ xfs_bmapi_convert_delalloc(
|
||||
error = -ENOSPC;
|
||||
if (WARN_ON_ONCE(bma.blkno == NULLFSBLOCK))
|
||||
goto out_finish;
|
||||
error = -EFSCORRUPTED;
|
||||
if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock)))
|
||||
if (WARN_ON_ONCE(!xfs_valid_startblock(ip, bma.got.br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_finish;
|
||||
}
|
||||
|
||||
XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, bma.length));
|
||||
XFS_STATS_INC(mp, xs_xstrat_quick);
|
||||
@@ -4674,6 +4746,7 @@ xfs_bmapi_remap(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -5088,8 +5161,10 @@ xfs_bmap_del_extent_real(
|
||||
error = xfs_bmbt_lookup_eq(cur, &got, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (got.br_startoff == del->br_startoff)
|
||||
@@ -5113,8 +5188,10 @@ xfs_bmap_del_extent_real(
|
||||
}
|
||||
if ((error = xfs_btree_delete(cur, &i)))
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
break;
|
||||
case BMAP_LEFT_FILLING:
|
||||
/*
|
||||
@@ -5186,8 +5263,10 @@ xfs_bmap_del_extent_real(
|
||||
error = xfs_bmbt_lookup_eq(cur, &got, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
/*
|
||||
* Update the btree record back
|
||||
* to the original value.
|
||||
@@ -5203,8 +5282,10 @@ xfs_bmap_del_extent_real(
|
||||
*logflagsp = 0;
|
||||
return -ENOSPC;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
} else
|
||||
*logflagsp |= xfs_ilog_fext(whichfork);
|
||||
|
||||
@@ -5286,8 +5367,10 @@ __xfs_bunmapi(
|
||||
whichfork = xfs_bmapi_whichfork(flags);
|
||||
ASSERT(whichfork != XFS_COW_FORK);
|
||||
ifp = xfs_ifork_ptr(ip, whichfork);
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)))
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp))) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (xfs_is_shutdown(mp))
|
||||
return -EIO;
|
||||
|
||||
@@ -5656,21 +5739,27 @@ xfs_bmse_merge(
|
||||
error = xfs_bmbt_lookup_eq(cur, got, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_btree_delete(cur, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/* lookup and update size of the previous extent */
|
||||
error = xfs_bmbt_lookup_eq(cur, left, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_bmbt_update(cur, &new);
|
||||
if (error)
|
||||
@@ -5718,8 +5807,10 @@ xfs_bmap_shift_update_extent(
|
||||
error = xfs_bmbt_lookup_eq(cur, &prev, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_bmbt_update(cur, got);
|
||||
if (error)
|
||||
@@ -5757,6 +5848,7 @@ xfs_bmap_collapse_extents(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -5779,6 +5871,7 @@ xfs_bmap_collapse_extents(
|
||||
goto del_cursor;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
@@ -5872,6 +5965,7 @@ xfs_bmap_insert_extents(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -5903,11 +5997,13 @@ xfs_bmap_insert_extents(
|
||||
}
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, isnullstartblock(got.br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, stop_fsb > got.br_startoff)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
@@ -5975,6 +6071,7 @@ xfs_bmap_split_extent(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(ifp)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -6006,6 +6103,7 @@ xfs_bmap_split_extent(
|
||||
if (error)
|
||||
goto del_cursor;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
@@ -6033,6 +6131,7 @@ xfs_bmap_split_extent(
|
||||
if (error)
|
||||
goto del_cursor;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
@@ -6040,6 +6139,7 @@ xfs_bmap_split_extent(
|
||||
if (error)
|
||||
goto del_cursor;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto del_cursor;
|
||||
}
|
||||
@@ -6157,8 +6257,10 @@ xfs_bmap_finish_one(
|
||||
bmap->br_startoff, bmap->br_blockcount,
|
||||
bmap->br_state);
|
||||
|
||||
if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK))
|
||||
if (WARN_ON_ONCE(bi->bi_whichfork != XFS_DATA_FORK)) {
|
||||
xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (XFS_TEST_ERROR(false, tp->t_mountp,
|
||||
XFS_ERRTAG_BMAP_FINISH_ONE))
|
||||
@@ -6176,6 +6278,7 @@ xfs_bmap_finish_one(
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
xfs_bmap_mark_sick(bi->bi_owner, bi->bi_whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_rmap_btree.h"
|
||||
#include "xfs_refcount_btree.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Btree magic numbers.
|
||||
@@ -177,6 +178,7 @@ xfs_btree_check_lblock(
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) {
|
||||
if (bp)
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
@@ -243,6 +245,7 @@ xfs_btree_check_sblock(
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) {
|
||||
if (bp)
|
||||
trace_xfs_btree_corrupt(bp, _RET_IP_);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
@@ -318,6 +321,7 @@ xfs_btree_check_ptr(
|
||||
level, index);
|
||||
}
|
||||
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -498,6 +502,8 @@ xfs_btree_dup_cursor(
|
||||
xfs_buf_daddr(bp), mp->m_bsize,
|
||||
0, &bp,
|
||||
cur->bc_ops->buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_btree_mark_sick(new);
|
||||
if (error) {
|
||||
xfs_btree_del_cursor(new, error);
|
||||
*ncur = NULL;
|
||||
@@ -1351,6 +1357,8 @@ xfs_btree_read_buf_block(
|
||||
error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
|
||||
mp->m_bsize, flags, bpp,
|
||||
cur->bc_ops->buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_btree_mark_sick(cur);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
@@ -1661,6 +1669,7 @@ xfs_btree_increment(
|
||||
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
|
||||
goto out0;
|
||||
ASSERT(0);
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1754,6 +1763,7 @@ xfs_btree_decrement(
|
||||
if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
|
||||
goto out0;
|
||||
ASSERT(0);
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1846,6 +1856,7 @@ xfs_btree_lookup_get_block(
|
||||
*blkp = NULL;
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_trans_brelse(cur->bc_tp, bp);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1892,8 +1903,10 @@ xfs_btree_lookup(
|
||||
XFS_BTREE_STATS_INC(cur, lookup);
|
||||
|
||||
/* No such thing as a zero-level tree. */
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
block = NULL;
|
||||
keyno = 0;
|
||||
@@ -1936,6 +1949,7 @@ xfs_btree_lookup(
|
||||
XFS_ERRLEVEL_LOW,
|
||||
cur->bc_mp, block,
|
||||
sizeof(*block));
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -2012,8 +2026,10 @@ xfs_btree_lookup(
|
||||
error = xfs_btree_increment(cur, 0, &i);
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
*stat = 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -2466,6 +2482,7 @@ xfs_btree_lshift(
|
||||
goto error0;
|
||||
i = xfs_btree_firstrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2636,6 +2653,7 @@ xfs_btree_rshift(
|
||||
goto error0;
|
||||
i = xfs_btree_lastrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -3524,6 +3542,7 @@ xfs_btree_insert(
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -3931,6 +3950,7 @@ xfs_btree_delrec(
|
||||
*/
|
||||
i = xfs_btree_lastrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -3939,12 +3959,14 @@ xfs_btree_delrec(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
|
||||
i = xfs_btree_lastrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -3992,6 +4014,7 @@ xfs_btree_delrec(
|
||||
if (!xfs_btree_ptr_is_null(cur, &lptr)) {
|
||||
i = xfs_btree_firstrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -4000,6 +4023,7 @@ xfs_btree_delrec(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -4017,6 +4041,7 @@ xfs_btree_delrec(
|
||||
*/
|
||||
i = xfs_btree_firstrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -4026,6 +4051,7 @@ xfs_btree_delrec(
|
||||
goto error0;
|
||||
i = xfs_btree_firstrec(tcur, level);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -4369,12 +4395,16 @@ xfs_btree_visit_block(
|
||||
*/
|
||||
if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
|
||||
if (be64_to_cpu(rptr.l) == XFS_DADDR_TO_FSB(cur->bc_mp,
|
||||
xfs_buf_daddr(bp)))
|
||||
xfs_buf_daddr(bp))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
} else {
|
||||
if (be32_to_cpu(rptr.s) == xfs_daddr_to_agbno(cur->bc_mp,
|
||||
xfs_buf_daddr(bp)))
|
||||
xfs_buf_daddr(bp))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
return xfs_btree_lookup_get_block(cur, level, &rptr, &block);
|
||||
}
|
||||
@@ -5233,6 +5263,7 @@ xfs_btree_goto_left_edge(
|
||||
return error;
|
||||
if (stat != 0) {
|
||||
ASSERT(0);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_errortag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* xfs_da_btree.c
|
||||
@@ -353,6 +354,8 @@ const struct xfs_buf_ops xfs_da3_node_buf_ops = {
|
||||
static int
|
||||
xfs_da3_node_set_type(
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_inode *dp,
|
||||
int whichfork,
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
struct xfs_da_blkinfo *info = bp->b_addr;
|
||||
@@ -374,6 +377,7 @@ xfs_da3_node_set_type(
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, tp->t_mountp,
|
||||
info, sizeof(*info));
|
||||
xfs_trans_brelse(tp, bp);
|
||||
xfs_dirattr_mark_sick(dp, whichfork);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
@@ -392,7 +396,7 @@ xfs_da3_node_read(
|
||||
&xfs_da3_node_buf_ops);
|
||||
if (error || !*bpp || !tp)
|
||||
return error;
|
||||
return xfs_da3_node_set_type(tp, *bpp);
|
||||
return xfs_da3_node_set_type(tp, dp, whichfork, *bpp);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -409,6 +413,8 @@ xfs_da3_node_read_mapped(
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, mappedbno,
|
||||
XFS_FSB_TO_BB(mp, xfs_dabuf_nfsb(mp, whichfork)), 0,
|
||||
bpp, &xfs_da3_node_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dirattr_mark_sick(dp, whichfork);
|
||||
if (error || !*bpp)
|
||||
return error;
|
||||
|
||||
@@ -419,7 +425,7 @@ xfs_da3_node_read_mapped(
|
||||
|
||||
if (!tp)
|
||||
return 0;
|
||||
return xfs_da3_node_set_type(tp, *bpp);
|
||||
return xfs_da3_node_set_type(tp, dp, whichfork, *bpp);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -632,6 +638,7 @@ xfs_da3_split(
|
||||
if (node->hdr.info.forw) {
|
||||
if (be32_to_cpu(node->hdr.info.forw) != addblk->blkno) {
|
||||
xfs_buf_mark_corrupt(oldblk->bp);
|
||||
xfs_da_mark_sick(state->args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -645,6 +652,7 @@ xfs_da3_split(
|
||||
if (node->hdr.info.back) {
|
||||
if (be32_to_cpu(node->hdr.info.back) != addblk->blkno) {
|
||||
xfs_buf_mark_corrupt(oldblk->bp);
|
||||
xfs_da_mark_sick(state->args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -1636,6 +1644,7 @@ xfs_da3_node_lookup_int(
|
||||
|
||||
if (magic != XFS_DA_NODE_MAGIC && magic != XFS_DA3_NODE_MAGIC) {
|
||||
xfs_buf_mark_corrupt(blk->bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1651,6 +1660,7 @@ xfs_da3_node_lookup_int(
|
||||
/* Tree taller than we can handle; bail out! */
|
||||
if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
|
||||
xfs_buf_mark_corrupt(blk->bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1659,6 +1669,7 @@ xfs_da3_node_lookup_int(
|
||||
expected_level = nodehdr.level - 1;
|
||||
else if (expected_level != nodehdr.level) {
|
||||
xfs_buf_mark_corrupt(blk->bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
} else
|
||||
expected_level--;
|
||||
@@ -1710,12 +1721,16 @@ xfs_da3_node_lookup_int(
|
||||
}
|
||||
|
||||
/* We can't point back to the root. */
|
||||
if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk))
|
||||
if (XFS_IS_CORRUPT(dp->i_mount, blkno == args->geo->leafblk)) {
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0))
|
||||
if (XFS_IS_CORRUPT(dp->i_mount, expected_level != 0)) {
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* A leaf block that ends in the hashval that we are interested in
|
||||
@@ -1733,6 +1748,7 @@ xfs_da3_node_lookup_int(
|
||||
args->blkno = blk->blkno;
|
||||
} else {
|
||||
ASSERT(0);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (((retval == -ENOENT) || (retval == -ENOATTR)) &&
|
||||
@@ -2299,8 +2315,10 @@ xfs_da3_swap_lastblock(
|
||||
error = xfs_bmap_last_before(tp, dp, &lastoff, w);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, lastoff == 0))
|
||||
if (XFS_IS_CORRUPT(mp, lastoff == 0)) {
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
/*
|
||||
* Read the last block in the btree space.
|
||||
*/
|
||||
@@ -2350,6 +2368,7 @@ xfs_da3_swap_lastblock(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
be32_to_cpu(sib_info->forw) != last_blkno ||
|
||||
sib_info->magic != dead_info->magic)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2370,6 +2389,7 @@ xfs_da3_swap_lastblock(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
be32_to_cpu(sib_info->back) != last_blkno ||
|
||||
sib_info->magic != dead_info->magic)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2392,6 +2412,7 @@ xfs_da3_swap_lastblock(
|
||||
xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
level >= 0 && level != par_hdr.level + 1)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2403,6 +2424,7 @@ xfs_da3_swap_lastblock(
|
||||
entno++)
|
||||
continue;
|
||||
if (XFS_IS_CORRUPT(mp, entno == par_hdr.count)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2428,6 +2450,7 @@ xfs_da3_swap_lastblock(
|
||||
xfs_trans_brelse(tp, par_buf);
|
||||
par_buf = NULL;
|
||||
if (XFS_IS_CORRUPT(mp, par_blkno == 0)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2437,6 +2460,7 @@ xfs_da3_swap_lastblock(
|
||||
par_node = par_buf->b_addr;
|
||||
xfs_da3_node_hdr_from_disk(dp->i_mount, &par_hdr, par_node);
|
||||
if (XFS_IS_CORRUPT(mp, par_hdr.level != level)) {
|
||||
xfs_da_mark_sick(args);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2567,6 +2591,7 @@ xfs_dabuf_map(
|
||||
invalid_mapping:
|
||||
/* Caller ok with no mapping. */
|
||||
if (XFS_IS_CORRUPT(mp, !(flags & XFS_DABUF_MAP_HOLE_OK))) {
|
||||
xfs_dirattr_mark_sick(dp, whichfork);
|
||||
error = -EFSCORRUPTED;
|
||||
if (xfs_error_level >= XFS_ERRLEVEL_LOW) {
|
||||
xfs_alert(mp, "%s: bno %u inode %llu",
|
||||
@@ -2648,6 +2673,8 @@ xfs_da_read_buf(
|
||||
|
||||
error = xfs_trans_read_buf_map(mp, tp, mp->m_ddev_targp, mapp, nmap, 0,
|
||||
&bp, ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dirattr_mark_sick(dp, whichfork);
|
||||
if (error)
|
||||
goto out_free;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "xfs_errortag.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
const struct xfs_name xfs_name_dotdot = {
|
||||
.name = (const unsigned char *)"..",
|
||||
@@ -626,8 +627,10 @@ xfs_dir2_isblock(
|
||||
return 0;
|
||||
|
||||
*isblock = true;
|
||||
if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize))
|
||||
if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) {
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Local function prototypes.
|
||||
@@ -152,6 +153,7 @@ xfs_dir3_block_read(
|
||||
__xfs_buf_mark_corrupt(*bpp, fa);
|
||||
xfs_trans_brelse(tp, *bpp);
|
||||
*bpp = NULL;
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
static xfs_failaddr_t xfs_dir2_data_freefind_verify(
|
||||
struct xfs_dir2_data_hdr *hdr, struct xfs_dir2_data_free *bf,
|
||||
@@ -433,6 +434,7 @@ xfs_dir3_data_read(
|
||||
__xfs_buf_mark_corrupt(*bpp, fa);
|
||||
xfs_trans_brelse(tp, *bpp);
|
||||
*bpp = NULL;
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1198,6 +1200,7 @@ xfs_dir2_data_use_free(
|
||||
corrupt:
|
||||
xfs_corruption_error(__func__, XFS_ERRLEVEL_LOW, args->dp->i_mount,
|
||||
hdr, sizeof(*hdr), __FILE__, __LINE__, fa);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Local function declarations.
|
||||
@@ -1393,8 +1394,10 @@ xfs_dir2_leaf_removename(
|
||||
bestsp = xfs_dir2_leaf_bests_p(ltp);
|
||||
if (be16_to_cpu(bestsp[db]) != oldbest) {
|
||||
xfs_buf_mark_corrupt(lbp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the former data entry unused.
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_buf_item.h"
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Function declarations.
|
||||
@@ -231,6 +232,7 @@ __xfs_dir3_free_read(
|
||||
__xfs_buf_mark_corrupt(*bpp, fa);
|
||||
xfs_trans_brelse(tp, *bpp);
|
||||
*bpp = NULL;
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -443,6 +445,7 @@ xfs_dir2_leaf_to_node(
|
||||
if (be32_to_cpu(ltp->bestcount) >
|
||||
(uint)dp->i_disk_size / args->geo->blksize) {
|
||||
xfs_buf_mark_corrupt(lbp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -517,6 +520,7 @@ xfs_dir2_leafn_add(
|
||||
*/
|
||||
if (index < 0) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -736,6 +740,7 @@ xfs_dir2_leafn_lookup_for_addname(
|
||||
cpu_to_be16(NULLDATAOFF))) {
|
||||
if (curfdb != newfdb)
|
||||
xfs_trans_brelse(tp, curbp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
curfdb = newfdb;
|
||||
@@ -804,6 +809,7 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
xfs_dir3_leaf_check(dp, bp);
|
||||
if (leafhdr.count <= 0) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1739,6 +1745,7 @@ xfs_dir2_node_add_datablk(
|
||||
} else {
|
||||
xfs_alert(mp, " ... fblk is NULL");
|
||||
}
|
||||
xfs_da_mark_sick(args);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,15 +26,19 @@
|
||||
* and the "sick" field tells us if that piece was found to need repairs.
|
||||
* Therefore we can conclude that for a given sick flag value:
|
||||
*
|
||||
* - checked && sick => metadata needs repair
|
||||
* - checked && !sick => metadata is ok
|
||||
* - !checked => has not been examined since mount
|
||||
* - checked && sick => metadata needs repair
|
||||
* - checked && !sick => metadata is ok
|
||||
* - !checked && sick => errors have been observed during normal operation,
|
||||
* but the metadata has not been checked thoroughly
|
||||
* - !checked && !sick => has not been examined since mount
|
||||
*/
|
||||
|
||||
struct xfs_mount;
|
||||
struct xfs_perag;
|
||||
struct xfs_inode;
|
||||
struct xfs_fsop_geom;
|
||||
struct xfs_btree_cur;
|
||||
struct xfs_da_args;
|
||||
|
||||
/* Observable health issues for metadata spanning the entire filesystem. */
|
||||
#define XFS_SICK_FS_COUNTERS (1 << 0) /* summary counters */
|
||||
@@ -111,29 +115,56 @@ struct xfs_fsop_geom;
|
||||
XFS_SICK_INO_DIR_ZAPPED | \
|
||||
XFS_SICK_INO_SYMLINK_ZAPPED)
|
||||
|
||||
/* These functions must be provided by the xfs implementation. */
|
||||
/*
|
||||
* These functions must be provided by the xfs implementation. Function
|
||||
* behavior with respect to the first argument should be as follows:
|
||||
*
|
||||
* xfs_*_mark_sick: Set the sick flags and do not set checked flags.
|
||||
* Runtime code should call this upon encountering
|
||||
* a corruption.
|
||||
*
|
||||
* xfs_*_mark_corrupt: Set the sick and checked flags simultaneously.
|
||||
* Fsck tools should call this when corruption is
|
||||
* found.
|
||||
*
|
||||
* xfs_*_mark_healthy: Clear the sick flags and set the checked flags.
|
||||
* Fsck tools should call this after correcting errors.
|
||||
*
|
||||
* xfs_*_measure_sickness: Return the sick and check status in the provided
|
||||
* out parameters.
|
||||
*/
|
||||
|
||||
void xfs_fs_mark_sick(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_fs_mark_corrupt(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_fs_mark_healthy(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_fs_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
|
||||
unsigned int *checked);
|
||||
|
||||
void xfs_rt_mark_sick(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_rt_mark_corrupt(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_rt_mark_healthy(struct xfs_mount *mp, unsigned int mask);
|
||||
void xfs_rt_measure_sickness(struct xfs_mount *mp, unsigned int *sick,
|
||||
unsigned int *checked);
|
||||
|
||||
void xfs_agno_mark_sick(struct xfs_mount *mp, xfs_agnumber_t agno,
|
||||
unsigned int mask);
|
||||
void xfs_ag_mark_sick(struct xfs_perag *pag, unsigned int mask);
|
||||
void xfs_ag_mark_corrupt(struct xfs_perag *pag, unsigned int mask);
|
||||
void xfs_ag_mark_healthy(struct xfs_perag *pag, unsigned int mask);
|
||||
void xfs_ag_measure_sickness(struct xfs_perag *pag, unsigned int *sick,
|
||||
unsigned int *checked);
|
||||
|
||||
void xfs_inode_mark_sick(struct xfs_inode *ip, unsigned int mask);
|
||||
void xfs_inode_mark_corrupt(struct xfs_inode *ip, unsigned int mask);
|
||||
void xfs_inode_mark_healthy(struct xfs_inode *ip, unsigned int mask);
|
||||
void xfs_inode_measure_sickness(struct xfs_inode *ip, unsigned int *sick,
|
||||
unsigned int *checked);
|
||||
|
||||
void xfs_health_unmount(struct xfs_mount *mp);
|
||||
void xfs_bmap_mark_sick(struct xfs_inode *ip, int whichfork);
|
||||
void xfs_btree_mark_sick(struct xfs_btree_cur *cur);
|
||||
void xfs_dirattr_mark_sick(struct xfs_inode *ip, int whichfork);
|
||||
void xfs_da_mark_sick(struct xfs_da_args *args);
|
||||
|
||||
/* Now some helpers. */
|
||||
|
||||
@@ -201,4 +232,7 @@ void xfs_fsop_geom_health(struct xfs_mount *mp, struct xfs_fsop_geom *geo);
|
||||
void xfs_ag_geom_health(struct xfs_perag *pag, struct xfs_ag_geometry *ageo);
|
||||
void xfs_bulkstat_health(struct xfs_inode *ip, struct xfs_bulkstat *bs);
|
||||
|
||||
#define xfs_metadata_is_sick(error) \
|
||||
(unlikely((error) == -EFSCORRUPTED || (error) == -EFSBADCRC))
|
||||
|
||||
#endif /* __XFS_HEALTH_H__ */
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_rmap.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Lookup a record by ino in the btree given by cur.
|
||||
@@ -147,6 +148,7 @@ xfs_inobt_complain_bad_rec(
|
||||
"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);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -571,6 +573,7 @@ xfs_inobt_insert_sprec(
|
||||
if (error)
|
||||
goto error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -587,10 +590,12 @@ xfs_inobt_insert_sprec(
|
||||
if (error)
|
||||
goto error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, rec.ir_startino != nrec->ir_startino)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -600,6 +605,7 @@ xfs_inobt_insert_sprec(
|
||||
* cannot merge, something is seriously wrong.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(mp, !__xfs_inobt_can_merge(nrec, &rec))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -949,8 +955,10 @@ xfs_ialloc_next_rec(
|
||||
error = xfs_inobt_get_rec(cur, rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -974,8 +982,10 @@ xfs_ialloc_get_rec(
|
||||
error = xfs_inobt_get_rec(cur, rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -1053,6 +1063,7 @@ xfs_dialloc_ag_inobt(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1061,6 +1072,7 @@ xfs_dialloc_ag_inobt(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, j != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1219,6 +1231,7 @@ xfs_dialloc_ag_inobt(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1228,6 +1241,7 @@ xfs_dialloc_ag_inobt(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1237,6 +1251,7 @@ xfs_dialloc_ag_inobt(
|
||||
if (error)
|
||||
goto error0;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1297,8 +1312,10 @@ xfs_dialloc_ag_finobt_near(
|
||||
error = xfs_inobt_get_rec(lcur, rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(lcur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we've landed in the parent inode record. The finobt
|
||||
@@ -1322,12 +1339,14 @@ xfs_dialloc_ag_finobt_near(
|
||||
if (error)
|
||||
goto error_rcur;
|
||||
if (XFS_IS_CORRUPT(lcur->bc_mp, j != 1)) {
|
||||
xfs_btree_mark_sick(lcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error_rcur;
|
||||
}
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(lcur->bc_mp, i != 1 && j != 1)) {
|
||||
xfs_btree_mark_sick(lcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error_rcur;
|
||||
}
|
||||
@@ -1383,8 +1402,10 @@ xfs_dialloc_ag_finobt_newino(
|
||||
error = xfs_inobt_get_rec(cur, rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1395,14 +1416,18 @@ xfs_dialloc_ag_finobt_newino(
|
||||
error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_inobt_get_rec(cur, rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1424,14 +1449,18 @@ xfs_dialloc_ag_update_inobt(
|
||||
error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_inobt_get_rec(cur, &rec, &i);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) %
|
||||
XFS_INODES_PER_CHUNK) == 0);
|
||||
|
||||
@@ -1440,8 +1469,10 @@ xfs_dialloc_ag_update_inobt(
|
||||
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp,
|
||||
rec.ir_free != frec->ir_free ||
|
||||
rec.ir_freecount != frec->ir_freecount))
|
||||
rec.ir_freecount != frec->ir_freecount)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
return xfs_inobt_update(cur, &rec);
|
||||
}
|
||||
@@ -1958,6 +1989,7 @@ xfs_difree_inobt(
|
||||
goto error0;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -1968,6 +2000,7 @@ xfs_difree_inobt(
|
||||
goto error0;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error0;
|
||||
}
|
||||
@@ -2080,6 +2113,7 @@ xfs_difree_finobt(
|
||||
* something is out of sync.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(mp, ibtrec->ir_freecount != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -2106,6 +2140,7 @@ xfs_difree_finobt(
|
||||
if (error)
|
||||
goto error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -2116,6 +2151,7 @@ xfs_difree_finobt(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
rec.ir_free != ibtrec->ir_free ||
|
||||
rec.ir_freecount != ibtrec->ir_freecount)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto error;
|
||||
}
|
||||
@@ -2604,6 +2640,8 @@ xfs_read_agi(
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
|
||||
XFS_AG_DADDR(mp, pag->pag_agno, XFS_AGI_DADDR(mp)),
|
||||
XFS_FSS_TO_BB(mp, 1), 0, agibpp, &xfs_agi_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
if (error)
|
||||
return error;
|
||||
if (tp)
|
||||
@@ -2995,6 +3033,7 @@ xfs_ialloc_check_shrink(
|
||||
goto out;
|
||||
|
||||
if (!has) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_INOBT);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_ialloc.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
#include <linux/iversion.h>
|
||||
|
||||
@@ -132,9 +133,14 @@ xfs_imap_to_bp(
|
||||
struct xfs_imap *imap,
|
||||
struct xfs_buf **bpp)
|
||||
{
|
||||
return xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
|
||||
imap->im_len, XBF_UNMAPPED, bpp,
|
||||
&xfs_inode_buf_ops);
|
||||
int error;
|
||||
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, imap->im_blkno,
|
||||
imap->im_len, XBF_UNMAPPED, bpp, &xfs_inode_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_agno_mark_sick(mp, xfs_daddr_to_agno(mp, imap->im_blkno),
|
||||
XFS_SICK_AG_INOBT);
|
||||
return error;
|
||||
}
|
||||
|
||||
static inline struct timespec64 xfs_inode_decode_bigtime(uint64_t ts)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "xfs_attr_leaf.h"
|
||||
#include "xfs_types.h"
|
||||
#include "xfs_errortag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
struct kmem_cache *xfs_ifork_cache;
|
||||
|
||||
@@ -88,6 +89,7 @@ xfs_iformat_local(
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
|
||||
"xfs_iformat_local", dip, sizeof(*dip),
|
||||
__this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -125,6 +127,7 @@ xfs_iformat_extents(
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
|
||||
"xfs_iformat_extents(1)", dip, sizeof(*dip),
|
||||
__this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -144,6 +147,7 @@ xfs_iformat_extents(
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
|
||||
"xfs_iformat_extents(2)",
|
||||
dp, sizeof(*dp), fa);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return xfs_bmap_complain_bad_rec(ip, whichfork,
|
||||
fa, &new);
|
||||
}
|
||||
@@ -202,6 +206,7 @@ xfs_iformat_btree(
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED,
|
||||
"xfs_iformat_btree", dfp, size,
|
||||
__this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -267,12 +272,14 @@ xfs_iformat_data_fork(
|
||||
default:
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
|
||||
dip, sizeof(*dip), __this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
|
||||
sizeof(*dip), __this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
@@ -344,6 +351,7 @@ xfs_iformat_attr_fork(
|
||||
default:
|
||||
xfs_inode_verifier_error(ip, error, __func__, dip,
|
||||
sizeof(*dip), __this_address);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
error = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "xfs_refcount.h"
|
||||
#include "xfs_rmap.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
struct kmem_cache *xfs_refcount_intent_cache;
|
||||
|
||||
@@ -156,6 +157,7 @@ xfs_refcount_complain_bad_rec(
|
||||
xfs_warn(mp,
|
||||
"Start block 0x%x, block count 0x%x, references 0x%x",
|
||||
irec->rc_startblock, irec->rc_blockcount, irec->rc_refcount);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -238,6 +240,7 @@ xfs_refcount_insert(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -268,12 +271,14 @@ xfs_refcount_delete(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
trace_xfs_refcount_delete(cur->bc_mp, cur->bc_ag.pag->pag_agno, &irec);
|
||||
error = xfs_btree_delete(cur, i);
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, *i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -398,6 +403,7 @@ xfs_refcount_split_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -425,6 +431,7 @@ xfs_refcount_split_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -470,6 +477,7 @@ xfs_refcount_merge_center_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -478,6 +486,7 @@ xfs_refcount_merge_center_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -487,6 +496,7 @@ xfs_refcount_merge_center_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -498,6 +508,7 @@ xfs_refcount_merge_center_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -542,6 +553,7 @@ xfs_refcount_merge_left_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -550,6 +562,7 @@ xfs_refcount_merge_left_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -561,6 +574,7 @@ xfs_refcount_merge_left_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -608,6 +622,7 @@ xfs_refcount_merge_right_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -616,6 +631,7 @@ xfs_refcount_merge_right_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -627,6 +643,7 @@ xfs_refcount_merge_right_extent(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -674,6 +691,7 @@ xfs_refcount_find_left_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -693,6 +711,7 @@ xfs_refcount_find_left_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -767,6 +786,7 @@ xfs_refcount_find_right_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -786,6 +806,7 @@ xfs_refcount_find_right_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1142,6 +1163,7 @@ xfs_refcount_adjust_extents(
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp,
|
||||
found_tmp != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1180,6 +1202,7 @@ xfs_refcount_adjust_extents(
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount == 0) ||
|
||||
XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount > *aglen)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1203,6 +1226,7 @@ xfs_refcount_adjust_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1327,8 +1351,10 @@ xfs_refcount_continue_op(
|
||||
struct xfs_perag *pag = cur->bc_ag.pag;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_verify_agbext(pag, new_agbno,
|
||||
ri->ri_blockcount)))
|
||||
ri->ri_blockcount))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
ri->ri_startblock = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
|
||||
|
||||
@@ -1535,6 +1561,7 @@ xfs_refcount_find_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1552,6 +1579,7 @@ xfs_refcount_find_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1585,6 +1613,7 @@ xfs_refcount_find_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1682,6 +1711,7 @@ xfs_refcount_adjust_cow_extents(
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec &&
|
||||
ext.rc_domain != XFS_REFC_DOMAIN_COW)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1697,6 +1727,7 @@ xfs_refcount_adjust_cow_extents(
|
||||
/* Adding a CoW reservation, there should be nothing here. */
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp,
|
||||
agbno + aglen > ext.rc_startblock)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1714,6 +1745,7 @@ xfs_refcount_adjust_cow_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_tmp != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1721,14 +1753,17 @@ xfs_refcount_adjust_cow_extents(
|
||||
case XFS_REFCOUNT_ADJUST_COW_FREE:
|
||||
/* Removing a CoW reservation, there should be one extent. */
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_startblock != agbno)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_blockcount != aglen)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, ext.rc_refcount != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1740,6 +1775,7 @@ xfs_refcount_adjust_cow_extents(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp, found_rec != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1889,8 +1925,10 @@ xfs_refcount_recover_extent(
|
||||
struct xfs_refcount_recovery *rr;
|
||||
|
||||
if (XFS_IS_CORRUPT(cur->bc_mp,
|
||||
be32_to_cpu(rec->refc.rc_refcount) != 1))
|
||||
be32_to_cpu(rec->refc.rc_refcount) != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
rr = kmalloc(sizeof(struct xfs_refcount_recovery),
|
||||
GFP_KERNEL | __GFP_NOFAIL);
|
||||
@@ -1900,6 +1938,7 @@ xfs_refcount_recover_extent(
|
||||
if (xfs_refcount_check_irec(cur->bc_ag.pag, &rr->rr_rrec) != NULL ||
|
||||
XFS_IS_CORRUPT(cur->bc_mp,
|
||||
rr->rr_rrec.rc_domain != XFS_REFC_DOMAIN_COW)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
kfree(rr);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
struct kmem_cache *xfs_rmap_intent_cache;
|
||||
|
||||
@@ -56,8 +57,10 @@ xfs_rmap_lookup_le(
|
||||
error = xfs_rmap_get_rec(cur, irec, &get_stat);
|
||||
if (error)
|
||||
return error;
|
||||
if (!get_stat)
|
||||
if (!get_stat) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -132,6 +135,7 @@ xfs_rmap_insert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 0)) {
|
||||
xfs_btree_mark_sick(rcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -145,6 +149,7 @@ xfs_rmap_insert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(rcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -174,6 +179,7 @@ xfs_rmap_delete(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(rcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -182,6 +188,7 @@ xfs_rmap_delete(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(rcur->bc_mp, i != 1)) {
|
||||
xfs_btree_mark_sick(rcur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -277,6 +284,7 @@ xfs_rmap_complain_bad_rec(
|
||||
"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);
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -512,7 +520,7 @@ xfs_rmap_lookup_le_range(
|
||||
*/
|
||||
static int
|
||||
xfs_rmap_free_check_owner(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_btree_cur *cur,
|
||||
uint64_t ltoff,
|
||||
struct xfs_rmap_irec *rec,
|
||||
xfs_filblks_t len,
|
||||
@@ -520,6 +528,7 @@ xfs_rmap_free_check_owner(
|
||||
uint64_t offset,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct xfs_mount *mp = cur->bc_mp;
|
||||
int error = 0;
|
||||
|
||||
if (owner == XFS_RMAP_OWN_UNKNOWN)
|
||||
@@ -529,12 +538,14 @@ xfs_rmap_free_check_owner(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
(flags & XFS_RMAP_UNWRITTEN) !=
|
||||
(rec->rm_flags & XFS_RMAP_UNWRITTEN))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Make sure the owner matches what we expect to find in the tree. */
|
||||
if (XFS_IS_CORRUPT(mp, owner != rec->rm_owner)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -546,16 +557,19 @@ xfs_rmap_free_check_owner(
|
||||
if (flags & XFS_RMAP_BMBT_BLOCK) {
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
!(rec->rm_flags & XFS_RMAP_BMBT_BLOCK))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (XFS_IS_CORRUPT(mp, rec->rm_offset > offset)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
offset + len > ltoff + rec->rm_blockcount)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -618,6 +632,7 @@ xfs_rmap_unmap(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -639,6 +654,7 @@ xfs_rmap_unmap(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
bno <
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -665,6 +681,7 @@ xfs_rmap_unmap(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -677,12 +694,13 @@ xfs_rmap_unmap(
|
||||
ltrec.rm_startblock > bno ||
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount <
|
||||
bno + len)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
/* Check owner information. */
|
||||
error = xfs_rmap_free_check_owner(mp, ltoff, <rec, len, owner,
|
||||
error = xfs_rmap_free_check_owner(cur, ltoff, <rec, len, owner,
|
||||
offset, flags);
|
||||
if (error)
|
||||
goto out_error;
|
||||
@@ -697,6 +715,7 @@ xfs_rmap_unmap(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -900,6 +919,7 @@ xfs_rmap_map(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
have_lt != 0 &&
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount > bno)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -917,10 +937,12 @@ xfs_rmap_map(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, bno + len > gtrec.rm_startblock)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -974,6 +996,7 @@ xfs_rmap_map(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1021,6 +1044,7 @@ xfs_rmap_map(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -1116,6 +1140,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1153,12 +1178,14 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
LEFT.rm_startblock + LEFT.rm_blockcount >
|
||||
bno)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1181,6 +1208,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1193,10 +1221,12 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1227,6 +1257,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1246,6 +1277,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1257,6 +1289,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1264,6 +1297,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1275,6 +1309,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1282,6 +1317,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1305,6 +1341,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1312,6 +1349,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1331,6 +1369,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1342,6 +1381,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1349,6 +1389,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1419,6 +1460,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1461,6 +1503,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1476,6 +1519,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1509,6 +1553,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1522,6 +1567,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 0)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1534,6 +1580,7 @@ xfs_rmap_convert(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1606,6 +1653,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1634,6 +1682,7 @@ xfs_rmap_convert_shared(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
LEFT.rm_startblock + LEFT.rm_blockcount >
|
||||
bno)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1652,10 +1701,12 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, bno + len > RIGHT.rm_startblock)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1706,6 +1757,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1732,6 +1784,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1758,6 +1811,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1781,6 +1835,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1816,6 +1871,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1861,6 +1917,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1896,6 +1953,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -1934,6 +1992,7 @@ xfs_rmap_convert_shared(
|
||||
if (error)
|
||||
goto done;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto done;
|
||||
}
|
||||
@@ -2023,6 +2082,7 @@ xfs_rmap_unmap_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2033,12 +2093,14 @@ xfs_rmap_unmap_shared(
|
||||
ltrec.rm_startblock > bno ||
|
||||
ltrec.rm_startblock + ltrec.rm_blockcount <
|
||||
bno + len)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
/* Make sure the owner matches what we expect to find in the tree. */
|
||||
if (XFS_IS_CORRUPT(mp, owner != ltrec.rm_owner)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2047,16 +2109,19 @@ xfs_rmap_unmap_shared(
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
(flags & XFS_RMAP_UNWRITTEN) !=
|
||||
(ltrec.rm_flags & XFS_RMAP_UNWRITTEN))) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
/* Check the offset. */
|
||||
if (XFS_IS_CORRUPT(mp, ltrec.rm_offset > offset)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
if (XFS_IS_CORRUPT(mp, offset > ltoff + ltrec.rm_blockcount)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2113,6 +2178,7 @@ xfs_rmap_unmap_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2142,6 +2208,7 @@ xfs_rmap_unmap_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2221,6 +2288,7 @@ xfs_rmap_map_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, have_gt != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2273,6 +2341,7 @@ xfs_rmap_map_shared(
|
||||
if (error)
|
||||
goto out_error;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_error;
|
||||
}
|
||||
@@ -2476,10 +2545,14 @@ xfs_rmap_finish_one(
|
||||
* allocate blocks.
|
||||
*/
|
||||
error = xfs_free_extent_fix_freelist(tp, ri->ri_pag, &agbp);
|
||||
if (error)
|
||||
if (error) {
|
||||
xfs_ag_mark_sick(ri->ri_pag, XFS_SICK_AG_AGFL);
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
|
||||
}
|
||||
if (XFS_IS_CORRUPT(tp->t_mountp, !agbp)) {
|
||||
xfs_ag_mark_sick(ri->ri_pag, XFS_SICK_AG_AGFL);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, ri->ri_pag);
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "xfs_rtalloc.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Realtime allocator bitmap functions shared with userspace.
|
||||
@@ -115,13 +116,19 @@ xfs_rtbuf_get(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map)))
|
||||
if (XFS_IS_CORRUPT(mp, nmap == 0 || !xfs_bmap_is_written_extent(&map))) {
|
||||
xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
|
||||
XFS_SICK_RT_BITMAP);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
ASSERT(map.br_startblock != NULLFSBLOCK);
|
||||
error = xfs_trans_read_buf(mp, args->tp, mp->m_ddev_targp,
|
||||
XFS_FSB_TO_DADDR(mp, map.br_startblock),
|
||||
mp->m_bsize, 0, &bp, &xfs_rtbuf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_rt_mark_sick(mp, issum ? XFS_SICK_RT_SUMMARY :
|
||||
XFS_SICK_RT_BITMAP);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
|
||||
@@ -1290,6 +1290,8 @@ xfs_sb_read_secondary(
|
||||
error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
|
||||
XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
|
||||
XFS_FSS_TO_BB(mp, 1), 0, &bp, &xfs_sb_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_agno_mark_sick(mp, agno, XFS_SICK_AG_SB);
|
||||
if (error)
|
||||
return error;
|
||||
xfs_buf_set_ref(bp, XFS_SSB_REF);
|
||||
|
||||
@@ -175,7 +175,7 @@ xchk_update_health(
|
||||
case XHG_AG:
|
||||
pag = xfs_perag_get(sc->mp, sc->sm->sm_agno);
|
||||
if (bad)
|
||||
xfs_ag_mark_sick(pag, sc->sick_mask);
|
||||
xfs_ag_mark_corrupt(pag, sc->sick_mask);
|
||||
else
|
||||
xfs_ag_mark_healthy(pag, sc->sick_mask);
|
||||
xfs_perag_put(pag);
|
||||
@@ -184,19 +184,19 @@ xchk_update_health(
|
||||
if (!sc->ip)
|
||||
return;
|
||||
if (bad)
|
||||
xfs_inode_mark_sick(sc->ip, sc->sick_mask);
|
||||
xfs_inode_mark_corrupt(sc->ip, sc->sick_mask);
|
||||
else
|
||||
xfs_inode_mark_healthy(sc->ip, sc->sick_mask);
|
||||
break;
|
||||
case XHG_FS:
|
||||
if (bad)
|
||||
xfs_fs_mark_sick(sc->mp, sc->sick_mask);
|
||||
xfs_fs_mark_corrupt(sc->mp, sc->sick_mask);
|
||||
else
|
||||
xfs_fs_mark_healthy(sc->mp, sc->sick_mask);
|
||||
break;
|
||||
case XHG_RT:
|
||||
if (bad)
|
||||
xfs_rt_mark_sick(sc->mp, sc->sick_mask);
|
||||
xfs_rt_mark_corrupt(sc->mp, sc->sick_mask);
|
||||
else
|
||||
xfs_rt_mark_healthy(sc->mp, sc->sick_mask);
|
||||
break;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "xfs_refcount_btree.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_health.h"
|
||||
#include "scrub/xfs_scrub.h"
|
||||
#include "scrub/scrub.h"
|
||||
#include "scrub/common.h"
|
||||
@@ -253,8 +254,10 @@ xrep_refc_walk_rmaps(
|
||||
error = xfs_rmap_get_rec(cur, &rmap, &have_gt);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, !have_gt))
|
||||
if (XFS_IS_CORRUPT(mp, !have_gt)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
if (rmap.rm_owner == XFS_RMAP_OWN_COW) {
|
||||
error = xrep_refc_stash_cow(rr, rmap.rm_startblock,
|
||||
@@ -425,8 +428,10 @@ xrep_refc_push_rmaps_at(
|
||||
error = xfs_btree_decrement(sc->sa.rmap_cur, 0, &have_gt);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(sc->mp, !have_gt))
|
||||
if (XFS_IS_CORRUPT(sc->mp, !have_gt)) {
|
||||
xfs_btree_mark_sick(sc->sa.rmap_cur);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "xfs_quota.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Invalidate any incore buffers associated with this remote attribute value
|
||||
@@ -147,6 +148,7 @@ xfs_attr3_node_inactive(
|
||||
if (level > XFS_DA_NODE_MAXDEPTH) {
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_trans_brelse(*trans, bp); /* no locks for later trans */
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -197,6 +199,7 @@ xfs_attr3_node_inactive(
|
||||
default:
|
||||
xfs_buf_mark_corrupt(child_bp);
|
||||
xfs_trans_brelse(*trans, child_bp);
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
@@ -286,6 +289,7 @@ xfs_attr3_root_inactive(
|
||||
error = xfs_attr3_leaf_inactive(trans, dp, bp);
|
||||
break;
|
||||
default:
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_trans_brelse(*trans, bp);
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
STATIC int
|
||||
xfs_attr_shortform_compare(const void *a, const void *b)
|
||||
@@ -82,8 +83,10 @@ xfs_attr_shortform_list(
|
||||
for (i = 0, sfe = xfs_attr_sf_firstentry(sf); i < sf->count; i++) {
|
||||
if (XFS_IS_CORRUPT(context->dp->i_mount,
|
||||
!xfs_attr_namecheck(sfe->nameval,
|
||||
sfe->namelen)))
|
||||
sfe->namelen))) {
|
||||
xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
context->put_listent(context,
|
||||
sfe->flags,
|
||||
sfe->nameval,
|
||||
@@ -125,6 +128,7 @@ xfs_attr_shortform_list(
|
||||
context->dp->i_mount, sfe,
|
||||
sizeof(*sfe));
|
||||
kfree(sbuf);
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -175,6 +179,7 @@ xfs_attr_shortform_list(
|
||||
if (XFS_IS_CORRUPT(context->dp->i_mount,
|
||||
!xfs_attr_namecheck(sbp->name,
|
||||
sbp->namelen))) {
|
||||
xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
@@ -262,8 +267,10 @@ xfs_attr_node_list_lookup(
|
||||
return 0;
|
||||
|
||||
/* We can't point back to the root. */
|
||||
if (XFS_IS_CORRUPT(mp, cursor->blkno == 0))
|
||||
if (XFS_IS_CORRUPT(mp, cursor->blkno == 0)) {
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (expected_level != 0)
|
||||
@@ -275,6 +282,7 @@ xfs_attr_node_list_lookup(
|
||||
out_corruptbuf:
|
||||
xfs_buf_mark_corrupt(bp);
|
||||
xfs_trans_brelse(tp, bp);
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -304,6 +312,8 @@ xfs_attr_node_list(
|
||||
if (cursor->blkno > 0) {
|
||||
error = xfs_da3_node_read(context->tp, dp, cursor->blkno, &bp,
|
||||
XFS_ATTR_FORK);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dirattr_mark_sick(dp, XFS_ATTR_FORK);
|
||||
if ((error != 0) && (error != -EFSCORRUPTED))
|
||||
return error;
|
||||
if (bp) {
|
||||
@@ -464,8 +474,10 @@ xfs_attr3_leaf_list_int(
|
||||
}
|
||||
|
||||
if (XFS_IS_CORRUPT(context->dp->i_mount,
|
||||
!xfs_attr_namecheck(name, namelen)))
|
||||
!xfs_attr_namecheck(name, namelen))) {
|
||||
xfs_dirattr_mark_sick(context->dp, XFS_ATTR_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
context->put_listent(context, entry->flags,
|
||||
name, namelen, valuelen);
|
||||
if (context->seen_enough)
|
||||
|
||||
@@ -118,8 +118,10 @@ xfs_dir2_sf_getdents(
|
||||
ctx->pos = off & 0x7fffffff;
|
||||
if (XFS_IS_CORRUPT(dp->i_mount,
|
||||
!xfs_dir2_namecheck(sfep->name,
|
||||
sfep->namelen)))
|
||||
sfep->namelen))) {
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino,
|
||||
xfs_dir3_get_dtype(mp, filetype)))
|
||||
return 0;
|
||||
@@ -211,6 +213,7 @@ xfs_dir2_block_getdents(
|
||||
if (XFS_IS_CORRUPT(dp->i_mount,
|
||||
!xfs_dir2_namecheck(dep->name,
|
||||
dep->namelen))) {
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_rele;
|
||||
}
|
||||
@@ -465,6 +468,7 @@ xfs_dir2_leaf_getdents(
|
||||
if (XFS_IS_CORRUPT(dp->i_mount,
|
||||
!xfs_dir2_namecheck(dep->name,
|
||||
dep->namelen))) {
|
||||
xfs_dirattr_mark_sick(dp, XFS_DATA_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Notes on an efficient, low latency fstrim algorithm
|
||||
@@ -210,6 +211,7 @@ xfs_trim_gather_extents(
|
||||
if (error)
|
||||
break;
|
||||
if (XFS_IS_CORRUPT(mp, i != 1)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "xfs_log.h"
|
||||
#include "xfs_bmap_btree.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Lock order:
|
||||
@@ -44,6 +45,29 @@ static struct kmem_cache *xfs_dquot_cache;
|
||||
static struct lock_class_key xfs_dquot_group_class;
|
||||
static struct lock_class_key xfs_dquot_project_class;
|
||||
|
||||
/* Record observations of quota corruption with the health tracking system. */
|
||||
static void
|
||||
xfs_dquot_mark_sick(
|
||||
struct xfs_dquot *dqp)
|
||||
{
|
||||
struct xfs_mount *mp = dqp->q_mount;
|
||||
|
||||
switch (dqp->q_type) {
|
||||
case XFS_DQTYPE_USER:
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_UQUOTA);
|
||||
break;
|
||||
case XFS_DQTYPE_GROUP:
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_GQUOTA);
|
||||
break;
|
||||
case XFS_DQTYPE_PROJ:
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_PQUOTA);
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called to free all the memory associated with a dquot
|
||||
*/
|
||||
@@ -451,6 +475,8 @@ xfs_dquot_disk_read(
|
||||
error = xfs_trans_read_buf(mp, NULL, mp->m_ddev_targp, dqp->q_blkno,
|
||||
mp->m_quotainfo->qi_dqchunklen, 0, &bp,
|
||||
&xfs_dquot_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dquot_mark_sick(dqp);
|
||||
if (error) {
|
||||
ASSERT(bp == NULL);
|
||||
return error;
|
||||
@@ -574,6 +600,7 @@ xfs_dquot_from_disk(
|
||||
"Metadata corruption detected at %pS, quota %u",
|
||||
__this_address, dqp->q_id);
|
||||
xfs_alert(bp->b_mount, "Unmount and run xfs_repair");
|
||||
xfs_dquot_mark_sick(dqp);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1238,6 +1265,8 @@ xfs_qm_dqflush(
|
||||
&bp, &xfs_dquot_buf_ops);
|
||||
if (error == -EAGAIN)
|
||||
goto out_unlock;
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_dquot_mark_sick(dqp);
|
||||
if (error)
|
||||
goto out_abort;
|
||||
|
||||
@@ -1246,6 +1275,7 @@ xfs_qm_dqflush(
|
||||
xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
|
||||
dqp->q_id, fa);
|
||||
xfs_buf_relse(bp);
|
||||
xfs_dquot_mark_sick(dqp);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_abort;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
#include "xfs_trace.h"
|
||||
#include "xfs_health.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_btree.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_quota_defs.h"
|
||||
|
||||
/*
|
||||
* Warn about metadata corruption that we detected but haven't fixed, and
|
||||
@@ -96,6 +100,20 @@ xfs_fs_mark_sick(
|
||||
ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
|
||||
trace_xfs_fs_mark_sick(mp, mask);
|
||||
|
||||
spin_lock(&mp->m_sb_lock);
|
||||
mp->m_fs_sick |= mask;
|
||||
spin_unlock(&mp->m_sb_lock);
|
||||
}
|
||||
|
||||
/* Mark per-fs metadata as having been checked and found unhealthy by fsck. */
|
||||
void
|
||||
xfs_fs_mark_corrupt(
|
||||
struct xfs_mount *mp,
|
||||
unsigned int mask)
|
||||
{
|
||||
ASSERT(!(mask & ~XFS_SICK_FS_PRIMARY));
|
||||
trace_xfs_fs_mark_corrupt(mp, mask);
|
||||
|
||||
spin_lock(&mp->m_sb_lock);
|
||||
mp->m_fs_sick |= mask;
|
||||
mp->m_fs_checked |= mask;
|
||||
@@ -139,6 +157,20 @@ xfs_rt_mark_sick(
|
||||
ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
|
||||
trace_xfs_rt_mark_sick(mp, mask);
|
||||
|
||||
spin_lock(&mp->m_sb_lock);
|
||||
mp->m_rt_sick |= mask;
|
||||
spin_unlock(&mp->m_sb_lock);
|
||||
}
|
||||
|
||||
/* Mark realtime metadata as having been checked and found unhealthy by fsck. */
|
||||
void
|
||||
xfs_rt_mark_corrupt(
|
||||
struct xfs_mount *mp,
|
||||
unsigned int mask)
|
||||
{
|
||||
ASSERT(!(mask & ~XFS_SICK_RT_PRIMARY));
|
||||
trace_xfs_rt_mark_corrupt(mp, mask);
|
||||
|
||||
spin_lock(&mp->m_sb_lock);
|
||||
mp->m_rt_sick |= mask;
|
||||
mp->m_rt_checked |= mask;
|
||||
@@ -173,6 +205,23 @@ xfs_rt_measure_sickness(
|
||||
spin_unlock(&mp->m_sb_lock);
|
||||
}
|
||||
|
||||
/* Mark unhealthy per-ag metadata given a raw AG number. */
|
||||
void
|
||||
xfs_agno_mark_sick(
|
||||
struct xfs_mount *mp,
|
||||
xfs_agnumber_t agno,
|
||||
unsigned int mask)
|
||||
{
|
||||
struct xfs_perag *pag = xfs_perag_get(mp, agno);
|
||||
|
||||
/* per-ag structure not set up yet? */
|
||||
if (!pag)
|
||||
return;
|
||||
|
||||
xfs_ag_mark_sick(pag, mask);
|
||||
xfs_perag_put(pag);
|
||||
}
|
||||
|
||||
/* Mark unhealthy per-ag metadata. */
|
||||
void
|
||||
xfs_ag_mark_sick(
|
||||
@@ -182,6 +231,20 @@ xfs_ag_mark_sick(
|
||||
ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
|
||||
trace_xfs_ag_mark_sick(pag->pag_mount, pag->pag_agno, mask);
|
||||
|
||||
spin_lock(&pag->pag_state_lock);
|
||||
pag->pag_sick |= mask;
|
||||
spin_unlock(&pag->pag_state_lock);
|
||||
}
|
||||
|
||||
/* Mark per-ag metadata as having been checked and found unhealthy by fsck. */
|
||||
void
|
||||
xfs_ag_mark_corrupt(
|
||||
struct xfs_perag *pag,
|
||||
unsigned int mask)
|
||||
{
|
||||
ASSERT(!(mask & ~XFS_SICK_AG_PRIMARY));
|
||||
trace_xfs_ag_mark_corrupt(pag->pag_mount, pag->pag_agno, mask);
|
||||
|
||||
spin_lock(&pag->pag_state_lock);
|
||||
pag->pag_sick |= mask;
|
||||
pag->pag_checked |= mask;
|
||||
@@ -225,6 +288,29 @@ xfs_inode_mark_sick(
|
||||
ASSERT(!(mask & ~(XFS_SICK_INO_PRIMARY | XFS_SICK_INO_ZAPPED)));
|
||||
trace_xfs_inode_mark_sick(ip, mask);
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_sick |= mask;
|
||||
spin_unlock(&ip->i_flags_lock);
|
||||
|
||||
/*
|
||||
* Keep this inode around so we don't lose the sickness report. Scrub
|
||||
* grabs inodes with DONTCACHE assuming that most inode are ok, which
|
||||
* is not the case here.
|
||||
*/
|
||||
spin_lock(&VFS_I(ip)->i_lock);
|
||||
VFS_I(ip)->i_state &= ~I_DONTCACHE;
|
||||
spin_unlock(&VFS_I(ip)->i_lock);
|
||||
}
|
||||
|
||||
/* Mark inode metadata as having been checked and found unhealthy by fsck. */
|
||||
void
|
||||
xfs_inode_mark_corrupt(
|
||||
struct xfs_inode *ip,
|
||||
unsigned int mask)
|
||||
{
|
||||
ASSERT(!(mask & ~(XFS_SICK_INO_PRIMARY | XFS_SICK_INO_ZAPPED)));
|
||||
trace_xfs_inode_mark_corrupt(ip, mask);
|
||||
|
||||
spin_lock(&ip->i_flags_lock);
|
||||
ip->i_sick |= mask;
|
||||
ip->i_checked |= mask;
|
||||
@@ -399,3 +485,103 @@ xfs_bulkstat_health(
|
||||
bs->bs_sick |= m->ioctl_mask;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark a block mapping sick. */
|
||||
void
|
||||
xfs_bmap_mark_sick(
|
||||
struct xfs_inode *ip,
|
||||
int whichfork)
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
switch (whichfork) {
|
||||
case XFS_DATA_FORK:
|
||||
mask = XFS_SICK_INO_BMBTD;
|
||||
break;
|
||||
case XFS_ATTR_FORK:
|
||||
mask = XFS_SICK_INO_BMBTA;
|
||||
break;
|
||||
case XFS_COW_FORK:
|
||||
mask = XFS_SICK_INO_BMBTC;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
xfs_inode_mark_sick(ip, mask);
|
||||
}
|
||||
|
||||
/* Record observations of btree corruption with the health tracking system. */
|
||||
void
|
||||
xfs_btree_mark_sick(
|
||||
struct xfs_btree_cur *cur)
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
switch (cur->bc_btnum) {
|
||||
case XFS_BTNUM_BMAP:
|
||||
xfs_bmap_mark_sick(cur->bc_ino.ip, cur->bc_ino.whichfork);
|
||||
return;
|
||||
case XFS_BTNUM_BNO:
|
||||
mask = XFS_SICK_AG_BNOBT;
|
||||
break;
|
||||
case XFS_BTNUM_CNT:
|
||||
mask = XFS_SICK_AG_CNTBT;
|
||||
break;
|
||||
case XFS_BTNUM_INO:
|
||||
mask = XFS_SICK_AG_INOBT;
|
||||
break;
|
||||
case XFS_BTNUM_FINO:
|
||||
mask = XFS_SICK_AG_FINOBT;
|
||||
break;
|
||||
case XFS_BTNUM_RMAP:
|
||||
mask = XFS_SICK_AG_RMAPBT;
|
||||
break;
|
||||
case XFS_BTNUM_REFC:
|
||||
mask = XFS_SICK_AG_REFCNTBT;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
xfs_ag_mark_sick(cur->bc_ag.pag, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Record observations of dir/attr btree corruption with the health tracking
|
||||
* system.
|
||||
*/
|
||||
void
|
||||
xfs_dirattr_mark_sick(
|
||||
struct xfs_inode *ip,
|
||||
int whichfork)
|
||||
{
|
||||
unsigned int mask;
|
||||
|
||||
switch (whichfork) {
|
||||
case XFS_DATA_FORK:
|
||||
mask = XFS_SICK_INO_DIR;
|
||||
break;
|
||||
case XFS_ATTR_FORK:
|
||||
mask = XFS_SICK_INO_XATTR;
|
||||
break;
|
||||
default:
|
||||
ASSERT(0);
|
||||
return;
|
||||
}
|
||||
|
||||
xfs_inode_mark_sick(ip, mask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Record observations of dir/attr btree corruption with the health tracking
|
||||
* system.
|
||||
*/
|
||||
void
|
||||
xfs_da_mark_sick(
|
||||
struct xfs_da_args *args)
|
||||
{
|
||||
xfs_dirattr_mark_sick(args->dp, args->whichfork);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "xfs_ialloc.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_log_priv.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
#include <linux/iversion.h>
|
||||
|
||||
@@ -415,6 +416,9 @@ xfs_iget_check_free_state(
|
||||
xfs_warn(ip->i_mount,
|
||||
"Corruption detected! Free inode 0x%llx not marked free! (mode 0x%x)",
|
||||
ip->i_ino, VFS_I(ip)->i_mode);
|
||||
xfs_agno_mark_sick(ip->i_mount,
|
||||
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
||||
XFS_SICK_AG_INOBT);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -422,6 +426,9 @@ xfs_iget_check_free_state(
|
||||
xfs_warn(ip->i_mount,
|
||||
"Corruption detected! Free inode 0x%llx has blocks allocated!",
|
||||
ip->i_ino);
|
||||
xfs_agno_mark_sick(ip->i_mount,
|
||||
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
||||
XFS_SICK_AG_INOBT);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
return 0;
|
||||
@@ -640,6 +647,8 @@ xfs_iget_cache_miss(
|
||||
xfs_buf_offset(bp, ip->i_imap.im_boffset));
|
||||
if (!error)
|
||||
xfs_buf_set_ref(bp, XFS_INO_REF);
|
||||
else
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
xfs_trans_brelse(tp, bp);
|
||||
|
||||
if (error)
|
||||
|
||||
@@ -780,6 +780,8 @@ xfs_init_new_inode(
|
||||
*/
|
||||
if ((pip && ino == pip->i_ino) || !xfs_verify_dir_ino(mp, ino)) {
|
||||
xfs_alert(mp, "Allocated a known in-use inode 0x%llx!", ino);
|
||||
xfs_agno_mark_sick(mp, XFS_INO_TO_AGNO(mp, ino),
|
||||
XFS_SICK_AG_INOBT);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -1970,6 +1972,7 @@ xfs_iunlink_update_bucket(
|
||||
*/
|
||||
if (old_value == new_agino) {
|
||||
xfs_buf_mark_corrupt(agibp);
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -2019,11 +2022,14 @@ xfs_iunlink_reload_next(
|
||||
*/
|
||||
ino = XFS_AGINO_TO_INO(mp, pag->pag_agno, next_agino);
|
||||
error = xfs_iget(mp, tp, ino, XFS_IGET_UNTRUSTED, 0, &next_ip);
|
||||
if (error)
|
||||
if (error) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* If this is not an unlinked inode, something is very wrong. */
|
||||
if (VFS_I(next_ip)->i_nlink != 0) {
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
error = -EFSCORRUPTED;
|
||||
goto rele;
|
||||
}
|
||||
@@ -2061,6 +2067,7 @@ xfs_iunlink_insert_inode(
|
||||
if (next_agino == agino ||
|
||||
!xfs_verify_agino_or_null(pag, next_agino)) {
|
||||
xfs_buf_mark_corrupt(agibp);
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -2148,6 +2155,7 @@ xfs_iunlink_remove_inode(
|
||||
if (!xfs_verify_agino(pag, head_agino)) {
|
||||
XFS_CORRUPTION_ERROR(__func__, XFS_ERRLEVEL_LOW, mp,
|
||||
agi, sizeof(*agi));
|
||||
xfs_ag_mark_sick(pag, XFS_SICK_AG_AGI);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -2176,8 +2184,10 @@ xfs_iunlink_remove_inode(
|
||||
struct xfs_inode *prev_ip;
|
||||
|
||||
prev_ip = xfs_iunlink_lookup(pag, ip->i_prev_unlinked);
|
||||
if (!prev_ip)
|
||||
if (!prev_ip) {
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
error = xfs_iunlink_log_inode(tp, prev_ip, pag,
|
||||
ip->i_next_unlinked);
|
||||
@@ -3412,6 +3422,8 @@ xfs_iflush(
|
||||
|
||||
/* generate the checksum. */
|
||||
xfs_dinode_calc_crc(mp, dip);
|
||||
if (error)
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "xfs_dquot_item.h"
|
||||
#include "xfs_dquot.h"
|
||||
#include "xfs_reflink.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
#define XFS_ALLOC_ALIGN(mp, off) \
|
||||
(((off) >> mp->m_allocsize_log) << mp->m_allocsize_log)
|
||||
@@ -45,6 +46,7 @@ xfs_alert_fsblock_zero(
|
||||
(unsigned long long)imap->br_startoff,
|
||||
(unsigned long long)imap->br_blockcount,
|
||||
imap->br_state);
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
@@ -99,8 +101,10 @@ xfs_bmbt_to_iomap(
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
struct xfs_buftarg *target = xfs_inode_buftarg(ip);
|
||||
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock)))
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
return xfs_alert_fsblock_zero(ip, imap);
|
||||
}
|
||||
|
||||
if (imap->br_startblock == HOLESTARTBLOCK) {
|
||||
iomap->addr = IOMAP_NULL_ADDR;
|
||||
@@ -325,8 +329,10 @@ xfs_iomap_write_direct(
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock)))
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap->br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
error = xfs_alert_fsblock_zero(ip, imap);
|
||||
}
|
||||
|
||||
out_unlock:
|
||||
*seq = xfs_iomap_inode_sequence(ip, 0);
|
||||
@@ -639,8 +645,10 @@ xfs_iomap_write_unwritten(
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap.br_startblock)))
|
||||
if (unlikely(!xfs_valid_startblock(ip, imap.br_startblock))) {
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
return xfs_alert_fsblock_zero(ip, &imap);
|
||||
}
|
||||
|
||||
if ((numblks_fsb = imap.br_blockcount) == 0) {
|
||||
/*
|
||||
@@ -986,6 +994,7 @@ xfs_buffered_write_iomap_begin(
|
||||
|
||||
if (XFS_IS_CORRUPT(mp, !xfs_ifork_has_extents(&ip->i_df)) ||
|
||||
XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BMAPIFORMAT)) {
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
@@ -297,8 +297,10 @@ xfs_iwalk_ag_start(
|
||||
error = xfs_inobt_get_rec(*curpp, irec, has_more);
|
||||
if (error)
|
||||
return error;
|
||||
if (XFS_IS_CORRUPT(mp, *has_more != 1))
|
||||
if (XFS_IS_CORRUPT(mp, *has_more != 1)) {
|
||||
xfs_btree_mark_sick(*curpp);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
iwag->lastino = XFS_AGINO_TO_INO(mp, pag->pag_agno,
|
||||
irec->ir_startino + XFS_INODES_PER_CHUNK - 1);
|
||||
@@ -425,6 +427,7 @@ xfs_iwalk_ag(
|
||||
rec_fsino = XFS_AGINO_TO_INO(mp, pag->pag_agno, irec->ir_startino);
|
||||
if (iwag->lastino != NULLFSINO &&
|
||||
XFS_IS_CORRUPT(mp, iwag->lastino >= rec_fsino)) {
|
||||
xfs_btree_mark_sick(cur);
|
||||
error = -EFSCORRUPTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -763,14 +763,18 @@ xfs_qm_qino_alloc(
|
||||
(mp->m_sb.sb_gquotino != NULLFSINO)) {
|
||||
ino = mp->m_sb.sb_gquotino;
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
mp->m_sb.sb_pquotino != NULLFSINO))
|
||||
mp->m_sb.sb_pquotino != NULLFSINO)) {
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_PQUOTA);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
} else if ((flags & XFS_QMOPT_GQUOTA) &&
|
||||
(mp->m_sb.sb_pquotino != NULLFSINO)) {
|
||||
ino = mp->m_sb.sb_pquotino;
|
||||
if (XFS_IS_CORRUPT(mp,
|
||||
mp->m_sb.sb_gquotino != NULLFSINO))
|
||||
mp->m_sb.sb_gquotino != NULLFSINO)) {
|
||||
xfs_fs_mark_sick(mp, XFS_SICK_FS_GQUOTA);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
}
|
||||
if (ino != NULLFSINO) {
|
||||
error = xfs_iget(mp, NULL, ino, 0, 0, ipp);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "xfs_iomap.h"
|
||||
#include "xfs_ag.h"
|
||||
#include "xfs_ag_resv.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Copy on Write of Shared Blocks
|
||||
@@ -1227,8 +1228,10 @@ xfs_reflink_remap_extent(
|
||||
* extent if they're both holes or both the same physical extent.
|
||||
*/
|
||||
if (dmap->br_startblock == smap.br_startblock) {
|
||||
if (dmap->br_state != smap.br_state)
|
||||
if (dmap->br_state != smap.br_state) {
|
||||
xfs_bmap_mark_sick(ip, XFS_DATA_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
}
|
||||
goto out_cancel;
|
||||
}
|
||||
|
||||
@@ -1391,6 +1394,7 @@ xfs_reflink_remap_blocks(
|
||||
ASSERT(nimaps == 1 && imap.br_startoff == srcoff);
|
||||
if (imap.br_startblock == DELAYSTARTBLOCK) {
|
||||
ASSERT(imap.br_startblock != DELAYSTARTBLOCK);
|
||||
xfs_bmap_mark_sick(src, XFS_DATA_FORK);
|
||||
error = -EFSCORRUPTED;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include "xfs_sb.h"
|
||||
#include "xfs_rtbitmap.h"
|
||||
#include "xfs_quota.h"
|
||||
#include "xfs_log_priv.h"
|
||||
#include "xfs_health.h"
|
||||
|
||||
/*
|
||||
* Return whether there are any free extents in the size range given
|
||||
@@ -1202,6 +1204,8 @@ xfs_rtmount_inodes(
|
||||
|
||||
sbp = &mp->m_sb;
|
||||
error = xfs_iget(mp, NULL, sbp->sb_rbmino, 0, 0, &mp->m_rbmip);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_rt_mark_sick(mp, XFS_SICK_RT_BITMAP);
|
||||
if (error)
|
||||
return error;
|
||||
ASSERT(mp->m_rbmip != NULL);
|
||||
@@ -1211,6 +1215,8 @@ xfs_rtmount_inodes(
|
||||
goto out_rele_bitmap;
|
||||
|
||||
error = xfs_iget(mp, NULL, sbp->sb_rsumino, 0, 0, &mp->m_rsumip);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_rt_mark_sick(mp, XFS_SICK_RT_SUMMARY);
|
||||
if (error)
|
||||
goto out_rele_bitmap;
|
||||
ASSERT(mp->m_rsumip != NULL);
|
||||
|
||||
@@ -58,6 +58,8 @@ xfs_readlink_bmap_ilocked(
|
||||
|
||||
error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
|
||||
&bp, &xfs_symlink_buf_ops);
|
||||
if (xfs_metadata_is_sick(error))
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
|
||||
if (error)
|
||||
return error;
|
||||
byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
|
||||
@@ -68,6 +70,7 @@ xfs_readlink_bmap_ilocked(
|
||||
if (xfs_has_crc(mp)) {
|
||||
if (!xfs_symlink_hdr_ok(ip->i_ino, offset,
|
||||
byte_cnt, bp)) {
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
|
||||
error = -EFSCORRUPTED;
|
||||
xfs_alert(mp,
|
||||
"symlink header does not match required off/len/owner (0x%x/Ox%x,0x%llx)",
|
||||
@@ -103,7 +106,7 @@ xfs_readlink(
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
xfs_fsize_t pathlen;
|
||||
int error = -EFSCORRUPTED;
|
||||
int error;
|
||||
|
||||
trace_xfs_readlink(ip);
|
||||
|
||||
@@ -116,14 +119,14 @@ xfs_readlink(
|
||||
|
||||
pathlen = ip->i_disk_size;
|
||||
if (!pathlen)
|
||||
goto out;
|
||||
goto out_corrupt;
|
||||
|
||||
if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) {
|
||||
xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)",
|
||||
__func__, (unsigned long long) ip->i_ino,
|
||||
(long long) pathlen);
|
||||
ASSERT(0);
|
||||
goto out;
|
||||
goto out_corrupt;
|
||||
}
|
||||
|
||||
if (ip->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
|
||||
@@ -132,7 +135,7 @@ xfs_readlink(
|
||||
* if if_data is junk.
|
||||
*/
|
||||
if (XFS_IS_CORRUPT(ip->i_mount, !ip->i_df.if_data))
|
||||
goto out;
|
||||
goto out_corrupt;
|
||||
|
||||
memcpy(link, ip->i_df.if_data, pathlen + 1);
|
||||
error = 0;
|
||||
@@ -140,9 +143,12 @@ xfs_readlink(
|
||||
error = xfs_readlink_bmap_ilocked(ip, link);
|
||||
}
|
||||
|
||||
out:
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
return error;
|
||||
out_corrupt:
|
||||
xfs_iunlock(ip, XFS_ILOCK_SHARED);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -497,6 +503,7 @@ xfs_inactive_symlink(
|
||||
__func__, (unsigned long long)ip->i_ino, pathlen);
|
||||
xfs_iunlock(ip, XFS_ILOCK_EXCL);
|
||||
ASSERT(0);
|
||||
xfs_inode_mark_sick(ip, XFS_SICK_INO_SYMLINK);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
|
||||
@@ -3926,9 +3926,11 @@ DEFINE_EVENT(xfs_fs_corrupt_class, name, \
|
||||
TP_PROTO(struct xfs_mount *mp, unsigned int flags), \
|
||||
TP_ARGS(mp, flags))
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_fs_mark_sick);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_fs_mark_corrupt);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_fs_mark_healthy);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_fs_unfixed_corruption);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_rt_mark_sick);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_rt_mark_corrupt);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_rt_mark_healthy);
|
||||
DEFINE_FS_CORRUPT_EVENT(xfs_rt_unfixed_corruption);
|
||||
|
||||
@@ -3955,6 +3957,7 @@ DEFINE_EVENT(xfs_ag_corrupt_class, name, \
|
||||
unsigned int flags), \
|
||||
TP_ARGS(mp, agno, flags))
|
||||
DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_sick);
|
||||
DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_corrupt);
|
||||
DEFINE_AG_CORRUPT_EVENT(xfs_ag_mark_healthy);
|
||||
DEFINE_AG_CORRUPT_EVENT(xfs_ag_unfixed_corruption);
|
||||
|
||||
@@ -3980,6 +3983,7 @@ DEFINE_EVENT(xfs_inode_corrupt_class, name, \
|
||||
TP_PROTO(struct xfs_inode *ip, unsigned int flags), \
|
||||
TP_ARGS(ip, flags))
|
||||
DEFINE_INODE_CORRUPT_EVENT(xfs_inode_mark_sick);
|
||||
DEFINE_INODE_CORRUPT_EVENT(xfs_inode_mark_corrupt);
|
||||
DEFINE_INODE_CORRUPT_EVENT(xfs_inode_mark_healthy);
|
||||
|
||||
TRACE_EVENT(xfs_iwalk_ag,
|
||||
|
||||
Reference in New Issue
Block a user