|
|
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 |
|