diff --git a/cmd/mount2/mount.go b/cmd/mount2/mount.go index 152f3a89e..e9b82dd04 100644 --- a/cmd/mount2/mount.go +++ b/cmd/mount2/mount.go @@ -32,6 +32,8 @@ func mountOptions(fsys *FS, f fs.Fs, opt *mountlib.Options) (mountOpts *fuse.Mou DisableXAttrs: true, Debug: fsys.opt.DebugFUSE, MaxReadAhead: int(fsys.opt.MaxReadAhead), + MaxWrite: 1024 * 1024, // Linux v4.20+ caps requests at 1 MiB + DisableReadDirPlus: true, // RememberInodes: true, // SingleThreaded: true, @@ -47,12 +49,42 @@ func mountOptions(fsys *FS, f fs.Fs, opt *mountlib.Options) (mountOpts *fuse.Mou // async I/O. Concurrency for synchronous I/O is not limited. MaxBackground int - // Write size to use. If 0, use default. This number is - // capped at the kernel maximum. + // MaxWrite is the max size for read and write requests. If 0, use + // go-fuse default (currently 64 kiB). + // This number is internally capped at MAX_KERNEL_WRITE (higher values don't make + // sense). + // + // Non-direct-io reads are mostly served via kernel readahead, which is + // additionally subject to the MaxReadAhead limit. + // + // Implementation notes: + // + // There's four values the Linux kernel looks at when deciding the request size: + // * MaxWrite, passed via InitOut.MaxWrite. Limits the WRITE size. + // * max_read, passed via a string mount option. Limits the READ size. + // go-fuse sets max_read equal to MaxWrite. + // You can see the current max_read value in /proc/self/mounts . + // * MaxPages, passed via InitOut.MaxPages. In Linux 4.20 and later, the value + // can go up to 1 MiB and go-fuse calculates the MaxPages value acc. + // to MaxWrite, rounding up. + // On older kernels, the value is fixed at 128 kiB and the + // passed value is ignored. No request can be larger than MaxPages, so + // READ and WRITE are effectively capped at MaxPages. + // * MaxReadAhead, passed via InitOut.MaxReadAhead. MaxWrite int - // Max read ahead to use. If 0, use default. This number is - // capped at the kernel maximum. + // MaxReadAhead is the max read ahead size to use. It controls how much data the + // kernel reads in advance to satisfy future read requests from applications. + // How much exactly is subject to clever heuristics in the kernel + // (see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/mm/readahead.c?h=v6.2-rc5#n375 + // if you are brave) and hence also depends on the kernel version. + // + // If 0, use kernel default. This number is capped at the kernel maximum + // (128 kiB on Linux) and cannot be larger than MaxWrite. + // + // MaxReadAhead only affects buffered reads (=non-direct-io), but even then, the + // kernel can and does send larger reads to satisfy read reqests from applications + // (up to MaxWrite or VM_READAHEAD_PAGES=128 kiB, whichever is less). MaxReadAhead int // If IgnoreSecurityLabels is set, all security related xattr @@ -87,9 +119,19 @@ func mountOptions(fsys *FS, f fs.Fs, opt *mountlib.Options) (mountOpts *fuse.Mou // you must implement the GetLk/SetLk/SetLkw methods. EnableLocks bool + // If set, the kernel caches all Readlink return values. The + // filesystem must use content notification to force the + // kernel to issue a new Readlink call. + EnableSymlinkCaching bool + // If set, ask kernel not to do automatic data cache invalidation. // The filesystem is fully responsible for invalidating data cache. ExplicitDataCacheControl bool + + // Disable ReadDirPlus capability so ReadDir is used instead. Simple + // directory queries (i.e. 'ls' without '-l') can be faster with + // ReadDir, as no per-file stat calls are needed + DisableReadDirPlus bool */ } diff --git a/cmd/mount2/mount_test.go b/cmd/mount2/mount_test.go index c6572a983..e90632f02 100644 --- a/cmd/mount2/mount_test.go +++ b/cmd/mount2/mount_test.go @@ -1,16 +1,14 @@ -//go:build linux || (darwin && amd64) -// +build linux darwin,amd64 +//go:build linux +// +build linux package mount2 import ( "testing" - "github.com/rclone/rclone/fstest/testy" "github.com/rclone/rclone/vfs/vfstest" ) func TestMount(t *testing.T) { - testy.SkipUnreliable(t) vfstest.RunTests(t, false, mount) } diff --git a/go.mod b/go.mod index da6987c4f..988a2b420 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/gdamore/tcell/v2 v2.6.0 github.com/go-chi/chi/v5 v5.0.8 github.com/google/uuid v1.3.0 - github.com/hanwen/go-fuse/v2 v2.2.0 + github.com/hanwen/go-fuse/v2 v2.2.1-0.20230410213758-80c1c8221982 github.com/hirochachacha/go-smb2 v1.1.0 github.com/iguanesolutions/go-systemd/v5 v5.1.1 github.com/jcmturner/gokrb5/v8 v8.4.4 diff --git a/go.sum b/go.sum index d7a4e3749..a39ae52de 100644 --- a/go.sum +++ b/go.sum @@ -248,8 +248,8 @@ github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyC github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/hanwen/go-fuse/v2 v2.2.0 h1:jo5QZYmBLNcl9ovypWaQ5yXMSSV+Ch68xoC3rtZvvBM= -github.com/hanwen/go-fuse/v2 v2.2.0/go.mod h1:B1nGE/6RBFyBRC1RRnf23UpwCdyJ31eukw34oAKukAc= +github.com/hanwen/go-fuse/v2 v2.2.1-0.20230410213758-80c1c8221982 h1:2620K4xZZUW81Nef9jqNJNS1UxAO6Fsb//FVDSC3KHw= +github.com/hanwen/go-fuse/v2 v2.2.1-0.20230410213758-80c1c8221982/go.mod h1:xKwi1cF7nXAOBCXujD5ie0ZKsxc8GGSA1rlMJc+8IJs= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -345,6 +345,8 @@ github.com/minio/minio-go/v6 v6.0.46/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tB github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=