diff options
author | Bernd Schubert <bschubert@ddn.com> | 2025-03-07 22:43:50 +0100 |
---|---|---|
committer | Bernd Schubert <bernd@bsbernd.com> | 2025-03-14 12:58:14 +0100 |
commit | 065272a23392011ea1728c4f2d20e63cf6579e7d (patch) | |
tree | 48834b949e6767f62ff7023093e6767ff831b9e3 | |
parent | 3ae5ca7443348aabad9bc71b9d5b0999f8292379 (diff) | |
download | libfuse-065272a23392011ea1728c4f2d20e63cf6579e7d.tar.gz |
fuse_session_receive_buf: Fix the pipe buf size
This fixes dynamic buffer allocation in commit
0e0f43b79b9b ("Reallocate fuse_session buffer...")
I noticed that when I increased the default fuse buf size as
possible in recent kernels.
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
-rw-r--r-- | lib/fuse_i.h | 4 | ||||
-rw-r--r-- | lib/fuse_lowlevel.c | 12 |
2 files changed, 13 insertions, 3 deletions
diff --git a/lib/fuse_i.h b/lib/fuse_i.h index ea04c34..69ca159 100644 --- a/lib/fuse_i.h +++ b/lib/fuse_i.h @@ -72,14 +72,14 @@ struct fuse_session { int broken_splice_nonblock; uint64_t notify_ctr; struct fuse_notify_req notify_list; - size_t bufsize; + _Atomic size_t bufsize; int error; /* This is useful if any kind of ABI incompatibility is found at * a later version, to 'fix' it at run time. */ struct libfuse_version version; - bool buf_reallocable; + _Atomic bool buf_reallocable; }; struct fuse_chan { diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index d650944..0642572 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -3042,11 +3042,14 @@ static int _fuse_session_receive_buf(struct fuse_session *se, { int err; ssize_t res; - size_t bufsize = se->bufsize; + size_t bufsize; #ifdef HAVE_SPLICE struct fuse_ll_pipe *llp; struct fuse_buf tmpbuf; +pipe_retry: + bufsize = se->bufsize; + if (se->conn.proto_minor < 14 || !(se->conn.want_ext & FUSE_CAP_SPLICE_READ)) goto fallback; @@ -3091,6 +3094,13 @@ static int _fuse_session_receive_buf(struct fuse_session *se, fuse_session_exit(se); return 0; } + + /* FUSE_INIT might have increased the required bufsize */ + if (err == EINVAL && bufsize < se->bufsize) { + fuse_ll_clear_pipe(se); + goto pipe_retry; + } + if (err != EINTR && err != EAGAIN) perror("fuse: splice from device"); return -err; |