aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGiuseppe Scrivano <giuseppe@scrivano.org>2019-07-23 21:52:16 +0200
committerNikolaus Rath <Nikolaus@rath.org>2019-07-23 12:52:16 -0700
commitf0e08cc700d629da2d46def8b620b0ed858cc0d9 (patch)
tree0dd2751cc9e8688b3486192bf2eb8151aa4e8013 /lib
parent249942f6411042c4af18bd10438da34801cce02b (diff)
downloadlibfuse-f0e08cc700d629da2d46def8b620b0ed858cc0d9.tar.gz
fuse-lowlevel: set pipe size to max (#438)
on failure to set the pipe size, set it to the maximum allowed by the kernel. If the first request required more than the maximum allowed, the can_grow flag would be reset thus preventing any further resize. Grow the pipe to the maximum allowed to increase the likelihood of using splice for successive requests instead of falling back to read/write. Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/fuse_lowlevel.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c
index 3684b8b..b9f128f 100644
--- a/lib/fuse_lowlevel.c
+++ b/lib/fuse_lowlevel.c
@@ -611,6 +611,35 @@ static int read_back(int fd, char *buf, size_t len)
return 0;
}
+static int grow_pipe_to_max(int pipefd)
+{
+ int max;
+ int res;
+ int maxfd;
+ char buf[32];
+
+ maxfd = open("/proc/sys/fs/pipe-max-size", O_RDONLY);
+ if (maxfd < 0)
+ return -errno;
+
+ res = read(maxfd, buf, sizeof(buf) - 1);
+ if (res < 0) {
+ int saved_errno;
+
+ saved_errno = errno;
+ close(maxfd);
+ return -saved_errno;
+ }
+ close(maxfd);
+ buf[res] = '\0';
+
+ max = atoi(buf);
+ res = fcntl(pipefd, F_SETPIPE_SZ, max);
+ if (res < 0)
+ return -errno;
+ return max;
+}
+
static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
struct iovec *iov, int iov_count,
struct fuse_bufvec *buf, unsigned int flags)
@@ -666,6 +695,9 @@ static int fuse_send_data_iov(struct fuse_session *se, struct fuse_chan *ch,
if (llp->can_grow) {
res = fcntl(llp->pipe[0], F_SETPIPE_SZ, pipesize);
if (res == -1) {
+ res = grow_pipe_to_max(llp->pipe[0]);
+ if (res > 0)
+ llp->size = res;
llp->can_grow = 0;
goto fallback;
}
@@ -2694,6 +2726,9 @@ int fuse_session_receive_buf_int(struct fuse_session *se, struct fuse_buf *buf,
res = fcntl(llp->pipe[0], F_SETPIPE_SZ, bufsize);
if (res == -1) {
llp->can_grow = 0;
+ res = grow_pipe_to_max(llp->pipe[0]);
+ if (res > 0)
+ llp->size = res;
goto fallback;
}
llp->size = res;