Re: [PATCH] xfs: invalidate xfs_bufs when allocating cow extents

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

 



On Wed, Nov 30, 2022 at 04:21:39PM -0800, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@xxxxxxxxxx>
> 
> While investigating test failures in xfs/17[1-3] in alwayscow mode, I
> noticed through code inspection that xfs_bmap_alloc_userdata isn't
> setting XFS_ALLOC_USERDATA when allocating extents for a file's CoW
> fork.  COW staging extents should be flagged as USERDATA, since user
> data are persisted to these blocks before being remapped into a file.
> 
> This mis-classification has a few impacts on the behavior of the system.
> First, the filestreams allocator is supposed to keep allocating from a
> chosen AG until it runs out of space in that AG.  However, it only does
> that for USERDATA allocations, which means that COW allocations aren't
> tied to the filestreams AG.  Fortunately, few people use filestreams, so
> nobody's noticed.
> 
> A more serious problem is that xfs_alloc_ag_vextent_small looks for a
> buffer to invalidate *if* the USERDATA flag is set and the AG is so full
> that the allocation had to come from the AGFL because the cntbt is
> empty.  The consequences of not invalidating the buffer are severe --
> if the AIL incorrectly checkpoints a buffer that is now being used to
> store user data, that action will clobber the user's written data.
> 
> Fix filestreams and yet another data corruption vector by flagging COW
> allocations as USERDATA.
> 
> Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
> ---
>  fs/xfs/libxfs/xfs_bmap.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 56b9b7db38bb..0d56a8d862e8 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -4058,7 +4058,7 @@ xfs_bmap_alloc_userdata(
>  	 * the busy list.
>  	 */
>  	bma->datatype = XFS_ALLOC_NOBUSY;
> -	if (whichfork == XFS_DATA_FORK) {
> +	if (whichfork == XFS_DATA_FORK || whichfork == XFS_COW_FORK) {
>  		bma->datatype |= XFS_ALLOC_USERDATA;
>  		if (bma->offset == 0)
>  			bma->datatype |= XFS_ALLOC_INITIAL_USER_DATA;

Makes sense.

Reviewed-by: Dave Chinner <dchinner@xxxxxxxxxx>

-- 
Dave Chinner
david@xxxxxxxxxxxxx



[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