Re: [PATCH] xfs: convert inode to extent format after extent merge due to shift

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

 



On Wed, Sep 18, 2019 at 10:55:38AM -0400, Brian Foster wrote:
> The collapse range operation can merge extents if two newly adjacent
> extents are physically contiguous. If the extent count is reduced on
> a btree format inode, a change to extent format might be necessary.
> This format change currently occurs as a side effect of the file
> size update after extents have been shifted for the collapse. This
> codepath ultimately calls xfs_bunmapi(), which happens to check for
> and execute the format conversion even if there were no blocks
> removed from the mapping.
> 
> While this ultimately puts the inode into the correct state, the
> fact the format conversion occurs in a separate transaction from the
> change that called for it is a problem. If an extent shift
> transaction commits and the filesystem happens to crash before the
> format conversion, the inode fork is left in a corrupted state after
> log recovery. The inode fork verifier fails and xfs_repair
> ultimately nukes the inode. This problem was originally reproduced
> by generic/388.
> 
> Similar to how the insert range extent split code handles extent to
> btree conversion, update the collapse range extent merge code to
> handle btree to extent format conversion in the same transaction
> that merges the extents. This ensures that the inode fork format
> remains consistent if the filesystem happens to crash in the middle
> of a collapse range operation that changes the inode fork format.
> 
> Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx>

Seems sensible to me,
Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

--D

> ---
>  fs/xfs/libxfs/xfs_bmap.c | 5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 054b4ce30033..eaf2d4250a26 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -5621,6 +5621,11 @@ xfs_bmse_merge(
>  	if (error)
>  		return error;
>  
> +	/* change to extent format if required after extent removal */
> +	error = xfs_bmap_btree_to_extents(tp, ip, cur, logflags, whichfork);
> +	if (error)
> +		return error;
> +
>  done:
>  	xfs_iext_remove(ip, icur, 0);
>  	xfs_iext_prev(XFS_IFORK_PTR(ip, whichfork), icur);
> -- 
> 2.20.1
> 



[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