aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 22:29:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-14 22:29:55 -0400
commite253d98f5babbec7e6ced810f7335b265a7f7e83 (patch)
treecd688c4ba8d43edb12bbeb523393879f7c212b65
parent0f0d12728e56c94d3289c6831243b6faeae8a19d (diff)
parentc35fc7a5abae9c154dd6f8c0b288462342facd45 (diff)
Merge branch 'work.read_write' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull nowait read support from Al Viro: "Support IOCB_NOWAIT for buffered reads and block devices" * 'work.read_write' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: block_dev: support RFW_NOWAIT on block device nodes fs: support RWF_NOWAIT for buffered reads fs: support IOCB_NOWAIT in generic_file_buffered_read fs: pass iocb to do_generic_file_read
-rw-r--r--fs/aio.c6
-rw-r--r--fs/block_dev.c5
-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
-rw-r--r--mm/filemap.c24
7 files changed, 42 insertions, 22 deletions
diff --git a/fs/aio.c b/fs/aio.c
index b5d69f28d8b1..5a2487217072 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1606,12 +1606,6 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb,
1606 goto out_put_req; 1606 goto out_put_req;
1607 } 1607 }
1608 1608
1609 if ((req->common.ki_flags & IOCB_NOWAIT) &&
1610 !(req->common.ki_flags & IOCB_DIRECT)) {
1611 ret = -EOPNOTSUPP;
1612 goto out_put_req;
1613 }
1614
1615 ret = put_user(KIOCB_KEY, &user_iocb->aio_key); 1609 ret = put_user(KIOCB_KEY, &user_iocb->aio_key);
1616 if (unlikely(ret)) { 1610 if (unlikely(ret)) {
1617 pr_debug("EFAULT: aio_key\n"); 1611 pr_debug("EFAULT: aio_key\n");
diff --git a/fs/block_dev.c b/fs/block_dev.c
index bb715b2fcfb8..93d088ffc05c 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1740,6 +1740,8 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1740 */ 1740 */
1741 filp->f_flags |= O_LARGEFILE; 1741 filp->f_flags |= O_LARGEFILE;
1742 1742
1743 filp->f_mode |= FMODE_NOWAIT;
1744
1743 if (filp->f_flags & O_NDELAY) 1745 if (filp->f_flags & O_NDELAY)
1744 filp->f_mode |= FMODE_NDELAY; 1746 filp->f_mode |= FMODE_NDELAY;
1745 if (filp->f_flags & O_EXCL) 1747 if (filp->f_flags & O_EXCL)
@@ -1892,6 +1894,9 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from)
1892 if (iocb->ki_pos >= size) 1894 if (iocb->ki_pos >= size)
1893 return -ENOSPC; 1895 return -ENOSPC;
1894 1896
1897 if ((iocb->ki_flags & (IOCB_NOWAIT | IOCB_DIRECT)) == IOCB_NOWAIT)
1898 return -EOPNOTSUPP;
1899
1895 iov_iter_truncate(from, size - iocb->ki_pos); 1900 iov_iter_truncate(from, size - iocb->ki_pos);
1896 1901
1897 blk_start_plug(&plug); 1902 blk_start_plug(&plug);
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 74fd7756cff3..aafcc785f840 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;
@@ -3112,7 +3116,7 @@ out:
3112 3116
3113static int btrfs_file_open(struct inode *inode, struct file *filp) 3117static int btrfs_file_open(struct inode *inode, struct file *filp)
3114{ 3118{
3115 filp->f_mode |= FMODE_AIO_NOWAIT; 3119 filp->f_mode |= FMODE_NOWAIT;
3116 return generic_file_open(inode, filp); 3120 return generic_file_open(inode, filp);
3117} 3121}
3118 3122
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index da9c6948ad25..b1da660ac3bc 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)
@@ -431,9 +433,7 @@ static int ext4_file_open(struct inode * inode, struct file * filp)
431 return ret; 433 return ret;
432 } 434 }
433 435
434 /* Set the flags to support nowait AIO */ 436 filp->f_mode |= FMODE_NOWAIT;
435 filp->f_mode |= FMODE_AIO_NOWAIT;
436
437 return dquot_file_open(inode, filp); 437 return dquot_file_open(inode, filp);
438} 438}
439 439
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index ec3e44fcf771..ebdd0bd2b261 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 b4ae080f41a6..bc475dfeb4ce 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -148,8 +148,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
148/* File was opened by fanotify and shouldn't generate fanotify events */ 148/* File was opened by fanotify and shouldn't generate fanotify events */
149#define FMODE_NONOTIFY ((__force fmode_t)0x4000000) 149#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
150 150
151/* File is capable of returning -EAGAIN if AIO will block */ 151/* File is capable of returning -EAGAIN if I/O will block */
152#define FMODE_AIO_NOWAIT ((__force fmode_t)0x8000000) 152#define FMODE_NOWAIT ((__force fmode_t)0x8000000)
153 153
154/* 154/*
155 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector 155 * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector
@@ -3194,7 +3194,7 @@ static inline int kiocb_set_rw_flags(struct kiocb *ki, rwf_t flags)
3194 return -EOPNOTSUPP; 3194 return -EOPNOTSUPP;
3195 3195
3196 if (flags & RWF_NOWAIT) { 3196 if (flags & RWF_NOWAIT) {
3197 if (!(ki->ki_filp->f_mode & FMODE_AIO_NOWAIT)) 3197 if (!(ki->ki_filp->f_mode & FMODE_NOWAIT))
3198 return -EOPNOTSUPP; 3198 return -EOPNOTSUPP;
3199 ki->ki_flags |= IOCB_NOWAIT; 3199 ki->ki_flags |= IOCB_NOWAIT;
3200 } 3200 }
diff --git a/mm/filemap.c b/mm/filemap.c
index 8c88e186a773..870971e20967 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1917,9 +1917,8 @@ static void shrink_readahead_size_eio(struct file *filp,
1917} 1917}
1918 1918
1919/** 1919/**
1920 * do_generic_file_read - generic file read routine 1920 * generic_file_buffered_read - generic file read routine
1921 * @filp: the file to read 1921 * @iocb: the iocb to read
1922 * @ppos: current file position
1923 * @iter: data destination 1922 * @iter: data destination
1924 * @written: already copied 1923 * @written: already copied
1925 * 1924 *
@@ -1929,12 +1928,14 @@ static void shrink_readahead_size_eio(struct file *filp,
1929 * This is really ugly. But the goto's actually try to clarify some 1928 * This is really ugly. But the goto's actually try to clarify some
1930 * of the logic when it comes to error handling etc. 1929 * of the logic when it comes to error handling etc.
1931 */ 1930 */
1932static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, 1931static ssize_t generic_file_buffered_read(struct kiocb *iocb,
1933 struct iov_iter *iter, ssize_t written) 1932 struct iov_iter *iter, ssize_t written)
1934{ 1933{
1934 struct file *filp = iocb->ki_filp;
1935 struct address_space *mapping = filp->f_mapping; 1935 struct address_space *mapping = filp->f_mapping;
1936 struct inode *inode = mapping->host; 1936 struct inode *inode = mapping->host;
1937 struct file_ra_state *ra = &filp->f_ra; 1937 struct file_ra_state *ra = &filp->f_ra;
1938 loff_t *ppos = &iocb->ki_pos;
1938 pgoff_t index; 1939 pgoff_t index;
1939 pgoff_t last_index; 1940 pgoff_t last_index;
1940 pgoff_t prev_index; 1941 pgoff_t prev_index;
@@ -1967,6 +1968,8 @@ find_page:
1967 1968
1968 page = find_get_page(mapping, index); 1969 page = find_get_page(mapping, index);
1969 if (!page) { 1970 if (!page) {
1971 if (iocb->ki_flags & IOCB_NOWAIT)
1972 goto would_block;
1970 page_cache_sync_readahead(mapping, 1973 page_cache_sync_readahead(mapping,
1971 ra, filp, 1974 ra, filp,
1972 index, last_index - index); 1975 index, last_index - index);
@@ -1980,6 +1983,11 @@ find_page:
1980 index, last_index - index); 1983 index, last_index - index);
1981 } 1984 }
1982 if (!PageUptodate(page)) { 1985 if (!PageUptodate(page)) {
1986 if (iocb->ki_flags & IOCB_NOWAIT) {
1987 put_page(page);
1988 goto would_block;
1989 }
1990
1983 /* 1991 /*
1984 * See comment in do_read_cache_page on why 1992 * See comment in do_read_cache_page on why
1985 * wait_on_page_locked is used to avoid unnecessarily 1993 * wait_on_page_locked is used to avoid unnecessarily
@@ -2161,6 +2169,8 @@ no_cached_page:
2161 goto readpage; 2169 goto readpage;
2162 } 2170 }
2163 2171
2172would_block:
2173 error = -EAGAIN;
2164out: 2174out:
2165 ra->prev_pos = prev_index; 2175 ra->prev_pos = prev_index;
2166 ra->prev_pos <<= PAGE_SHIFT; 2176 ra->prev_pos <<= PAGE_SHIFT;
@@ -2182,14 +2192,14 @@ out:
2182ssize_t 2192ssize_t
2183generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) 2193generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
2184{ 2194{
2185 struct file *file = iocb->ki_filp;
2186 ssize_t retval = 0;
2187 size_t count = iov_iter_count(iter); 2195 size_t count = iov_iter_count(iter);
2196 ssize_t retval = 0;
2188 2197
2189 if (!count) 2198 if (!count)
2190 goto out; /* skip atime */ 2199 goto out; /* skip atime */
2191 2200
2192 if (iocb->ki_flags & IOCB_DIRECT) { 2201 if (iocb->ki_flags & IOCB_DIRECT) {
2202 struct file *file = iocb->ki_filp;
2193 struct address_space *mapping = file->f_mapping; 2203 struct address_space *mapping = file->f_mapping;
2194 struct inode *inode = mapping->host; 2204 struct inode *inode = mapping->host;
2195 loff_t size; 2205 loff_t size;
@@ -2230,7 +2240,7 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
2230 goto out; 2240 goto out;
2231 } 2241 }
2232 2242
2233 retval = do_generic_file_read(file, &iocb->ki_pos, iter, retval); 2243 retval = generic_file_buffered_read(iocb, iter, retval);
2234out: 2244out:
2235 return retval; 2245 return retval;
2236} 2246}