Re: [PATCH 06/11] xfs_repair: invalidate dirty dir buffers when we zap a directory

[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>
> 
> If we decide to rebuild a directory in phase 6, we need to find and
> invalidate all of the old directory buffers so that they don't get
> written out, which can trigger write verifier errors when we finish.
> This fixes the write verifier errors in phase 7 that can occur via
> xfs/382.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

seems reasonable

Reviewed-by: Eric Sandeen <sandeen@xxxxxxxxxx>

> ---
>  libxfs/libxfs_api_defs.h |    1 +
>  repair/phase6.c          |   46 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 47 insertions(+)
> 
> 
> diff --git a/libxfs/libxfs_api_defs.h b/libxfs/libxfs_api_defs.h
> index 09f1428..3b36e0e 100644
> --- a/libxfs/libxfs_api_defs.h
> +++ b/libxfs/libxfs_api_defs.h
> @@ -100,6 +100,7 @@
>  #define xfs_dir2_data_make_free		libxfs_dir2_data_make_free
>  #define xfs_dir2_data_use_free		libxfs_dir2_data_use_free
>  #define xfs_dir2_shrink_inode		libxfs_dir2_shrink_inode
> +#define xfs_da_get_buf			libxfs_da_get_buf
>  
>  #define xfs_inode_from_disk		libxfs_inode_from_disk
>  #define xfs_inode_to_disk		libxfs_inode_to_disk
> diff --git a/repair/phase6.c b/repair/phase6.c
> index 498a3b5..2005e40 100644
> --- a/repair/phase6.c
> +++ b/repair/phase6.c
> @@ -1311,6 +1311,48 @@ entry_junked(
>  	return !no_modify;
>  }
>  
> +/* Find and invalidate all the directory's buffers. */
> +static int
> +dir_binval(
> +	struct xfs_trans	*tp,
> +	struct xfs_inode	*ip,
> +	int			whichfork)
> +{
> +	struct xfs_iext_cursor	icur;
> +	struct xfs_bmbt_irec	rec;
> +	struct xfs_ifork	*ifp;
> +	struct xfs_da_geometry	*geo;
> +	struct xfs_buf		*bp;
> +	xfs_dablk_t		dabno, end_dabno;
> +	int			error = 0;
> +
> +	if (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS &&
> +	    ip->i_d.di_format != XFS_DINODE_FMT_BTREE)
> +		return 0;
> +
> +	geo = tp->t_mountp->m_dir_geo;
> +	ifp = XFS_IFORK_PTR(ip, XFS_DATA_FORK);
> +	for_each_xfs_iext(ifp, &icur, &rec) {
> +		dabno = xfs_dir2_db_to_da(geo, rec.br_startoff +
> +				geo->fsbcount - 1);
> +		end_dabno = xfs_dir2_db_to_da(geo, rec.br_startoff +
> +				rec.br_blockcount);
> +		for (; dabno <= end_dabno; dabno += geo->fsbcount) {
> +			bp = NULL;
> +			error = -libxfs_da_get_buf(tp, ip, dabno, -2, &bp,
> +					whichfork);
> +			if (error)
> +				return error;
> +			if (!bp)
> +				continue;
> +			libxfs_trans_binval(tp, bp);
> +			libxfs_trans_brelse(tp, bp);
> +		}
> +	}
> +
> +	return error;
> +}
> +
>  /*
>   * Unexpected failure during the rebuild will leave the entries in
>   * lost+found on the next run
> @@ -1361,6 +1403,10 @@ longform_dir2_rebuild(
>  		res_failed(error);
>  	libxfs_trans_ijoin(tp, ip, 0);
>  
> +	error = dir_binval(tp, ip, XFS_DATA_FORK);
> +	if (error)
> +		res_failed(error);
> +
>  	if ((error = -libxfs_bmap_last_offset(ip, &lastblock, XFS_DATA_FORK)))
>  		do_error(_("xfs_bmap_last_offset failed -- error - %d\n"),
>  			error);
> 
> --
> 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