Re: [PATCH 18/19] xfs: cleanup xfs_iomap_write_unwritten

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

 



On Mon, Sep 09, 2019 at 08:27:21PM +0200, Christoph Hellwig wrote:
> Move more checks into the helpers that determine if we need a COW
> operation or allocation and split the return path for when an existing
> data for allocation has been found versus a new allocation.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>

Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx>

--D

> ---
>  fs/xfs/xfs_iomap.c | 74 ++++++++++++++++++++++++----------------------
>  1 file changed, 38 insertions(+), 36 deletions(-)
> 
> diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
> index 0e575ca1e3fc..e4e79aa5b695 100644
> --- a/fs/xfs/xfs_iomap.c
> +++ b/fs/xfs/xfs_iomap.c
> @@ -642,23 +642,42 @@ xfs_iomap_write_unwritten(
>  static inline bool
>  imap_needs_alloc(
>  	struct inode		*inode,
> +	unsigned		flags,
>  	struct xfs_bmbt_irec	*imap,
>  	int			nimaps)
>  {
> -	return !nimaps ||
> -		imap->br_startblock == HOLESTARTBLOCK ||
> -		imap->br_startblock == DELAYSTARTBLOCK ||
> -		(IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN);
> +	/* don't allocate blocks when just zeroing */
> +	if (flags & IOMAP_ZERO)
> +		return false;
> +	if (!nimaps ||
> +	    imap->br_startblock == HOLESTARTBLOCK ||
> +	    imap->br_startblock == DELAYSTARTBLOCK)
> +		return true;
> +	/* we convert unwritten extents before copying the data for DAX */
> +	if (IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN)
> +		return true;
> +	return false;
>  }
>  
>  static inline bool
> -needs_cow_for_zeroing(
> +imap_needs_cow(
> +	struct xfs_inode	*ip,
>  	struct xfs_bmbt_irec	*imap,
> +	unsigned int		flags,
>  	int			nimaps)
>  {
> -	return nimaps &&
> -		imap->br_startblock != HOLESTARTBLOCK &&
> -		imap->br_state != XFS_EXT_UNWRITTEN;
> +	if (!xfs_is_cow_inode(ip))
> +		return false;
> +
> +	/* when zeroing we don't have to COW holes or unwritten extents */
> +	if (flags & IOMAP_ZERO) {
> +		if (!nimaps ||
> +		    imap->br_startblock == HOLESTARTBLOCK ||
> +		    imap->br_state == XFS_EXT_UNWRITTEN)
> +			return false;
> +	}
> +
> +	return true;
>  }
>  
>  static int
> @@ -734,7 +753,6 @@ xfs_direct_write_iomap_begin(
>  	xfs_fileoff_t		end_fsb = xfs_iomap_end_fsb(mp, offset, length);
>  	int			nimaps = 1, error = 0;
>  	bool			shared = false;
> -	u16			iomap_flags = 0;
>  	unsigned		lockmode;
>  
>  	ASSERT(flags & (IOMAP_WRITE | IOMAP_ZERO));
> @@ -761,12 +779,7 @@ xfs_direct_write_iomap_begin(
>  	 * Break shared extents if necessary. Checks for non-blocking IO have
>  	 * been done up front, so we don't need to do them here.
>  	 */
> -	if (xfs_is_cow_inode(ip)) {
> -		/* if zeroing doesn't need COW allocation, then we are done. */
> -		if ((flags & IOMAP_ZERO) &&
> -		    !needs_cow_for_zeroing(&imap, nimaps))
> -			goto out_found;
> -
> +	if (imap_needs_cow(ip, &imap, flags, nimaps)) {
>  		/* may drop and re-acquire the ilock */
>  		error = xfs_reflink_allocate_cow(ip, &imap, &cmap, &shared,
>  				&lockmode, flags & IOMAP_DIRECT);
> @@ -778,18 +791,17 @@ xfs_direct_write_iomap_begin(
>  		length = XFS_FSB_TO_B(mp, end_fsb) - offset;
>  	}
>  
> -	/* Don't need to allocate over holes when doing zeroing operations. */
> -	if (flags & IOMAP_ZERO)
> -		goto out_found;
> +	if (imap_needs_alloc(inode, flags, &imap, nimaps))
> +		goto allocate_blocks;
>  
> -	if (!imap_needs_alloc(inode, &imap, nimaps))
> -		goto out_found;
> +	xfs_iunlock(ip, lockmode);
> +	trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
> +	return xfs_bmbt_to_iomap(ip, iomap, &imap, 0);
>  
> -	/* If nowait is set bail since we are going to make allocations. */
> -	if (flags & IOMAP_NOWAIT) {
> -		error = -EAGAIN;
> +allocate_blocks:
> +	error = -EAGAIN;
> +	if (flags & IOMAP_NOWAIT)
>  		goto out_unlock;
> -	}
>  
>  	/*
>  	 * We cap the maximum length we map to a sane size  to keep the chunks
> @@ -808,22 +820,12 @@ xfs_direct_write_iomap_begin(
>  	 */
>  	if (lockmode == XFS_ILOCK_EXCL)
>  		xfs_ilock_demote(ip, lockmode);
> -	error = xfs_iomap_write_direct(ip, offset, length, &imap,
> -			nimaps);
> +	error = xfs_iomap_write_direct(ip, offset, length, &imap, nimaps);
>  	if (error)
>  		return error;
>  
> -	iomap_flags |= IOMAP_F_NEW;
>  	trace_xfs_iomap_alloc(ip, offset, length, XFS_DATA_FORK, &imap);
> -
> -out_finish:
> -	return xfs_bmbt_to_iomap(ip, iomap, &imap, iomap_flags);
> -
> -out_found:
> -	ASSERT(nimaps);
> -	xfs_iunlock(ip, lockmode);
> -	trace_xfs_iomap_found(ip, offset, length, XFS_DATA_FORK, &imap);
> -	goto out_finish;
> +	return xfs_bmbt_to_iomap(ip, iomap, &imap, IOMAP_F_NEW);
>  
>  out_found_cow:
>  	xfs_iunlock(ip, lockmode);
> -- 
> 2.20.1
> 



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux