diff --git a/cmd/cmount/fs.go b/cmd/cmount/fs.go index 6b51fd0cf..0a35edc59 100644 --- a/cmd/cmount/fs.go +++ b/cmd/cmount/fs.go @@ -251,7 +251,14 @@ func (fsys *FS) Readdir(dirPath string, fs.Errorf(dirPath, "Name too long (%d bytes) for FUSE, skipping: %s", len(name), name) continue } - fill(name, nil, 0) + if usingReaddirPlus { + // We have called host.SetCapReaddirPlus() so supply the stat information + var stat fuse.Stat_t + _ = fsys.stat(node, &stat) // not capable of returning an error + fill(name, &stat, 0) + } else { + fill(name, nil, 0) + } } } itemsRead = len(items) diff --git a/cmd/cmount/mount.go b/cmd/cmount/mount.go index 330029d0b..36985fdcb 100644 --- a/cmd/cmount/mount.go +++ b/cmd/cmount/mount.go @@ -26,6 +26,13 @@ import ( "github.com/rclone/rclone/vfs/vfsflags" ) +const ( + // SetCapReaddirPlus informs the host that the hosted file system has the readdir-plus + // capability [Windows only]. A file system that has the readdir-plus capability can send + // full stat information during Readdir, thus avoiding extraneous Getattr calls. + usingReaddirPlus = runtime.GOOS == "windows" +) + func init() { name := "cmount" if runtime.GOOS == "windows" { @@ -142,6 +149,9 @@ func mount(f fs.Fs, mountpoint string) (*vfs.VFS, <-chan error, func() error, er // Create underlying FS fsys := NewFS(f) host := fuse.NewFileSystemHost(fsys) + if usingReaddirPlus { + host.SetCapReaddirPlus(true) + } // Create options options := mountOptions(f.Name()+":"+f.Root(), mountpoint)