[rh7,v2] fuse: allow kernel to access "direct_io" files again

Submitted by Andrey Ryabinin on Sept. 27, 2019, 11:42 a.m.

Details

Message ID 20190927114226.19247-1-aryabinin@virtuozzo.com
State New
Series "fuse: allow kernel to access "direct_io" files"
Headers show

Commit Message

Andrey Ryabinin Sept. 27, 2019, 11:42 a.m.
This partially reverts bogus f2ac00874c20 ("fuse: remove direct_IO_page").
The commit removed vital hunk needed to export fuse via nfsd.

Let's bring it back.

https://jira.sw.ru/browse/PSBM-97905
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 fs/fuse/file.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

Patch hide | download patch | download mbox

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 344f35562bbe..ef2fcdbc9a05 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1703,6 +1703,21 @@  static int fuse_get_user_pages(struct fuse_req *req, struct iov_iter *ii,
 {
 	size_t nbytes = 0;  /* # bytes already packed in req */
 
+	/* Special case for kernel I/O: can copy directly into the buffer */
+	if (segment_eq(get_fs(), KERNEL_DS)) {
+		unsigned long user_addr = fuse_get_user_addr(ii);
+		size_t frag_size = fuse_get_frag_size(ii, *nbytesp);
+
+		if (write)
+			req->in.args[1].value = (void *) user_addr;
+		else
+			req->out.args[0].value = (void *) user_addr;
+
+		iov_iter_advance(ii, frag_size);
+		*nbytesp = frag_size;
+		return 0;
+	}
+
 	while (nbytes < *nbytesp && req->num_pages < req->max_pages) {
 		unsigned npages;
 		unsigned long user_addr = fuse_get_user_addr(ii);