On 4/17/18 9:47 PM, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > In process_bmbt_reclist_int, only update the in-core extent state after > clearing the entire extent for conflicts. If we encounter conflicts > we'll try rebuilding the fork from rmap data and rescanning the fork. > It is essential to avoid polluting the in-memory state with garbage > data so that we don't end up nuking other files needlessly. Found by > fuzzing recs[1].blockcount = middlebit in xfs/380. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> AFAICT this makes sense. :) Reviewed-by: Eric Sandeen <sandeen@xxxxxxxxxx> > --- > repair/dinode.c | 30 ++++++++++++++++++++++++++++-- > 1 file changed, 28 insertions(+), 2 deletions(-) > > > diff --git a/repair/dinode.c b/repair/dinode.c > index ceffc52..c8c1850 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -751,7 +751,6 @@ _("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"), > /* fall through ... */ > case XR_E_INUSE1: /* seen by rmap */ > case XR_E_UNKNOWN: > - set_bmap_ext(agno, agbno, blen, XR_E_INUSE); > break; > > case XR_E_BAD_STATE: > @@ -773,7 +772,6 @@ _("%s fork in inode %" PRIu64 " claims metadata block %" PRIu64 "\n"), > > case XR_E_INUSE: > case XR_E_MULT: > - set_bmap_ext(agno, agbno, blen, XR_E_MULT); > if (type == XR_INO_DATA && > xfs_sb_version_hasreflink(&mp->m_sb)) > break; > @@ -792,6 +790,34 @@ _("%s fork in %s inode %" PRIu64 " claims CoW block %" PRIu64 "\n"), > do_error( > _("illegal state %d in block map %" PRIu64 "\n"), > state, b); > + goto done; > + } > + } > + > + /* > + * Update the internal extent map only after we've checked > + * every block in this extent. The first time we reject this > + * data fork we'll try to rebuild the bmbt from rmap data. > + * After a successful rebuild we'll try this scan again. > + * (If the rebuild fails we won't come back here.) > + */ > + agbno = XFS_FSB_TO_AGBNO(mp, irec.br_startblock); > + ebno = agbno + irec.br_blockcount; > + for (; agbno < ebno; agbno += blen) { > + state = get_bmap_ext(agno, agbno, ebno, &blen); > + switch (state) { > + case XR_E_FREE: > + case XR_E_FREE1: > + case XR_E_INUSE1: > + case XR_E_UNKNOWN: > + set_bmap_ext(agno, agbno, blen, XR_E_INUSE); > + break; > + case XR_E_INUSE: > + case XR_E_MULT: > + set_bmap_ext(agno, agbno, blen, XR_E_MULT); > + break; > + default: > + break; > } > } > if (collect_rmaps) { /* && !check_dups */ > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html