Blame SOURCES/0002-fuse_lowlevel-Add-max_pages-support-384.patch

5a6f97
From 5100bdc814435a1222fef6438cebcd81a3de6c73 Mon Sep 17 00:00:00 2001
5a6f97
From: scosu <mpargmann@allfex.org>
5a6f97
Date: Thu, 13 Jun 2019 13:59:10 +0200
5a6f97
Subject: [PATCH 2/4] fuse_lowlevel: Add max_pages support (#384)
5a6f97
5a6f97
Starting with kernel version 4.20 fuse supports a new property
5a6f97
'max_pages' which is the maximum number of pages that can be used per
5a6f97
request. This can be set via an argument during initialization.
5a6f97
This new property allows writes to be larger than 128k.
5a6f97
5a6f97
This patch sets the property if the matching capability is set
5a6f97
(FUSE_MAX_PAGES). It will also set max_write to 1MiB. Filesystems have
5a6f97
the possibility to decrease this size by setting max_write to a smaller
5a6f97
size. The max_pages and bufsize fields are adjusted accordingly.
5a6f97
5a6f97
Cc: Constantine Shulyupin <const@MakeLinux.com>
5a6f97
Signed-off-by: Markus Pargmann <scosu@quobyte.com>
5a6f97
(cherry picked from commit 027d0d17c8a4605109f09d9c988e255b64a2c19a)
5a6f97
Signed-off-by: Pavel Reichl <preichl@redhat.com>
5a6f97
---
5a6f97
 ChangeLog.rst       |  7 +++++++
5a6f97
 lib/fuse_i.h        |  6 ++++++
5a6f97
 lib/fuse_lowlevel.c | 30 +++++++++++++++++++++---------
5a6f97
 3 files changed, 34 insertions(+), 9 deletions(-)
5a6f97
5a6f97
diff --git a/ChangeLog.rst b/ChangeLog.rst
5a6f97
index 8ea9397..411cd4a 100644
5a6f97
--- a/ChangeLog.rst
5a6f97
+++ b/ChangeLog.rst
5a6f97
@@ -1,6 +1,13 @@
5a6f97
 libfuse 3.3.0 (2018-11-06)
5a6f97
 ==========================
5a6f97
 
5a6f97
+* Added support for fuse kernel feature `max_pages` which allows to increase
5a6f97
+  the maximum number of pages that can be used per request. This feature was
5a6f97
+  introduced in kernel 4.20. `max_pages` is set based on the value in
5a6f97
+  `max_write`. By default `max_write` will be 1MiB now for kernels that support
5a6f97
+  `max_pages`. If you want smaller buffers or writes you have to set
5a6f97
+  `max_write` manually.
5a6f97
+
5a6f97
 * The `auto_unmount` mode now works correctly in combination with
5a6f97
   autofs.
5a6f97
 
5a6f97
diff --git a/lib/fuse_i.h b/lib/fuse_i.h
5a6f97
index cf35551..d38b630 100644
5a6f97
--- a/lib/fuse_i.h
5a6f97
+++ b/lib/fuse_i.h
5a6f97
@@ -131,3 +131,9 @@ struct fuse *fuse_new_31(struct fuse_args *args, const struct fuse_operations *o
5a6f97
 int fuse_loop_mt_32(struct fuse *f, struct fuse_loop_config *config);
5a6f97
 int fuse_session_loop_mt_32(struct fuse_session *se, struct fuse_loop_config *config);
5a6f97
 
5a6f97
+#define FUSE_MAX_MAX_PAGES 256
5a6f97
+#define FUSE_DEFAULT_MAX_PAGES_PER_REQ 32
5a6f97
+
5a6f97
+/* room needed in buffer to accommodate header */
5a6f97
+#define FUSE_BUFFER_HEADER_SIZE 0x1000
5a6f97
+
5a6f97
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
5a6f97
index 844e797..60195e0 100644
5a6f97
--- a/lib/fuse_lowlevel.c
5a6f97
+++ b/lib/fuse_lowlevel.c
5a6f97
@@ -1882,6 +1882,14 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
5a6f97
 			se->conn.capable |= FUSE_CAP_POSIX_ACL;
5a6f97
 		if (arg->flags & FUSE_HANDLE_KILLPRIV)
5a6f97
 			se->conn.capable |= FUSE_CAP_HANDLE_KILLPRIV;
5a6f97
+		if (!(arg->flags & FUSE_MAX_PAGES)) {
5a6f97
+			size_t max_bufsize =
5a6f97
+				FUSE_DEFAULT_MAX_PAGES_PER_REQ * getpagesize()
5a6f97
+				+ FUSE_BUFFER_HEADER_SIZE;
5a6f97
+			if (bufsize > max_bufsize) {
5a6f97
+				bufsize = max_bufsize;
5a6f97
+			}
5a6f97
+		}
5a6f97
 	} else {
5a6f97
 		se->conn.max_readahead = 0;
5a6f97
 	}
5a6f97
@@ -1928,10 +1936,10 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
5a6f97
 			bufsize);
5a6f97
 		bufsize = FUSE_MIN_READ_BUFFER;
5a6f97
 	}
5a6f97
+	se->bufsize = bufsize;
5a6f97
 
5a6f97
-	bufsize -= 4096;
5a6f97
-	if (bufsize < se->conn.max_write)
5a6f97
-		se->conn.max_write = bufsize;
5a6f97
+	if (se->conn.max_write > bufsize - FUSE_BUFFER_HEADER_SIZE)
5a6f97
+		se->conn.max_write = bufsize - FUSE_BUFFER_HEADER_SIZE;
5a6f97
 
5a6f97
 	se->got_init = 1;
5a6f97
 	if (se->op.init)
5a6f97
@@ -1958,6 +1966,14 @@ static void do_init(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
5a6f97
 		return;
5a6f97
 	}
5a6f97
 
5a6f97
+	if (se->conn.max_write < bufsize - FUSE_BUFFER_HEADER_SIZE) {
5a6f97
+		se->bufsize = se->conn.max_write + FUSE_BUFFER_HEADER_SIZE;
5a6f97
+	}
5a6f97
+	if (arg->flags & FUSE_MAX_PAGES) {
5a6f97
+		outarg.flags |= FUSE_MAX_PAGES;
5a6f97
+		outarg.max_pages = (se->conn.max_write - 1) / getpagesize() + 1;
5a6f97
+	}
5a6f97
+
5a6f97
 	/* Always enable big writes, this is superseded
5a6f97
 	   by the max_write option */
5a6f97
 	outarg.flags |= FUSE_BIG_WRITES;
5a6f97
@@ -2779,11 +2795,6 @@ restart:
5a6f97
 	return res;
5a6f97
 }
5a6f97
 
5a6f97
-#define KERNEL_BUF_PAGES 32
5a6f97
-
5a6f97
-/* room needed in buffer to accommodate header */
5a6f97
-#define HEADER_SIZE 0x1000
5a6f97
-
5a6f97
 struct fuse_session *fuse_session_new(struct fuse_args *args,
5a6f97
 				      const struct fuse_lowlevel_ops *op,
5a6f97
 				      size_t op_size, void *userdata)
5a6f97
@@ -2844,7 +2855,8 @@ struct fuse_session *fuse_session_new(struct fuse_args *args,
5a6f97
 	if (se->debug)
5a6f97
 		fprintf(stderr, "FUSE library version: %s\n", PACKAGE_VERSION);
5a6f97
 
5a6f97
-	se->bufsize = KERNEL_BUF_PAGES * getpagesize() + HEADER_SIZE;
5a6f97
+	se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() +
5a6f97
+		FUSE_BUFFER_HEADER_SIZE;
5a6f97
 
5a6f97
 	list_init_req(&se->list);
5a6f97
 	list_init_req(&se->interrupts);
5a6f97
-- 
5a6f97
2.36.1
5a6f97