Re: [PATCH 07/11] xfs_repair: only update in-core extent state after scanning full extent

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux