Skip to content

Commit

Permalink
fs: support RWF_NOWAIT for buffered reads
Browse files Browse the repository at this point in the history
This is based on the old idea and code from Milosz Tanski.  With the aio
nowait code it becomes mostly trivial now.  Buffered writes continue to
return -EOPNOTSUPP if RWF_NOWAIT is passed.

Signed-off-by: Christoph Hellwig <[email protected]>
Reviewed-by: Jan Kara <[email protected]>
Signed-off-by: Al Viro <[email protected]>
  • Loading branch information
Christoph Hellwig authored and Al Viro committed Sep 4, 2017
1 parent 3239d83 commit 91f9943
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 15 deletions.
6 changes: 0 additions & 6 deletions fs/aio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1593,12 +1593,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
goto out_put_req;
}

if ((req->common.ki_flags & IOCB_NOWAIT) &&
!(req->common.ki_flags & IOCB_DIRECT)) {
ret = -EOPNOTSUPP;
goto out_put_req;
}

ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
if (unlikely(ret)) {
pr_debug("EFAULT: aio_key\n");
Expand Down
6 changes: 5 additions & 1 deletion fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,10 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
loff_t oldsize;
int clean_page = 0;

if (!(iocb->ki_flags & IOCB_DIRECT) &&
(iocb->ki_flags & IOCB_NOWAIT))
return -EOPNOTSUPP;

if (!inode_trylock(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
return -EAGAIN;
Expand Down Expand Up @@ -3105,7 +3109,7 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int whence)

static int btrfs_file_open(struct inode *inode, struct file *filp)
{
filp->f_mode |= FMODE_AIO_NOWAIT;
filp->f_mode |= FMODE_NOWAIT;
return generic_file_open(inode, filp);
}

Expand Down
6 changes: 3 additions & 3 deletions fs/ext4/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (IS_DAX(inode))
return ext4_dax_write_iter(iocb, from);
#endif
if (!o_direct && (iocb->ki_flags & IOCB_NOWAIT))
return -EOPNOTSUPP;

if (!inode_trylock(inode)) {
if (iocb->ki_flags & IOCB_NOWAIT)
Expand Down Expand Up @@ -448,9 +450,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
return ret;
}

/* Set the flags to support nowait AIO */
filp->f_mode |= FMODE_AIO_NOWAIT;

filp->f_mode |= FMODE_NOWAIT;
return dquot_file_open(inode, filp);
}

Expand Down
11 changes: 9 additions & 2 deletions fs/xfs/xfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,11 @@ xfs_file_buffered_aio_read(

trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos);

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

Expand Down Expand Up @@ -636,6 +640,9 @@ xfs_file_buffered_aio_write(
int enospc = 0;
int iolock;

if (iocb->ki_flags & IOCB_NOWAIT)
return -EOPNOTSUPP;

write_retry:
iolock = XFS_IOLOCK_EXCL;
xfs_ilock(ip, iolock);
Expand Down Expand Up @@ -912,7 +919,7 @@ xfs_file_open(
return -EFBIG;
if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
return -EIO;
file->f_mode |= FMODE_AIO_NOWAIT;
file->f_mode |= FMODE_NOWAIT;
return 0;
}

Expand Down
6 changes: 3 additions & 3 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
/* File was opened by fanotify and shouldn't generate fanotify events */
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)

/* File is capable of returning -EAGAIN if AIO will block */
#define FMODE_AIO_NOWAIT ((__force fmode_t)0x8000000)
/* File is capable of returning -EAGAIN if I/O will block */
#define FMODE_NOWAIT ((__force fmode_t)0x8000000)

/*
* Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
Expand Down Expand Up @@ -3149,7 +3149,7 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, int flags)
return -EOPNOTSUPP;

if (flags & RWF_NOWAIT) {
if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT))
if (!(ki->ki_filp->f_mode & FMODE_NOWAIT))
return -EOPNOTSUPP;
ki->ki_flags |= IOCB_NOWAIT;
}
Expand Down

0 comments on commit 91f9943

Please sign in to comment.