aboutsummaryrefslogtreecommitdiffstats
path: root/0001-readfile-implement-readfile-syscall.patch
diff options
Diffstat (limited to '0001-readfile-implement-readfile-syscall.patch')
-rw-r--r--0001-readfile-implement-readfile-syscall.patch81
1 files changed, 81 insertions, 0 deletions
diff --git a/0001-readfile-implement-readfile-syscall.patch b/0001-readfile-implement-readfile-syscall.patch
new file mode 100644
index 00000000000000..1393312d340858
--- /dev/null
+++ b/0001-readfile-implement-readfile-syscall.patch
@@ -0,0 +1,81 @@
+From 64793c95677d62753de4db132b0c85adab7aa9ab Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sun, 24 May 2020 12:37:15 +0200
+Subject: [PATCH 1/3] readfile: implement readfile syscall
+
+It's a tiny syscall, meant to allow a user to do a single "open this
+file, read into this buffer, and close the file" all in a single shot.
+
+Should be good for reading "tiny" files like sysfs, procfs, and other
+"small" files.
+
+There is no restarting the syscall, this is a "simple" syscall, with the
+attempt to make reading "simple" files easier with less syscall
+overhead.
+
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/open.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/fs/open.c b/fs/open.c
+index 6cd48a61cda3..9ec18cddee18 100644
+--- a/fs/open.c
++++ b/fs/open.c
+@@ -1370,3 +1370,53 @@ int stream_open(struct inode *inode, struct file *filp)
+ }
+
+ EXPORT_SYMBOL(stream_open);
++
++static struct file *readfile_open(int dfd, const char __user *filename,
++ struct open_flags *op)
++{
++ struct filename *tmp;
++ struct file *f;
++
++ tmp = getname(filename);
++ if (IS_ERR(tmp))
++ return (struct file *)tmp;
++
++ f = do_filp_open(dfd, tmp, op);
++ if (!IS_ERR(f))
++ fsnotify_open(f);
++
++ putname(tmp);
++ return f;
++}
++
++SYSCALL_DEFINE5(readfile, int, dfd, const char __user *, filename,
++ char __user *, buffer, size_t, bufsize, int, flags)
++{
++ struct open_flags op;
++ struct open_how how;
++ struct file *file;
++ loff_t pos = 0;
++ int retval;
++
++ /* only accept a small subset of O_ flags that make sense */
++ if ((flags | O_NOFOLLOW | O_NOATIME) != flags)
++ return -EINVAL;
++
++ /* add some needed flags to be able to open the file properly */
++ flags |= O_RDONLY | O_LARGEFILE;
++
++ how = build_open_how(flags, 0000);
++ retval = build_open_flags(&how, &op);
++ if (retval)
++ return retval;
++
++ file = readfile_open(dfd, filename, &op);
++ if (IS_ERR(file))
++ return PTR_ERR(file);
++
++ retval = vfs_read(file, buffer, bufsize, &pos);
++
++ filp_close(file, NULL);
++
++ return retval;
++}
+--
+2.27.0
+