Module Name: src Committed By: manu Date: Tue Oct 18 15:06:17 UTC 2016
Modified Files: src/lib/libperfuse: libperfuse.3 perfuse.c src/usr.sbin/perfused: msg.c perfused.8 Log Message: Make FUSE socket buffer tunable When dealing with high I/O throughput, we could run out of buffer space if the filesystem was not consuming requests fast enough. Here we slightly raise the buffer size, and we make it tunable through the PERFUSE_BUFSIZE environment variable so that we can cope with higher requirement later. While there, document PERFUSE_OPTIONS environment variable. To generate a diff of this commit: cvs rdiff -u -r1.3 -r1.4 src/lib/libperfuse/libperfuse.3 cvs rdiff -u -r1.37 -r1.38 src/lib/libperfuse/perfuse.c cvs rdiff -u -r1.22 -r1.23 src/usr.sbin/perfused/msg.c cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/perfused/perfused.8 Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libperfuse/libperfuse.3 diff -u src/lib/libperfuse/libperfuse.3:1.3 src/lib/libperfuse/libperfuse.3:1.4 --- src/lib/libperfuse/libperfuse.3:1.3 Tue May 10 12:14:37 2011 +++ src/lib/libperfuse/libperfuse.3 Tue Oct 18 15:06:17 2016 @@ -1,4 +1,4 @@ -.\" $NetBSD: libperfuse.3,v 1.3 2011/05/10 12:14:37 njoly Exp $ +.\" $NetBSD: libperfuse.3,v 1.4 2016/10/18 15:06:17 manu Exp $ .\" .\" Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. .\" @@ -100,6 +100,21 @@ is different than .Fn perfuse_open handles control to the regular .Xr open 2 . +.Sh ENVIRONMENT +.Bl -tag -width Er +.It Ev PERFUSE_OPTIONS +Comma-separated values controlling the usage of some FUSE methods. Allowed +values are +.Li enable_access , +.Li disable_access , +.Li enable_creat , +.Li disable_creat . +.It Ev PERFUSE_BUFSIZE +Set the socket buffer sizes used for communication with the filesystem. +This should be raised as operation throughput requires it. Default is +.Li 2162688 +bytes, which is enough to queue 16 FUSE packets of maximum 132 kB length. +.El .Sh RETURN VALUES .Fn perfuse_mount returns a file descriptor to the Index: src/lib/libperfuse/perfuse.c diff -u src/lib/libperfuse/perfuse.c:1.37 src/lib/libperfuse/perfuse.c:1.38 --- src/lib/libperfuse/perfuse.c:1.37 Fri Jun 19 17:33:20 2015 +++ src/lib/libperfuse/perfuse.c Tue Oct 18 15:06:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse.c,v 1.37 2015/06/19 17:33:20 christos Exp $ */ +/* $NetBSD: perfuse.c,v 1.38 2016/10/18 15:06:17 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -51,6 +51,7 @@ extern char **environ; static struct perfuse_state *init_state(void); static int get_fd(const char *); +static uint32_t bufvar_from_env(const char *, const uint32_t); static struct perfuse_state * @@ -146,6 +147,35 @@ get_fd(const char *data) } +static uint32_t +bufvar_from_env(name, defval) + const char *name; + const uint32_t defval; +{ + char valstr[1024]; + uint32_t retval = defval; + + if (getenv_r(name, valstr, sizeof(valstr)) != -1) { + long int val; + char *ep; + + errno = 0; + val = (int)strtol(valstr, &ep, 10); + if (*valstr == '\0' || *ep != '\0') + DWARNX("bad %s value \"%s\"", name, valstr); + else if (errno != 0) + DWARN("bad %s value \"%s\"", name, valstr); + else if (val <= 0L || + (unsigned long int)val > (unsigned long int)UINT32_MAX) + DWARNX("%s value %ld out of " + "uint32_t bounds", name, val); + else + retval = val; + } + + return retval; +} + int perfuse_open(const char *path, int flags, mode_t mode) { @@ -180,10 +210,10 @@ perfuse_open(const char *path, int flags } /* - * Set a buffer lentgh large enough so that any FUSE packet + * Set a buffer lentgh large enough so that enough FUSE packets * will fit. */ - opt = (uint32_t)FUSE_BUFSIZE; + opt = bufvar_from_env("PERFUSE_BUFSIZE", 16 * FUSE_BUFSIZE); optlen = sizeof(opt); if (setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &opt, optlen) != 0) DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt); @@ -211,10 +241,10 @@ perfuse_open(const char *path, int flags } /* - * Set a buffer lentgh large enough so that any FUSE packet + * Set a buffer lentgh large enough so that enough FUSE packets * will fit. */ - opt = (uint32_t)(4 * FUSE_BUFSIZE); + opt = bufvar_from_env("PERFUSE_BUFSIZE", 16 * FUSE_BUFSIZE); optlen = sizeof(opt); if (setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &opt, optlen) != 0) DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt); Index: src/usr.sbin/perfused/msg.c diff -u src/usr.sbin/perfused/msg.c:1.22 src/usr.sbin/perfused/msg.c:1.23 --- src/usr.sbin/perfused/msg.c:1.22 Sat Aug 16 16:32:04 2014 +++ src/usr.sbin/perfused/msg.c Tue Oct 18 15:06:17 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: msg.c,v 1.22 2014/08/16 16:32:04 manu Exp $ */ +/* $NetBSD: msg.c,v 1.23 2016/10/18 15:06:17 manu Exp $ */ /*- * Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. @@ -43,11 +43,41 @@ #include "perfused.h" +static uint32_t bufvar_from_env(const char const *, const uint32_t); static int xchg_pb_inloop(struct puffs_usermount *a, struct puffs_framebuf *, int, enum perfuse_xchg_pb_reply); static int xchg_pb_early(struct puffs_usermount *a, struct puffs_framebuf *, int, enum perfuse_xchg_pb_reply); +static uint32_t +bufvar_from_env(name, defval) + const char *name; + const uint32_t defval; +{ + char valstr[1024]; + uint32_t retval = defval; + + if (getenv_r(name, valstr, sizeof(valstr)) != -1) { + long int val; + char *ep; + + errno = 0; + val = (int)strtol(valstr, &ep, 10); + if (*valstr == '\0' || *ep != '\0') + DWARNX("bad %s value \"%s\"", name, valstr); + else if (errno != 0) + DWARN("bad %s value \"%s\"", name, valstr); + else if (val <= 0L || + (unsigned long int)val > (unsigned long int)UINT32_MAX) + DWARNX("%s value %ld out of " + "uint32_t bounds", name, val); + else + retval = val; + } + + return retval; +} + int perfused_open_sock(void) { @@ -80,15 +110,13 @@ perfused_open_sock(void) /* * Set a buffer lentgh large enough so that a few FUSE packets * will fit. - * XXX We will have to find how many packets we need */ - opt = 4 * FUSE_BUFSIZE; + opt = bufvar_from_env("PERFUSE_BUFSIZE", 16 * FUSE_BUFSIZE); if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) != 0) - DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt); + DWARN("%s: setsockopt SO_SNDBUF = %d failed", __func__, opt); - opt = 4 * FUSE_BUFSIZE; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) != 0) - DWARN("%s: setsockopt SO_RCVBUF to %d failed", __func__, opt); + DWARN("%s: setsockopt SO_RCVBUF = %d failed", __func__, opt); /* * Request peer credentials Index: src/usr.sbin/perfused/perfused.8 diff -u src/usr.sbin/perfused/perfused.8:1.11 src/usr.sbin/perfused/perfused.8:1.12 --- src/usr.sbin/perfused/perfused.8:1.11 Sun Jan 29 11:32:23 2012 +++ src/usr.sbin/perfused/perfused.8 Tue Oct 18 15:06:17 2016 @@ -1,4 +1,4 @@ -.\" $NetBSD: perfused.8,v 1.11 2012/01/29 11:32:23 wiz Exp $ +.\" $NetBSD: perfused.8,v 1.12 2016/10/18 15:06:17 manu Exp $ .\" .\" Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved. .\" @@ -118,6 +118,12 @@ is started from Enable debug output only when receiving .Li SIGINFO . .El +.Sh ENVIRONMENT +See +.Xr libperfuse 3 +for environment variables affecting +.Nm +behavior. .Sh SIGNALS .Bl -tag -width indent .It Dv SIGINFO