Filesystems that generic_file_read_iter will not be allowed to perform non-blocking reads. This only will read data if it's in the page cache and if there is no page error (causing a re-read). Signed-off-by: Milosz Tanski <milosz@xxxxxxxxx> --- fs/read_write.c | 4 ++-- mm/filemap.c | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/fs/read_write.c b/fs/read_write.c index 6c5030a..87a6034 100644 --- a/fs/read_write.c +++ b/fs/read_write.c @@ -908,7 +908,7 @@ SYSCALL_DEFINE4(readv2, unsigned long, fd, const struct iovec __user *, vec, struct fd f = fdget_pos(fd); ssize_t ret = -EBADF; - if (flags & ~0) + if (flags & ~O_NONBLOCK) return -EINVAL; if (f.file) { @@ -1006,7 +1006,7 @@ SYSCALL_DEFINE6(preadv2, unsigned long, fd, const struct iovec __user *, vec, struct fd f; ssize_t ret = -EBADF; - if (flags & ~0) + if (flags & ~O_NONBLOCK) return -EINVAL; if (pos < 0) return -EINVAL; diff --git a/mm/filemap.c b/mm/filemap.c index c95edbf..5b72572 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1483,7 +1483,10 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos, cond_resched(); find_page: page = find_get_page(mapping, index); + if (!page) { + if (flags & O_NONBLOCK) + goto would_block; page_cache_sync_readahead(mapping, ra, filp, index, last_index - index); @@ -1575,6 +1578,11 @@ page_ok: continue; page_not_up_to_date: + if (flags & O_NONBLOCK) { + page_cache_release(page); + goto would_block; + } + /* Get exclusive access to the page ... */ error = lock_page_killable(page); if (unlikely(error)) @@ -1594,6 +1602,12 @@ page_not_up_to_date_locked: goto page_ok; } + if (flags & O_NONBLOCK) { + unlock_page(page); + page_cache_release(page); + goto would_block; + } + readpage: /* * A previous I/O error may have been due to temporary @@ -1662,6 +1676,10 @@ no_cached_page: goto out; } goto readpage; + +would_block: + error = -EAGAIN; + goto out; } out: @@ -1697,6 +1715,9 @@ generic_file_read_iter(struct kiocb *iocb, struct iov_iter *iter, int flags) size_t count = iov_iter_count(iter); loff_t size; + if (flags & O_NONBLOCK) + return -EAGAIN; + if (!count) goto out; /* skip atime */ size = i_size_read(inode); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html