Initialize session buffer size to value set by sysctl
authorJoanne Koong <joannelkoong@gmail.com>
Thu, 26 Sep 2024 00:49:56 +0000 (17:49 -0700)
committerBernd Schubert <bernd.schubert@fastmail.fm>
Sat, 28 Sep 2024 10:24:25 +0000 (12:24 +0200)
Currently in libfuse, the buffer size for a fuse session is
capped at 1 MiB on a 4k page system. A recent patch
upstream [1] was merged that allows the max number of pages
per fuse request to be dynamically configurable through the
/proc/sys interface (/proc/sys/fs/fuse/max_pages_limit).

This commit adds support for this on the libfuse side to set
the fuse session buffer to take into account the max pages
limit set in /proc/sys/fs/fuse/max_pages_limit. If this
sysctl does not exist (eg older kernels), it will default to
old behavior (using FUSE_MAX_MAX_PAGES (256) as the max pages
limit). This allows for things like bigger write buffers per
request.

[1] https://lore.kernel.org/linux-fsdevel/20240923171311.1561917-1-joannelkoong@gmail.com/T/#t

lib/fuse_lowlevel.c

index 8bfeb01279ebf3b5cbd42319c86d398335d22213..824dbab4f76cb681a3106cde1096ce62488d97b3 100644 (file)
@@ -2907,6 +2907,29 @@ static void fuse_ll_pipe_destructor(void *data)
        fuse_ll_pipe_free(llp);
 }
 
+static unsigned int get_max_pages(void)
+{
+       char buf[32];
+       int res;
+       int fd;
+
+       fd = open("/proc/sys/fs/fuse/max_pages_limit", O_RDONLY);
+       if (fd < 0)
+               return FUSE_MAX_MAX_PAGES;
+
+       res = read(fd, buf, sizeof(buf) - 1);
+
+       close(fd);
+
+       if (res < 0)
+               return FUSE_MAX_MAX_PAGES;
+
+       buf[res] = '\0';
+
+       res = strtol(buf, NULL, 10);
+       return res < 0 ? FUSE_MAX_MAX_PAGES : res;
+}
+
 int fuse_session_receive_buf(struct fuse_session *se, struct fuse_buf *buf)
 {
        return fuse_session_receive_buf_int(se, buf, NULL);
@@ -3142,7 +3165,7 @@ struct fuse_session *_fuse_session_new_317(struct fuse_args *args,
        if (se->debug)
                fuse_log(FUSE_LOG_DEBUG, "FUSE library version: %s\n", PACKAGE_VERSION);
 
-       se->bufsize = FUSE_MAX_MAX_PAGES * getpagesize() +
+       se->bufsize = get_max_pages() * getpagesize() +
                FUSE_BUFFER_HEADER_SIZE;
 
        list_init_req(&se->list);