xfs: don't allocate COW blocks for zeroing holes or unwritten extents

The iomap zeroing interface is smart enough to skip zeroing holes or
unwritten extents.  Don't subvert this logic for reflink files.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Christoph Hellwig 2018-03-01 14:10:31 -08:00 committed by Darrick J. Wong
parent 5b4c845ea4
commit 172ed391f6
1 changed files with 10 additions and 1 deletions

View File

@ -955,6 +955,13 @@ static inline bool imap_needs_alloc(struct inode *inode,
(IS_DAX(inode) && imap->br_state == XFS_EXT_UNWRITTEN);
}
static inline bool needs_cow_for_zeroing(struct xfs_bmbt_irec *imap, int nimaps)
{
return nimaps &&
imap->br_startblock != HOLESTARTBLOCK &&
imap->br_state != XFS_EXT_UNWRITTEN;
}
static inline bool need_excl_ilock(struct xfs_inode *ip, unsigned flags)
{
/*
@ -1024,7 +1031,9 @@ xfs_file_iomap_begin(
goto out_unlock;
}
if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
if (xfs_is_reflink_inode(ip) &&
((flags & IOMAP_WRITE) ||
((flags & IOMAP_ZERO) && needs_cow_for_zeroing(&imap, nimaps)))) {
if (flags & IOMAP_DIRECT) {
/*
* A reflinked inode will result in CoW alloc.