forked from TrueCloudLab/rclone
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:
parent
f3f743c3f9
commit
a67688dcc7
5 changed files with 15 additions and 2 deletions
|
@ -27,6 +27,7 @@ const fhUnset = ^uint64(0)
|
||||||
type FS struct {
|
type FS struct {
|
||||||
VFS *vfs.VFS
|
VFS *vfs.VFS
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
|
opt *mountlib.Options
|
||||||
ready chan (struct{})
|
ready chan (struct{})
|
||||||
mu sync.Mutex // to protect the below
|
mu sync.Mutex // to protect the below
|
||||||
handles []vfs.Handle
|
handles []vfs.Handle
|
||||||
|
@ -34,10 +35,11 @@ type FS struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFS makes a new FS
|
// NewFS makes a new FS
|
||||||
func NewFS(VFS *vfs.VFS) *FS {
|
func NewFS(VFS *vfs.VFS, opt *mountlib.Options) *FS {
|
||||||
fsys := &FS{
|
fsys := &FS{
|
||||||
VFS: VFS,
|
VFS: VFS,
|
||||||
f: VFS.Fs(),
|
f: VFS.Fs(),
|
||||||
|
opt: opt,
|
||||||
ready: make(chan (struct{})),
|
ready: make(chan (struct{})),
|
||||||
}
|
}
|
||||||
return fsys
|
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 {
|
if entry := handle.Node().DirEntry(); entry != nil && entry.Size() < 0 {
|
||||||
fi.DirectIo = true
|
fi.DirectIo = true
|
||||||
}
|
}
|
||||||
|
if fsys.opt.DirectIO {
|
||||||
|
fi.DirectIo = true
|
||||||
|
}
|
||||||
|
|
||||||
fi.Fh = fsys.openHandle(handle)
|
fi.Fh = fsys.openHandle(handle)
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -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)
|
fs.Debugf(nil, "Mounting on %q (%q)", mountpoint, opt.VolumeName)
|
||||||
|
|
||||||
// Create underlying FS
|
// Create underlying FS
|
||||||
fsys := NewFS(VFS)
|
fsys := NewFS(VFS, opt)
|
||||||
host := fuse.NewFileSystemHost(fsys)
|
host := fuse.NewFileSystemHost(fsys)
|
||||||
host.SetCapReaddirPlus(true) // only works on Windows
|
host.SetCapReaddirPlus(true) // only works on Windows
|
||||||
if opt.CaseInsensitive.Valid {
|
if opt.CaseInsensitive.Valid {
|
||||||
|
|
|
@ -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 {
|
if entry := handle.Node().DirEntry(); entry != nil && entry.Size() < 0 {
|
||||||
resp.Flags |= fuse.OpenDirectIO
|
resp.Flags |= fuse.OpenDirectIO
|
||||||
}
|
}
|
||||||
|
if f.fsys.opt.DirectIO {
|
||||||
|
resp.Flags |= fuse.OpenDirectIO
|
||||||
|
}
|
||||||
|
|
||||||
return &FileHandle{handle}, nil
|
return &FileHandle{handle}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
if entry := n.node.DirEntry(); entry != nil && entry.Size() < 0 {
|
||||||
fuseFlags |= fuse.FOPEN_DIRECT_IO
|
fuseFlags |= fuse.FOPEN_DIRECT_IO
|
||||||
}
|
}
|
||||||
|
if n.fsys.opt.DirectIO {
|
||||||
|
fuseFlags |= fuse.FOPEN_DIRECT_IO
|
||||||
|
}
|
||||||
return newFileHandle(handle, n.fsys), fuseFlags, 0
|
return newFileHandle(handle, n.fsys), fuseFlags, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ type Options struct {
|
||||||
DaemonTimeout time.Duration // OSXFUSE only
|
DaemonTimeout time.Duration // OSXFUSE only
|
||||||
AsyncRead bool
|
AsyncRead bool
|
||||||
NetworkMode bool // Windows only
|
NetworkMode bool // Windows only
|
||||||
|
DirectIO bool // use Direct IO for file access
|
||||||
CaseInsensitive fs.Tristate
|
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.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.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.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
|
// Windows and OSX
|
||||||
flags.StringVarP(flagSet, &Opt.VolumeName, "volname", "", Opt.VolumeName, "Set the volume name (supported on Windows and OSX only)", "Mount")
|
flags.StringVarP(flagSet, &Opt.VolumeName, "volname", "", Opt.VolumeName, "Set the volume name (supported on Windows and OSX only)", "Mount")
|
||||||
// OSX only
|
// OSX only
|
||||||
|
|
Loading…
Reference in a new issue