Commit d0641780 authored by Dave Chinner's avatar Dave Chinner Committed by Darrick J. Wong

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarCarlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 3460cac1
...@@ -1040,6 +1040,10 @@ xfs_file_iomap_begin( ...@@ -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,29 +1072,33 @@ xfs_file_iomap_begin( ...@@ -1068,29 +1072,33 @@ 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 (!imap_needs_alloc(inode, &imap, nimaps))
goto out_found;
/* If nowait is set bail since we are going to make allocations. */
if (flags & IOMAP_NOWAIT) { if (flags & IOMAP_NOWAIT) {
error = -EAGAIN; error = -EAGAIN;
goto out_unlock; goto out_unlock;
} }
/* /*
* We cap the maximum length we map here to MAX_WRITEBACK_PAGES * We cap the maximum length we map to a sane size to keep the chunks
* pages to keep the chunks of work done where somewhat symmetric * of work done where somewhat symmetric with the work writeback does.
* with the work writeback does. This is a completely arbitrary * This is a completely arbitrary number pulled out of thin air as a
* number pulled out of thin air as a best guess for initial * best guess for initial testing.
* testing.
* *
* Note that the values needs to be less than 32-bits wide until * Note that the values needs to be less than 32-bits wide until the
* the lower level functions are updated. * lower level functions are updated.
*/ */
length = min_t(loff_t, length, 1024 * PAGE_SIZE); length = min_t(loff_t, length, 1024 * PAGE_SIZE);
/* /*
* xfs_iomap_write_direct() expects the shared lock. It * xfs_iomap_write_direct() expects the shared lock. It is unlocked on
* is unlocked on return. * return.
*/ */
if (lockmode == XFS_ILOCK_EXCL) if (lockmode == XFS_ILOCK_EXCL)
xfs_ilock_demote(ip, lockmode); xfs_ilock_demote(ip, lockmode);
...@@ -1101,13 +1109,8 @@ xfs_file_iomap_begin( ...@@ -1101,13 +1109,8 @@ xfs_file_iomap_begin(
iomap->flags = IOMAP_F_NEW; iomap->flags = IOMAP_F_NEW;
trace_xfs_iomap_alloc(ip, offset, length, 0, &imap); trace_xfs_iomap_alloc(ip, offset, length, 0, &imap);
} else {
ASSERT(nimaps);
xfs_iunlock(ip, lockmode);
trace_xfs_iomap_found(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( ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment