xfs: simplify xfs_file_iomap_begin() logic
The current logic that determines whether allocation should be done has grown somewhat spaghetti like with the addition of IOMAP_NOWAIT functionality. Separate out each of the different cases into single, obvious checks to get rid most of the nested IOMAP_NOWAIT checks in the allocation logic. Signed-Off-By: Dave Chinner <dchinner@redhat.com> Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
parent
3460cac1ca
commit
d064178094
1 changed files with 46 additions and 36 deletions
|
@ -1040,6 +1040,10 @@ xfs_file_iomap_begin(
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Non-modifying mapping requested, so we are done */
|
||||||
|
if (!(flags & (IOMAP_WRITE | IOMAP_ZERO)))
|
||||||
|
goto out_found;
|
||||||
|
|
||||||
if (xfs_is_reflink_inode(ip) &&
|
if (xfs_is_reflink_inode(ip) &&
|
||||||
((flags & IOMAP_WRITE) ||
|
((flags & IOMAP_WRITE) ||
|
||||||
((flags & IOMAP_ZERO) && needs_cow_for_zeroing(&imap, nimaps)))) {
|
((flags & IOMAP_ZERO) && needs_cow_for_zeroing(&imap, nimaps)))) {
|
||||||
|
@ -1068,46 +1072,45 @@ xfs_file_iomap_begin(
|
||||||
length = XFS_FSB_TO_B(mp, end_fsb) - offset;
|
length = XFS_FSB_TO_B(mp, end_fsb) - offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & IOMAP_WRITE) && imap_needs_alloc(inode, &imap, nimaps)) {
|
/* Don't need to allocate over holes when doing zeroing operations. */
|
||||||
/*
|
if (flags & IOMAP_ZERO)
|
||||||
* If nowait is set bail since we are going to make
|
goto out_found;
|
||||||
* allocations.
|
|
||||||
*/
|
|
||||||
if (flags & IOMAP_NOWAIT) {
|
|
||||||
error = -EAGAIN;
|
|
||||||
goto out_unlock;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* We cap the maximum length we map here to MAX_WRITEBACK_PAGES
|
|
||||||
* pages to keep the chunks of work done where somewhat symmetric
|
|
||||||
* with the work writeback does. This is a completely arbitrary
|
|
||||||
* number pulled out of thin air as a best guess for initial
|
|
||||||
* testing.
|
|
||||||
*
|
|
||||||
* Note that the values needs to be less than 32-bits wide until
|
|
||||||
* the lower level functions are updated.
|
|
||||||
*/
|
|
||||||
length = min_t(loff_t, length, 1024 * PAGE_SIZE);
|
|
||||||
/*
|
|
||||||
* xfs_iomap_write_direct() expects the shared lock. It
|
|
||||||
* is unlocked on return.
|
|
||||||
*/
|
|
||||||
if (lockmode == XFS_ILOCK_EXCL)
|
|
||||||
xfs_ilock_demote(ip, lockmode);
|
|
||||||
error = xfs_iomap_write_direct(ip, offset, length, &imap,
|
|
||||||
nimaps);
|
|
||||||
if (error)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
iomap->flags = IOMAP_F_NEW;
|
if (!imap_needs_alloc(inode, &imap, nimaps))
|
||||||
trace_xfs_iomap_alloc(ip, offset, length, 0, &imap);
|
goto out_found;
|
||||||
} else {
|
|
||||||
ASSERT(nimaps);
|
|
||||||
|
|
||||||
xfs_iunlock(ip, lockmode);
|
/* If nowait is set bail since we are going to make allocations. */
|
||||||
trace_xfs_iomap_found(ip, offset, length, 0, &imap);
|
if (flags & IOMAP_NOWAIT) {
|
||||||
|
error = -EAGAIN;
|
||||||
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We cap the maximum length we map to a sane size to keep the chunks
|
||||||
|
* of work done where somewhat symmetric with the work writeback does.
|
||||||
|
* This is a completely arbitrary number pulled out of thin air as a
|
||||||
|
* best guess for initial testing.
|
||||||
|
*
|
||||||
|
* Note that the values needs to be less than 32-bits wide until the
|
||||||
|
* lower level functions are updated.
|
||||||
|
*/
|
||||||
|
length = min_t(loff_t, length, 1024 * PAGE_SIZE);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* xfs_iomap_write_direct() expects the shared lock. It is unlocked on
|
||||||
|
* return.
|
||||||
|
*/
|
||||||
|
if (lockmode == XFS_ILOCK_EXCL)
|
||||||
|
xfs_ilock_demote(ip, lockmode);
|
||||||
|
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, 0, &imap);
|
||||||
|
|
||||||
|
out_finish:
|
||||||
if (xfs_ipincount(ip) && (ip->i_itemp->ili_fsync_fields
|
if (xfs_ipincount(ip) && (ip->i_itemp->ili_fsync_fields
|
||||||
& ~XFS_ILOG_TIMESTAMP))
|
& ~XFS_ILOG_TIMESTAMP))
|
||||||
iomap->flags |= IOMAP_F_DIRTY;
|
iomap->flags |= IOMAP_F_DIRTY;
|
||||||
|
@ -1117,6 +1120,13 @@ xfs_file_iomap_begin(
|
||||||
if (shared)
|
if (shared)
|
||||||
iomap->flags |= IOMAP_F_SHARED;
|
iomap->flags |= IOMAP_F_SHARED;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out_found:
|
||||||
|
ASSERT(nimaps);
|
||||||
|
xfs_iunlock(ip, lockmode);
|
||||||
|
trace_xfs_iomap_found(ip, offset, length, 0, &imap);
|
||||||
|
goto out_finish;
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
xfs_iunlock(ip, lockmode);
|
xfs_iunlock(ip, lockmode);
|
||||||
return error;
|
return error;
|
||||||
|
|
Loading…
Add table
Reference in a new issue