mount,cmount,mount2: add --direct-io flag to force uncached access

This change adds the --direct-io flag to the mount. This means the
page cache is completely bypassed for reads and writes. No read-ahead
takes place. Shared mmap is disabled.

This is useful to accurately read files which may change length
frequently on the source.
This commit is contained in:
Nick Craig-Wood 2024-03-04 11:37:18 +00:00
parent f3f743c3f9
commit a67688dcc7
5 changed files with 15 additions and 2 deletions

View File

@ -27,6 +27,7 @@ const fhUnset = ^uint64(0)
type FS struct {
VFS *vfs.VFS
f fs.Fs
opt *mountlib.Options
ready chan (struct{})
mu sync.Mutex // to protect the below
handles []vfs.Handle
@ -34,10 +35,11 @@ type FS struct {
}
// NewFS makes a new FS
func NewFS(VFS *vfs.VFS) *FS {
func NewFS(VFS *vfs.VFS, opt *mountlib.Options) *FS {
fsys := &FS{
VFS: VFS,
f: VFS.Fs(),
opt: opt,
ready: make(chan (struct{})),
}
return fsys
@ -309,6 +311,9 @@ func (fsys *FS) OpenEx(path string, fi *fuse.FileInfo_t) (errc int) {
if entry := handle.Node().DirEntry(); entry != nil && entry.Size() < 0 {
fi.DirectIo = true
}
if fsys.opt.DirectIO {
fi.DirectIo = true
}
fi.Fh = fsys.openHandle(handle)
return 0

View File

@ -149,7 +149,7 @@ func mount(VFS *vfs.VFS, mountPath string, opt *mountlib.Options) (<-chan error,
fs.Debugf(nil, "Mounting on %q (%q)", mountpoint, opt.VolumeName)
// Create underlying FS
fsys := NewFS(VFS)
fsys := NewFS(VFS, opt)
host := fuse.NewFileSystemHost(fsys)
host.SetCapReaddirPlus(true) // only works on Windows
if opt.CaseInsensitive.Valid {

View File

@ -78,6 +78,9 @@ func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR
if entry := handle.Node().DirEntry(); entry != nil && entry.Size() < 0 {
resp.Flags |= fuse.OpenDirectIO
}
if f.fsys.opt.DirectIO {
resp.Flags |= fuse.OpenDirectIO
}
return &FileHandle{handle}, nil
}

View File

@ -158,6 +158,9 @@ func (n *Node) Open(ctx context.Context, flags uint32) (fh fusefs.FileHandle, fu
if entry := n.node.DirEntry(); entry != nil && entry.Size() < 0 {
fuseFlags |= fuse.FOPEN_DIRECT_IO
}
if n.fsys.opt.DirectIO {
fuseFlags |= fuse.FOPEN_DIRECT_IO
}
return newFileHandle(handle, n.fsys), fuseFlags, 0
}

View File

@ -52,6 +52,7 @@ type Options struct {
DaemonTimeout time.Duration // OSXFUSE only
AsyncRead bool
NetworkMode bool // Windows only
DirectIO bool // use Direct IO for file access
CaseInsensitive fs.Tristate
}
@ -145,6 +146,7 @@ func AddFlags(flagSet *pflag.FlagSet) {
flags.BoolVarP(flagSet, &Opt.WritebackCache, "write-back-cache", "", Opt.WritebackCache, "Makes kernel buffer writes before sending them to rclone (without this, writethrough caching is used) (not supported on Windows)", "Mount")
flags.StringVarP(flagSet, &Opt.DeviceName, "devname", "", Opt.DeviceName, "Set the device name - default is remote:path", "Mount")
flags.FVarP(flagSet, &Opt.CaseInsensitive, "mount-case-insensitive", "", "Tell the OS the mount is case insensitive (true) or sensitive (false) regardless of the backend (auto)", "Mount")
flags.BoolVarP(flagSet, &Opt.DirectIO, "direct-io", "", Opt.DirectIO, "Use Direct IO, disables caching of data", "Mount")
// Windows and OSX
flags.StringVarP(flagSet, &Opt.VolumeName, "volname", "", Opt.VolumeName, "Set the volume name (supported on Windows and OSX only)", "Mount")
// OSX only