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

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
Loading
Loading
Loading
Loading
+46 −36
Original line number Diff line number Diff line
@@ -1040,6 +1040,10 @@ xfs_file_iomap_begin(
			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) &&
	    ((flags & IOMAP_WRITE) ||
	     ((flags & IOMAP_ZERO) && needs_cow_for_zeroing(&imap, nimaps)))) {
@@ -1068,29 +1072,33 @@ xfs_file_iomap_begin(
		length = XFS_FSB_TO_B(mp, end_fsb) - offset;
	}

	if ((flags & IOMAP_WRITE) && imap_needs_alloc(inode, &imap, nimaps)) {
		/*
		 * If nowait is set bail since we are going to make
		 * allocations.
		 */
	/* Don't need to allocate over holes when doing zeroing operations. */
	if (flags & IOMAP_ZERO)
		goto out_found;

	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) {
		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.
	 * 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.
	 * 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.
	 * xfs_iomap_write_direct() expects the shared lock. It is unlocked on
	 * return.
	 */
	if (lockmode == XFS_ILOCK_EXCL)
		xfs_ilock_demote(ip, lockmode);
@@ -1101,13 +1109,8 @@ xfs_file_iomap_begin(

	iomap->flags = IOMAP_F_NEW;
	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
				& ~XFS_ILOG_TIMESTAMP))
		iomap->flags |= IOMAP_F_DIRTY;
@@ -1117,6 +1120,13 @@ xfs_file_iomap_begin(
	if (shared)
		iomap->flags |= IOMAP_F_SHARED;
	return 0;

out_found:
	ASSERT(nimaps);
	xfs_iunlock(ip, lockmode);
	trace_xfs_iomap_found(ip, offset, length, 0, &imap);
	goto out_finish;

out_unlock:
	xfs_iunlock(ip, lockmode);
	return error;