Commit 6fe1910e authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'corruption-health-reports-6.9_2024-02-23' of...

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: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan 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
parents 128d0fd1 989d5ec3
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -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;

+89 −16
Original line number Diff line number Diff line
@@ -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,15 +499,19 @@ 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,15 +522,19 @@ 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
	if (bno_cur->bc_nlevels == 1 && cnt_cur->bc_nlevels == 1) {
@@ -536,9 +546,11 @@ 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,31 +579,41 @@ 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,13 +640,17 @@ 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, &ltbno, &ltlen, &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, &gtbno, &gtlen, &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;
	}
+4 −0
Original line number Diff line number Diff line
@@ -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 −13
Original line number Diff line number Diff line
@@ -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 */

@@ -278,12 +279,13 @@ STATIC int
xfs_attr_rmtval_copyout(
	struct xfs_mount	*mp,
	struct xfs_buf		*bp,
	xfs_ino_t	ino,
	struct xfs_inode	*dp,
	int			*offset,
	int			*valuelen,
	uint8_t			**dst)
{
	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;
@@ -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;
+119 −16

File changed.

Preview size limit exceeded, changes collapsed.

Loading