[Bug 271065] Kernel FUSE limits read() size by 64k/128k

From: <bugzilla-noreply_at_freebsd.org>
Date: Tue, 25 Apr 2023 16:24:16 UTC

--- Comment #4 from Alan Somers <asomers@FreeBSD.org> ---
(In reply to Ivan Rozhuk from comment #2)
> fuse: unknown option(s): `-o async_read'
> looks like it was not handled.
> I do not see code to handle it in sshfs and in kernel FUSE.

Annoying, because it's mentioned in the sshfs man page:
https://linux.die.net/man/1/sshfs .

> Read ahead is work. There is comment in kernel FUSE code that it read one
> block ahead, so this is why I got 64+64=128k read request.

Where do you see that comment?  It's definitely possible to read ahead more
than that.  For example:

$ cd /usr/tests/sys/fs/fusefs
$ sudo sysctl vfs.usermount=1
$ sudo kldload fusefs
$ mkdir mountpoint
$ sudo chmod 1777 mountpoint
$ ./read --gtest_filter=RA/ReadAhead.readahead/3 -v
Note: Google Test filter = RA/ReadAhead.readahead/3
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from RA/ReadAhead
[ RUN      ] RA/ReadAhead.readahead/3
INIT        ino= 0
ACCESS      ino= 1 mask=0x1
LOOKUP      ino= 1 some_file.txt
OPEN        ino=42 flags=0
BMAP        ino=42 block=0 blocksize=0x10000
READ        ino=42 offset=0 size=262144
[       OK ] RA/ReadAhead.readahead/3 (2 ms)
[----------] 1 test from RA/ReadAhead (2 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (2 ms total)
[  PASSED  ] 1 test.

That shows a 256kB read.  By tweaking the test's source a bit, I can make it
read up to 1 MB.  I haven't tried higher.

The FUSE server can limit the amount of readahead at mount time.  Looking at
the source, it seems that sshfs sets the limit to UINT_MAX.  However, I see a
discrepancy between what libfuse does and what the fusefs test suite does. 
Could you please try this patch and tell me what you find?

diff --git a/sys/fs/fuse/fuse_internal.c b/sys/fs/fuse/fuse_internal.c
index 6ac7b4432e23..173fe7a71234 100644
--- a/sys/fs/fuse/fuse_internal.c
+++ b/sys/fs/fuse/fuse_internal.c
@@ -1096,7 +1096,7 @@ fuse_internal_send_init(struct fuse_data *data, struct
thread *td)
         * fusefs currently reads ahead no more than one cache block at a time.
         * See fuse_read_biobackend
-       fiii->max_readahead = maxbcachebuf;
+       fiii->max_readahead = maxphys;
         * Unsupported features:
         * FUSE_FILE_OPS: No known FUSE server or client supports it

You are receiving this mail because:
You are the assignee for the bug.