summaryrefslogtreecommitdiffstats
path: root/mm/readahead.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-10-01 13:20:45 +0200
committerLinus Walleij <linus.walleij@linaro.org>2018-10-01 13:20:45 +0200
commit30aa69e7bd9f7af3574120249eecb3726dcaf737 (patch)
treeb4a9ec1374ec9aed1022fdb32802c483952e5a97 /mm/readahead.c
parentpinctrl: sprd: Move DT parsing before registering pinctrl device (diff)
parentLinux 4.19-rc6 (diff)
downloadlinux-30aa69e7bd9f7af3574120249eecb3726dcaf737.tar.xz
linux-30aa69e7bd9f7af3574120249eecb3726dcaf737.zip
Merge tag 'v4.19-rc6' into devel
This is the 4.19-rc6 release I needed to merge this in because of extensive conflicts in the MSM and Intel pin control drivers. I know how to resolve them, so let's do it like this. Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'mm/readahead.c')
-rw-r--r--mm/readahead.c45
1 files changed, 17 insertions, 28 deletions
diff --git a/mm/readahead.c b/mm/readahead.c
index a59ea70527b9..4e630143a0ba 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -20,6 +20,7 @@
#include <linux/file.h>
#include <linux/mm_inline.h>
#include <linux/blk-cgroup.h>
+#include <linux/fadvise.h>
#include "internal.h"
@@ -575,24 +576,6 @@ page_cache_async_readahead(struct address_space *mapping,
}
EXPORT_SYMBOL_GPL(page_cache_async_readahead);
-static ssize_t
-do_readahead(struct address_space *mapping, struct file *filp,
- pgoff_t index, unsigned long nr)
-{
- if (!mapping || !mapping->a_ops)
- return -EINVAL;
-
- /*
- * Readahead doesn't make sense for DAX inodes, but we don't want it
- * to report a failure either. Instead, we just return success and
- * don't do any work.
- */
- if (dax_mapping(mapping))
- return 0;
-
- return force_page_cache_readahead(mapping, filp, index, nr);
-}
-
ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
{
ssize_t ret;
@@ -600,16 +583,22 @@ ssize_t ksys_readahead(int fd, loff_t offset, size_t count)
ret = -EBADF;
f = fdget(fd);
- if (f.file) {
- if (f.file->f_mode & FMODE_READ) {
- struct address_space *mapping = f.file->f_mapping;
- pgoff_t start = offset >> PAGE_SHIFT;
- pgoff_t end = (offset + count - 1) >> PAGE_SHIFT;
- unsigned long len = end - start + 1;
- ret = do_readahead(mapping, f.file, start, len);
- }
- fdput(f);
- }
+ if (!f.file || !(f.file->f_mode & FMODE_READ))
+ goto out;
+
+ /*
+ * The readahead() syscall is intended to run only on files
+ * that can execute readahead. If readahead is not possible
+ * on this file, then we must return -EINVAL.
+ */
+ ret = -EINVAL;
+ if (!f.file->f_mapping || !f.file->f_mapping->a_ops ||
+ !S_ISREG(file_inode(f.file)->i_mode))
+ goto out;
+
+ ret = vfs_fadvise(f.file, offset, count, POSIX_FADV_WILLNEED);
+out:
+ fdput(f);
return ret;
}