summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2017-08-29 10:13:20 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2017-09-04 19:04:23 -0400
commit91f9943e1c7b6638f27312d03fe71fcc67b23571 (patch)
treebf9c2212d93f4fbf9af6f5fafc2e667fa3d29de1
parent3239d834847627b6634a4139cf1dc58f6f137a46 (diff)
fs: support RWF_NOWAIT for buffered reads
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 <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/aio.c6
-rw-r--r--fs/btrfs/file.c6
-rw-r--r--fs/ext4/file.c6
-rw-r--r--fs/xfs/xfs_file.c11
-rw-r--r--include/linux/fs.h6
5 files changed, 20 insertions, 15 deletions
diff --git a/fs/aio.c b/fs/aio.c
index dcad3a66748c..d93daa076726 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1593,12 +1593,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1593 goto out_put_req; 1593 goto out_put_req;
1594 } 1594 }
1595 1595
1596 if ((req->common.ki_flags & IOCB_NOWAIT) &&
1597 !(req->common.ki_flags & IOCB_DIRECT)) {
1598 ret = -EOPNOTSUPP;
1599 goto out_put_req;
1600 }
1601
1602 ret = put_user(KIOCB_KEY, &user_iocb->aio_key); 1596 ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
1603 if (unlikely(ret)) { 1597 if (unlikely(ret)) {
1604 pr_debug("EFAULT: aio_key\n"); 1598 pr_debug("EFAULT: aio_key\n");
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9e75d8a39aac..e62dd55b4079 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1886,6 +1886,10 @@ static ssize_t btrfs_file_write_iter(struct kiocb *iocb,
1886 loff_t oldsize; 1886 loff_t oldsize;
1887 int clean_page = 0; 1887 int clean_page = 0;
1888 1888
1889 if (!(iocb->ki_flags & IOCB_DIRECT) &&
1890 (iocb->ki_flags & IOCB_NOWAIT))
1891 return -EOPNOTSUPP;
1892
1889 if (!inode_trylock(inode)) { 1893 if (!inode_trylock(inode)) {
1890 if (iocb->ki_flags & IOCB_NOWAIT) 1894 if (iocb->ki_flags & IOCB_NOWAIT)
1891 return -EAGAIN; 1895 return -EAGAIN;
@@ -3105,7 +3109,7 @@ out:
3105 3109
3106static int btrfs_file_open(struct inode *inode, struct file *filp) 3110static int btrfs_file_open(struct inode *inode, struct file *filp)
3107{ 3111{
3108 filp->f_mode |= FMODE_AIO_NOWAIT; 3112 filp->f_mode |= FMODE_NOWAIT;
3109 return generic_file_open(inode, filp); 3113 return generic_file_open(inode, filp);
3110} 3114}
3111 3115
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index 0d7cf0cc9b87..f83521337b8f 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -223,6 +223,8 @@ ext4_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
223 if (IS_DAX(inode)) 223 if (IS_DAX(inode))
224 return ext4_dax_write_iter(iocb, from); 224 return ext4_dax_write_iter(iocb, from);
225#endif 225#endif
226 if (!o_direct && (iocb->ki_flags & IOCB_NOWAIT))
227 return -EOPNOTSUPP;
226 228
227 if (!inode_trylock(inode)) { 229 if (!inode_trylock(inode)) {
228 if (iocb->ki_flags & IOCB_NOWAIT) 230 if (iocb->ki_flags & IOCB_NOWAIT)
@@ -448,9 +450,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
448 return ret; 450 return ret;
449 } 451 }
450 452
451 /* Set the flags to support nowait AIO */ 453 filp->f_mode |= FMODE_NOWAIT;
452 filp->f_mode |= FMODE_AIO_NOWAIT;
453
454 return dquot_file_open(inode, filp); 454 return dquot_file_open(inode, filp);
455} 455}
456 456
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index c4893e226fd8..1a09104b3eb0 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -259,7 +259,11 @@ xfs_file_buffered_aio_read(
259 259
260 trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos); 260 trace_xfs_file_buffered_read(ip, iov_iter_count(to), iocb->ki_pos);
261 261
262 xfs_ilock(ip, XFS_IOLOCK_SHARED); 262 if (!xfs_ilock_nowait(ip, XFS_IOLOCK_SHARED)) {
263 if (iocb->ki_flags & IOCB_NOWAIT)
264 return -EAGAIN;
265 xfs_ilock(ip, XFS_IOLOCK_SHARED);
266 }
263 ret = generic_file_read_iter(iocb, to); 267 ret = generic_file_read_iter(iocb, to);
264 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 268 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
265 269
@@ -636,6 +640,9 @@ xfs_file_buffered_aio_write(
636 int enospc = 0; 640 int enospc = 0;
637 int iolock; 641 int iolock;
638 642
643 if (iocb->ki_flags & IOCB_NOWAIT)
644 return -EOPNOTSUPP;
645
639write_retry: 646write_retry:
640 iolock = XFS_IOLOCK_EXCL; 647 iolock = XFS_IOLOCK_EXCL;
641 xfs_ilock(ip, iolock); 648 xfs_ilock(ip, iolock);
@@ -912,7 +919,7 @@ xfs_file_open(
912 return -EFBIG; 919 return -EFBIG;
913 if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb))) 920 if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
914 return -EIO; 921 return -EIO;
915 file->f_mode |= FMODE_AIO_NOWAIT; 922 file->f_mode |= FMODE_NOWAIT;
916 return 0; 923 return 0;
917} 924}
918 925
diff --git a/include/linux/fs.h b/include/linux/fs.h
index cbfe127bccf8..94582c379dac 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -146,8 +146,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
146/* File was opened by fanotify and shouldn't generate fanotify events */ 146/* File was opened by fanotify and shouldn't generate fanotify events */
147#define FMODE_NONOTIFY ((__force fmode_t)0x4000000) 147#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
148 148
149/* File is capable of returning -EAGAIN if AIO will block */ 149/* File is capable of returning -EAGAIN if I/O will block */
150#define FMODE_AIO_NOWAIT ((__force fmode_t)0x8000000) 150#define FMODE_NOWAIT ((__force fmode_t)0x8000000)
151 151
152/* 152/*
153 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector 153 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
@@ -3149,7 +3149,7 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, int flags)
3149 return -EOPNOTSUPP; 3149 return -EOPNOTSUPP;
3150 3150
3151 if (flags & RWF_NOWAIT) { 3151 if (flags & RWF_NOWAIT) {
3152 if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT)) 3152 if (!(ki->ki_filp->f_mode & FMODE_NOWAIT))
3153 return -EOPNOTSUPP; 3153 return -EOPNOTSUPP;
3154 ki->ki_flags |= IOCB_NOWAIT; 3154 ki->ki_flags |= IOCB_NOWAIT;
3155 } 3155 }