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

Reply via email to