Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29a5d29e authored by Goldwyn Rodrigues's avatar Goldwyn Rodrigues Committed by Jens Axboe
Browse files

xfs: nowait aio support



If IOCB_NOWAIT is set, bail if the i_rwsem is not lockable
immediately.

IF IOMAP_NOWAIT is set, return EAGAIN in xfs_file_iomap_begin
if it needs allocation either due to file extension, writing to a hole,
or COW or waiting for other DIOs to finish.

Return -EAGAIN if we don't have extent list in memory.

Signed-off-by: default avatarGoldwyn Rodrigues <rgoldwyn@suse.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 728fbc0e
Loading
Loading
Loading
Loading
+26 −6
Original line number Diff line number Diff line
@@ -237,7 +237,11 @@ xfs_file_dax_read(
	if (!count)
		return 0; /* skip atime */

	if (!xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED)) {
		if (iocb->ki_flags & IOCB_NOWAIT)
			return -EAGAIN;
		xfs_ilock(ip, XFS_IOLOCK_SHARED);
	}
	ret = dax_iomap_rw(iocb, to, &xfs_iomap_ops);
	xfs_iunlock(ip, XFS_IOLOCK_SHARED);

@@ -541,7 +545,11 @@ xfs_file_dio_aio_write(
		iolock = XFS_IOLOCK_SHARED;
	}

	if (!xfs_ilock_nowait(ip, iolock)) {
		if (iocb->ki_flags & IOCB_NOWAIT)
			return -EAGAIN;
		xfs_ilock(ip, iolock);
	}

	ret = xfs_file_aio_write_checks(iocb, from, &iolock);
	if (ret)
@@ -553,9 +561,15 @@ xfs_file_dio_aio_write(
	 * otherwise demote the lock if we had to take the exclusive lock
	 * for other reasons in xfs_file_aio_write_checks.
	 */
	if (unaligned_io)
	if (unaligned_io) {
		/* If we are going to wait for other DIO to finish, bail */
		if (iocb->ki_flags & IOCB_NOWAIT) {
			if (atomic_read(&inode->i_dio_count))
				return -EAGAIN;
		} else {
			inode_dio_wait(inode);
	else if (iolock == XFS_IOLOCK_EXCL) {
		}
	} else if (iolock == XFS_IOLOCK_EXCL) {
		xfs_ilock_demote(ip, XFS_IOLOCK_EXCL);
		iolock = XFS_IOLOCK_SHARED;
	}
@@ -585,7 +599,12 @@ xfs_file_dax_write(
	size_t			count;
	loff_t			pos;

	if (!xfs_ilock_nowait(ip, iolock)) {
		if (iocb->ki_flags & IOCB_NOWAIT)
			return -EAGAIN;
		xfs_ilock(ip, iolock);
	}

	ret = xfs_file_aio_write_checks(iocb, from, &iolock);
	if (ret)
		goto out;
@@ -892,6 +911,7 @@ xfs_file_open(
		return -EFBIG;
	if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
		return -EIO;
	file->f_mode |= FMODE_AIO_NOWAIT;
	return 0;
}

+22 −0
Original line number Diff line number Diff line
@@ -995,6 +995,11 @@ xfs_file_iomap_begin(
		lockmode = xfs_ilock_data_map_shared(ip);
	}

	if ((flags & IOMAP_NOWAIT) && !(ip->i_df.if_flags & XFS_IFEXTENTS)) {
		error = -EAGAIN;
		goto out_unlock;
	}

	ASSERT(offset <= mp->m_super->s_maxbytes);
	if ((xfs_fsize_t)offset + length > mp->m_super->s_maxbytes)
		length = mp->m_super->s_maxbytes - offset;
@@ -1016,6 +1021,15 @@ xfs_file_iomap_begin(

	if ((flags & (IOMAP_WRITE | IOMAP_ZERO)) && xfs_is_reflink_inode(ip)) {
		if (flags & IOMAP_DIRECT) {
			/*
			 * A reflinked inode will result in CoW alloc.
			 * FIXME: It could still overwrite on unshared extents
			 * and not need allocation.
			 */
			if (flags & IOMAP_NOWAIT) {
				error = -EAGAIN;
				goto out_unlock;
			}
			/* may drop and re-acquire the ilock */
			error = xfs_reflink_allocate_cow(ip, &imap, &shared,
					&lockmode);
@@ -1032,6 +1046,14 @@ xfs_file_iomap_begin(
	}

	if ((flags & IOMAP_WRITE) && imap_needs_alloc(inode, &imap, nimaps)) {
		/*
		 * 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