vfs: factor flags into vfsflags and remove global variables
This commit is contained in:
parent
1a8f824bad
commit
e8883e9fdb
16 changed files with 144 additions and 115 deletions
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/billziss-gh/cgofuse/fuse"
|
"github.com/billziss-gh/cgofuse/fuse"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/vfs"
|
"github.com/ncw/rclone/vfs"
|
||||||
|
"github.com/ncw/rclone/vfs/vfsflags"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,7 +33,7 @@ type FS struct {
|
||||||
// NewFS makes a new FS
|
// NewFS makes a new FS
|
||||||
func NewFS(f fs.Fs) *FS {
|
func NewFS(f fs.Fs) *FS {
|
||||||
fsys := &FS{
|
fsys := &FS{
|
||||||
VFS: vfs.New(f),
|
VFS: vfs.New(f, &vfsflags.Opt),
|
||||||
f: f,
|
f: f,
|
||||||
openDirs: newOpenFiles(0x01),
|
openDirs: newOpenFiles(0x01),
|
||||||
openFilesWr: newOpenFiles(0x02),
|
openFilesWr: newOpenFiles(0x02),
|
||||||
|
@ -201,19 +202,19 @@ func (fsys *FS) stat(node vfs.Node, stat *fuse.Stat_t) (errc int) {
|
||||||
switch x := node.(type) {
|
switch x := node.(type) {
|
||||||
case *vfs.Dir:
|
case *vfs.Dir:
|
||||||
modTime = x.ModTime()
|
modTime = x.ModTime()
|
||||||
Mode = vfs.DirPerms | fuse.S_IFDIR
|
Mode = fsys.VFS.Opt.DirPerms | fuse.S_IFDIR
|
||||||
case *vfs.File:
|
case *vfs.File:
|
||||||
modTime = x.ModTime()
|
modTime = x.ModTime()
|
||||||
Size = uint64(x.Size())
|
Size = uint64(x.Size())
|
||||||
Blocks = (Size + 511) / 512
|
Blocks = (Size + 511) / 512
|
||||||
Mode = vfs.FilePerms | fuse.S_IFREG
|
Mode = fsys.VFS.Opt.FilePerms | fuse.S_IFREG
|
||||||
}
|
}
|
||||||
//stat.Dev = 1
|
//stat.Dev = 1
|
||||||
stat.Ino = node.Inode() // FIXME do we need to set the inode number?
|
stat.Ino = node.Inode() // FIXME do we need to set the inode number?
|
||||||
stat.Mode = uint32(Mode)
|
stat.Mode = uint32(Mode)
|
||||||
stat.Nlink = 1
|
stat.Nlink = 1
|
||||||
stat.Uid = vfs.UID
|
stat.Uid = fsys.VFS.Opt.UID
|
||||||
stat.Gid = vfs.GID
|
stat.Gid = fsys.VFS.Opt.GID
|
||||||
//stat.Rdev
|
//stat.Rdev
|
||||||
stat.Size = int64(Size)
|
stat.Size = int64(Size)
|
||||||
t := fuse.NewTimespec(modTime)
|
t := fuse.NewTimespec(modTime)
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/ncw/rclone/cmd/mountlib"
|
"github.com/ncw/rclone/cmd/mountlib"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/vfs"
|
"github.com/ncw/rclone/vfs"
|
||||||
|
"github.com/ncw/rclone/vfs/vfsflags"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ func mountOptions(device string, mountpoint string) (options []string) {
|
||||||
if mountlib.DefaultPermissions {
|
if mountlib.DefaultPermissions {
|
||||||
options = append(options, "-o", "default_permissions")
|
options = append(options, "-o", "default_permissions")
|
||||||
}
|
}
|
||||||
if vfs.ReadOnly {
|
if vfsflags.Opt.ReadOnly {
|
||||||
options = append(options, "-o", "ro")
|
options = append(options, "-o", "ro")
|
||||||
}
|
}
|
||||||
if mountlib.WritebackCache {
|
if mountlib.WritebackCache {
|
||||||
|
|
|
@ -36,9 +36,9 @@ var _ fusefs.Node = (*Dir)(nil)
|
||||||
// Attr updates the attributes of a directory
|
// Attr updates the attributes of a directory
|
||||||
func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) (err error) {
|
func (d *Dir) Attr(ctx context.Context, a *fuse.Attr) (err error) {
|
||||||
defer fs.Trace(d, "")("attr=%+v, err=%v", a, &err)
|
defer fs.Trace(d, "")("attr=%+v, err=%v", a, &err)
|
||||||
a.Gid = vfs.GID
|
a.Gid = d.VFS().Opt.GID
|
||||||
a.Uid = vfs.UID
|
a.Uid = d.VFS().Opt.UID
|
||||||
a.Mode = os.ModeDir | vfs.DirPerms
|
a.Mode = os.ModeDir | d.VFS().Opt.DirPerms
|
||||||
modTime := d.ModTime()
|
modTime := d.ModTime()
|
||||||
a.Atime = modTime
|
a.Atime = modTime
|
||||||
a.Mtime = modTime
|
a.Mtime = modTime
|
||||||
|
@ -55,7 +55,7 @@ var _ fusefs.NodeSetattrer = (*Dir)(nil)
|
||||||
// Setattr handles attribute changes from FUSE. Currently supports ModTime only.
|
// Setattr handles attribute changes from FUSE. Currently supports ModTime only.
|
||||||
func (d *Dir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
|
func (d *Dir) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
|
||||||
defer fs.Trace(d, "stat=%+v", req)("err=%v", &err)
|
defer fs.Trace(d, "stat=%+v", req)("err=%v", &err)
|
||||||
if vfs.NoModTime {
|
if d.VFS().Opt.NoModTime {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ func (f *File) Attr(ctx context.Context, a *fuse.Attr) (err error) {
|
||||||
modTime := f.File.ModTime()
|
modTime := f.File.ModTime()
|
||||||
Size := uint64(f.File.Size())
|
Size := uint64(f.File.Size())
|
||||||
Blocks := (Size + 511) / 512
|
Blocks := (Size + 511) / 512
|
||||||
a.Gid = vfs.GID
|
a.Gid = f.VFS().Opt.GID
|
||||||
a.Uid = vfs.UID
|
a.Uid = f.VFS().Opt.UID
|
||||||
a.Mode = vfs.FilePerms
|
a.Mode = f.VFS().Opt.FilePerms
|
||||||
a.Size = Size
|
a.Size = Size
|
||||||
a.Atime = modTime
|
a.Atime = modTime
|
||||||
a.Mtime = modTime
|
a.Mtime = modTime
|
||||||
|
@ -45,7 +45,7 @@ var _ fusefs.NodeSetattrer = (*File)(nil)
|
||||||
// Setattr handles attribute changes from FUSE. Currently supports ModTime only.
|
// Setattr handles attribute changes from FUSE. Currently supports ModTime only.
|
||||||
func (f *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
|
func (f *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
|
||||||
defer fs.Trace(f, "a=%+v", req)("err=%v", &err)
|
defer fs.Trace(f, "a=%+v", req)("err=%v", &err)
|
||||||
if vfs.NoModTime {
|
if f.VFS().Opt.NoModTime {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if req.Valid.MtimeNow() {
|
if req.Valid.MtimeNow() {
|
||||||
|
@ -64,7 +64,7 @@ func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR
|
||||||
defer fs.Trace(f, "flags=%v", req.Flags)("fh=%v, err=%v", &fh, &err)
|
defer fs.Trace(f, "flags=%v", req.Flags)("fh=%v, err=%v", &fh, &err)
|
||||||
switch {
|
switch {
|
||||||
case req.Flags.IsReadOnly():
|
case req.Flags.IsReadOnly():
|
||||||
if vfs.NoSeek {
|
if f.VFS().Opt.NoSeek {
|
||||||
resp.Flags |= fuse.OpenNonSeekable
|
resp.Flags |= fuse.OpenNonSeekable
|
||||||
}
|
}
|
||||||
var rfh *vfs.ReadFileHandle
|
var rfh *vfs.ReadFileHandle
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
fusefs "bazil.org/fuse/fs"
|
fusefs "bazil.org/fuse/fs"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/vfs"
|
"github.com/ncw/rclone/vfs"
|
||||||
|
"github.com/ncw/rclone/vfs/vfsflags"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
@ -27,7 +28,7 @@ var _ fusefs.FS = (*FS)(nil)
|
||||||
// NewFS makes a new FS
|
// NewFS makes a new FS
|
||||||
func NewFS(f fs.Fs) *FS {
|
func NewFS(f fs.Fs) *FS {
|
||||||
fsys := &FS{
|
fsys := &FS{
|
||||||
VFS: vfs.New(f),
|
VFS: vfs.New(f, &vfsflags.Opt),
|
||||||
f: f,
|
f: f,
|
||||||
}
|
}
|
||||||
return fsys
|
return fsys
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"github.com/ncw/rclone/cmd/mountlib"
|
"github.com/ncw/rclone/cmd/mountlib"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/vfs"
|
"github.com/ncw/rclone/vfs"
|
||||||
|
"github.com/ncw/rclone/vfs/vfsflags"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -49,7 +50,7 @@ func mountOptions(device string) (options []fuse.MountOption) {
|
||||||
if mountlib.DefaultPermissions {
|
if mountlib.DefaultPermissions {
|
||||||
options = append(options, fuse.DefaultPermissions())
|
options = append(options, fuse.DefaultPermissions())
|
||||||
}
|
}
|
||||||
if vfs.ReadOnly {
|
if vfsflags.Opt.ReadOnly {
|
||||||
options = append(options, fuse.ReadOnly())
|
options = append(options, fuse.ReadOnly())
|
||||||
}
|
}
|
||||||
if mountlib.WritebackCache {
|
if mountlib.WritebackCache {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/ncw/rclone/cmd"
|
"github.com/ncw/rclone/cmd"
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/ncw/rclone/vfs"
|
"github.com/ncw/rclone/vfs/vfsflags"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ like this:
|
||||||
//flags.BoolVarP(&foreground, "foreground", "", foreground, "Do not detach.")
|
//flags.BoolVarP(&foreground, "foreground", "", foreground, "Do not detach.")
|
||||||
|
|
||||||
// Add in the generic flags
|
// Add in the generic flags
|
||||||
vfs.AddFlags(flags)
|
vfsflags.AddFlags(flags)
|
||||||
|
|
||||||
return commandDefintion
|
return commandDefintion
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,10 +207,10 @@ func (r *Run) readLocal(t *testing.T, dir dirMap, filepath string) {
|
||||||
if fi.IsDir() {
|
if fi.IsDir() {
|
||||||
dir[name+"/"] = struct{}{}
|
dir[name+"/"] = struct{}{}
|
||||||
r.readLocal(t, dir, name)
|
r.readLocal(t, dir, name)
|
||||||
assert.Equal(t, vfs.DirPerms, fi.Mode().Perm())
|
assert.Equal(t, run.vfs.Opt.DirPerms, fi.Mode().Perm())
|
||||||
} else {
|
} else {
|
||||||
dir[fmt.Sprintf("%s %d", name, fi.Size())] = struct{}{}
|
dir[fmt.Sprintf("%s %d", name, fi.Size())] = struct{}{}
|
||||||
assert.Equal(t, vfs.FilePerms, fi.Mode().Perm())
|
assert.Equal(t, run.vfs.Opt.FilePerms, fi.Mode().Perm())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,5 +292,5 @@ func TestRoot(t *testing.T) {
|
||||||
fi, err := os.Lstat(run.mountPath)
|
fi, err := os.Lstat(run.mountPath)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.True(t, fi.IsDir())
|
assert.True(t, fi.IsDir())
|
||||||
assert.Equal(t, fi.Mode().Perm(), vfs.DirPerms)
|
assert.Equal(t, fi.Mode().Perm(), run.vfs.Opt.DirPerms)
|
||||||
}
|
}
|
||||||
|
|
21
vfs/dir.go
21
vfs/dir.go
|
@ -169,7 +169,7 @@ func (d *Dir) _readDir() error {
|
||||||
// fs.Debugf(d.path, "Reading directory")
|
// fs.Debugf(d.path, "Reading directory")
|
||||||
} else {
|
} else {
|
||||||
age := when.Sub(d.read)
|
age := when.Sub(d.read)
|
||||||
if age < d.vfs.dirCacheTime {
|
if age < d.vfs.Opt.DirCacheTime {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
fs.Debugf(d.path, "Re-reading directory (%v old)", age)
|
fs.Debugf(d.path, "Re-reading directory (%v old)", age)
|
||||||
|
@ -260,7 +260,7 @@ func (d *Dir) Size() int64 {
|
||||||
|
|
||||||
// SetModTime sets the modTime for this dir
|
// SetModTime sets the modTime for this dir
|
||||||
func (d *Dir) SetModTime(modTime time.Time) error {
|
func (d *Dir) SetModTime(modTime time.Time) error {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
|
@ -309,7 +309,7 @@ func (d *Dir) ReadDirAll() (items Nodes, err error) {
|
||||||
|
|
||||||
// Create makes a new file
|
// Create makes a new file
|
||||||
func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) {
|
func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return nil, nil, EROFS
|
return nil, nil, EROFS
|
||||||
}
|
}
|
||||||
path := path.Join(d.path, name)
|
path := path.Join(d.path, name)
|
||||||
|
@ -328,7 +328,7 @@ func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) {
|
||||||
|
|
||||||
// Mkdir creates a new directory
|
// Mkdir creates a new directory
|
||||||
func (d *Dir) Mkdir(name string) (*Dir, error) {
|
func (d *Dir) Mkdir(name string) (*Dir, error) {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return nil, EROFS
|
return nil, EROFS
|
||||||
}
|
}
|
||||||
path := path.Join(d.path, name)
|
path := path.Join(d.path, name)
|
||||||
|
@ -347,7 +347,7 @@ func (d *Dir) Mkdir(name string) (*Dir, error) {
|
||||||
|
|
||||||
// Remove the directory
|
// Remove the directory
|
||||||
func (d *Dir) Remove() error {
|
func (d *Dir) Remove() error {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
// Check directory is empty first
|
// Check directory is empty first
|
||||||
|
@ -375,7 +375,7 @@ func (d *Dir) Remove() error {
|
||||||
|
|
||||||
// RemoveAll removes the directory and any contents recursively
|
// RemoveAll removes the directory and any contents recursively
|
||||||
func (d *Dir) RemoveAll() error {
|
func (d *Dir) RemoveAll() error {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
// Remove contents of the directory
|
// Remove contents of the directory
|
||||||
|
@ -403,7 +403,7 @@ func (d *Dir) DirEntry() (entry fs.DirEntry) {
|
||||||
// which must be a directory. The entry to be removed may correspond
|
// which must be a directory. The entry to be removed may correspond
|
||||||
// to a file (unlink) or to a directory (rmdir).
|
// to a file (unlink) or to a directory (rmdir).
|
||||||
func (d *Dir) RemoveName(name string) error {
|
func (d *Dir) RemoveName(name string) error {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
path := path.Join(d.path, name)
|
path := path.Join(d.path, name)
|
||||||
|
@ -418,7 +418,7 @@ func (d *Dir) RemoveName(name string) error {
|
||||||
|
|
||||||
// Rename the file
|
// Rename the file
|
||||||
func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||||
if d.vfs.readOnly {
|
if d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
oldPath := path.Join(d.path, oldName)
|
oldPath := path.Join(d.path, oldName)
|
||||||
|
@ -494,3 +494,8 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||||
func (d *Dir) Fsync() error {
|
func (d *Dir) Fsync() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VFS returns the instance of the VFS
|
||||||
|
func (d *Dir) VFS() *VFS {
|
||||||
|
return d.vfs
|
||||||
|
}
|
||||||
|
|
18
vfs/file.go
18
vfs/file.go
|
@ -98,7 +98,7 @@ func (f *File) ModTime() (modTime time.Time) {
|
||||||
f.mu.Lock()
|
f.mu.Lock()
|
||||||
defer f.mu.Unlock()
|
defer f.mu.Unlock()
|
||||||
|
|
||||||
if !f.d.vfs.noModTime {
|
if !f.d.vfs.Opt.NoModTime {
|
||||||
// if o is nil it isn't valid yet or there are writers, so return the size so far
|
// if o is nil it isn't valid yet or there are writers, so return the size so far
|
||||||
if f.o == nil || f.writers != 0 {
|
if f.o == nil || f.writers != 0 {
|
||||||
if !f.pendingModTime.IsZero() {
|
if !f.pendingModTime.IsZero() {
|
||||||
|
@ -126,7 +126,7 @@ func (f *File) Size() int64 {
|
||||||
|
|
||||||
// SetModTime sets the modtime for the file
|
// SetModTime sets the modtime for the file
|
||||||
func (f *File) SetModTime(modTime time.Time) error {
|
func (f *File) SetModTime(modTime time.Time) error {
|
||||||
if f.d.vfs.readOnly {
|
if f.d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
f.mu.Lock()
|
f.mu.Lock()
|
||||||
|
@ -224,7 +224,7 @@ func (f *File) OpenRead() (fh *ReadFileHandle, err error) {
|
||||||
|
|
||||||
// OpenWrite open the file for write
|
// OpenWrite open the file for write
|
||||||
func (f *File) OpenWrite() (fh *WriteFileHandle, err error) {
|
func (f *File) OpenWrite() (fh *WriteFileHandle, err error) {
|
||||||
if f.d.vfs.readOnly {
|
if f.d.vfs.Opt.ReadOnly {
|
||||||
return nil, EROFS
|
return nil, EROFS
|
||||||
}
|
}
|
||||||
// if o is nil it isn't valid yet
|
// if o is nil it isn't valid yet
|
||||||
|
@ -254,7 +254,7 @@ func (f *File) Fsync() error {
|
||||||
|
|
||||||
// Remove the file
|
// Remove the file
|
||||||
func (f *File) Remove() error {
|
func (f *File) Remove() error {
|
||||||
if f.d.vfs.readOnly {
|
if f.d.vfs.Opt.ReadOnly {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
err := f.o.Remove()
|
err := f.o.Remove()
|
||||||
|
@ -276,3 +276,13 @@ func (f *File) RemoveAll() error {
|
||||||
func (f *File) DirEntry() (entry fs.DirEntry) {
|
func (f *File) DirEntry() (entry fs.DirEntry) {
|
||||||
return f.o
|
return f.o
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Dir returns the directory this file is in
|
||||||
|
func (f *File) Dir() *Dir {
|
||||||
|
return f.d
|
||||||
|
}
|
||||||
|
|
||||||
|
// VFS returns the instance of the VFS
|
||||||
|
func (f *File) VFS() *VFS {
|
||||||
|
return f.d.vfs
|
||||||
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ var (
|
||||||
func newReadFileHandle(f *File, o fs.Object) (*ReadFileHandle, error) {
|
func newReadFileHandle(f *File, o fs.Object) (*ReadFileHandle, error) {
|
||||||
var hash *fs.MultiHasher
|
var hash *fs.MultiHasher
|
||||||
var err error
|
var err error
|
||||||
if !f.d.vfs.noChecksum {
|
if !f.d.vfs.Opt.NoChecksum {
|
||||||
hash, err = fs.NewMultiHasherTypes(o.Fs().Hashes())
|
hash, err = fs.NewMultiHasherTypes(o.Fs().Hashes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(o.Fs(), "newReadFileHandle hash error: %v", err)
|
fs.Errorf(o.Fs(), "newReadFileHandle hash error: %v", err)
|
||||||
|
@ -43,7 +43,7 @@ func newReadFileHandle(f *File, o fs.Object) (*ReadFileHandle, error) {
|
||||||
|
|
||||||
fh := &ReadFileHandle{
|
fh := &ReadFileHandle{
|
||||||
o: o,
|
o: o,
|
||||||
noSeek: f.d.vfs.noSeek,
|
noSeek: f.d.vfs.Opt.NoSeek,
|
||||||
file: f,
|
file: f,
|
||||||
hash: hash,
|
hash: hash,
|
||||||
}
|
}
|
||||||
|
|
84
vfs/vfs.go
84
vfs/vfs.go
|
@ -17,25 +17,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ncw/rclone/fs"
|
"github.com/ncw/rclone/fs"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Options set by command line flags
|
|
||||||
var (
|
|
||||||
NoModTime = false
|
|
||||||
NoChecksum = false
|
|
||||||
NoSeek = false
|
|
||||||
DirCacheTime = 5 * 60 * time.Second
|
|
||||||
PollInterval = time.Minute
|
|
||||||
// mount options
|
|
||||||
ReadOnly = false
|
|
||||||
Umask = 0
|
|
||||||
UID = ^uint32(0) // these values instruct WinFSP-FUSE to use the current user
|
|
||||||
GID = ^uint32(0) // overriden for non windows in mount_unix.go
|
|
||||||
// foreground = false
|
|
||||||
// default permissions for directories - modified by umask in New
|
|
||||||
DirPerms = os.FileMode(0777)
|
|
||||||
FilePerms = os.FileMode(0666)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Node represents either a directory (*Dir) or a file (*File)
|
// Node represents either a directory (*Dir) or a file (*File)
|
||||||
|
@ -48,6 +29,7 @@ type Node interface {
|
||||||
Remove() error
|
Remove() error
|
||||||
RemoveAll() error
|
RemoveAll() error
|
||||||
DirEntry() fs.DirEntry
|
DirEntry() fs.DirEntry
|
||||||
|
VFS() *VFS
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check interfaces
|
// Check interfaces
|
||||||
|
@ -82,42 +64,43 @@ var (
|
||||||
type VFS struct {
|
type VFS struct {
|
||||||
f fs.Fs
|
f fs.Fs
|
||||||
root *Dir
|
root *Dir
|
||||||
noSeek bool // don't allow seeking if set
|
Opt Options
|
||||||
noChecksum bool // don't check checksums if set
|
|
||||||
readOnly bool // if set VFS is read only
|
|
||||||
noModTime bool // don't read mod times for files
|
|
||||||
dirCacheTime time.Duration // how long to consider directory listing cache valid
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new VFS and root directory
|
// Options is options for creating the vfs
|
||||||
func New(f fs.Fs) *VFS {
|
type Options struct {
|
||||||
|
NoSeek bool // don't allow seeking if set
|
||||||
|
NoChecksum bool // don't check checksums if set
|
||||||
|
ReadOnly bool // if set VFS is read only
|
||||||
|
NoModTime bool // don't read mod times for files
|
||||||
|
DirCacheTime time.Duration // how long to consider directory listing cache valid
|
||||||
|
PollInterval time.Duration
|
||||||
|
Umask int
|
||||||
|
UID uint32
|
||||||
|
GID uint32
|
||||||
|
DirPerms os.FileMode
|
||||||
|
FilePerms os.FileMode
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new VFS and root directory. If opt is nil, then
|
||||||
|
// defaults will be used.
|
||||||
|
func New(f fs.Fs, opt *Options) *VFS {
|
||||||
fsDir := fs.NewDir("", time.Now())
|
fsDir := fs.NewDir("", time.Now())
|
||||||
vfs := &VFS{
|
vfs := &VFS{
|
||||||
f: f,
|
f: f,
|
||||||
|
Opt: *opt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask permissions
|
// Mask the permissions with the umask
|
||||||
DirPerms = 0777 &^ os.FileMode(Umask)
|
vfs.Opt.DirPerms &= ^os.FileMode(vfs.Opt.Umask)
|
||||||
FilePerms = 0666 &^ os.FileMode(Umask)
|
vfs.Opt.FilePerms &= ^os.FileMode(vfs.Opt.Umask)
|
||||||
|
|
||||||
if NoSeek {
|
|
||||||
vfs.noSeek = true
|
|
||||||
}
|
|
||||||
if NoChecksum {
|
|
||||||
vfs.noChecksum = true
|
|
||||||
}
|
|
||||||
if ReadOnly {
|
|
||||||
vfs.readOnly = true
|
|
||||||
}
|
|
||||||
if NoModTime {
|
|
||||||
vfs.noModTime = true
|
|
||||||
}
|
|
||||||
vfs.dirCacheTime = DirCacheTime
|
|
||||||
|
|
||||||
|
// Create root directory
|
||||||
vfs.root = newDir(vfs, f, nil, fsDir)
|
vfs.root = newDir(vfs, f, nil, fsDir)
|
||||||
|
|
||||||
if PollInterval > 0 {
|
// Start polling if required
|
||||||
vfs.PollChanges(PollInterval)
|
if vfs.Opt.PollInterval > 0 {
|
||||||
|
vfs.PollChanges(vfs.Opt.PollInterval)
|
||||||
}
|
}
|
||||||
return vfs
|
return vfs
|
||||||
}
|
}
|
||||||
|
@ -190,14 +173,3 @@ func (vfs *VFS) Statfs() error {
|
||||||
*/
|
*/
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddFlags adds the non filing system specific flags to the command
|
|
||||||
func AddFlags(flags *pflag.FlagSet) {
|
|
||||||
flags.BoolVarP(&NoModTime, "no-modtime", "", NoModTime, "Don't read/write the modification time (can speed things up).")
|
|
||||||
flags.BoolVarP(&NoChecksum, "no-checksum", "", NoChecksum, "Don't compare checksums on up/download.")
|
|
||||||
flags.BoolVarP(&NoSeek, "no-seek", "", NoSeek, "Don't allow seeking in files.")
|
|
||||||
flags.DurationVarP(&DirCacheTime, "dir-cache-time", "", DirCacheTime, "Time to cache directory entries for.")
|
|
||||||
flags.DurationVarP(&PollInterval, "poll-interval", "", PollInterval, "Time to wait between polling for changes. Must be smaller than dir-cache-time. Only on supported remotes. Set to 0 to disable.")
|
|
||||||
flags.BoolVarP(&ReadOnly, "read-only", "", ReadOnly, "Mount read-only.")
|
|
||||||
platformFlags(flags)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
// +build linux darwin freebsd
|
|
||||||
|
|
||||||
package vfs
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/pflag"
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// add any extra platform specific flags
|
|
||||||
func platformFlags(flags *pflag.FlagSet) {
|
|
||||||
flags.IntVarP(&Umask, "umask", "", Umask, "Override the permission bits set by the filesystem.")
|
|
||||||
Umask = unix.Umask(0) // read the umask
|
|
||||||
unix.Umask(Umask) // set it back to what it was
|
|
||||||
UID = uint32(unix.Geteuid())
|
|
||||||
GID = uint32(unix.Getegid())
|
|
||||||
flags.Uint32VarP(&UID, "uid", "", UID, "Override the uid field set by the filesystem.")
|
|
||||||
flags.Uint32VarP(&GID, "gid", "", GID, "Override the gid field set by the filesystem.")
|
|
||||||
}
|
|
38
vfs/vfsflags/vfsflags.go
Normal file
38
vfs/vfsflags/vfsflags.go
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// Package vfsflags implements command line flags to set up a vfs
|
||||||
|
package vfsflags
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/ncw/rclone/vfs"
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Options set by command line flags
|
||||||
|
var (
|
||||||
|
Opt = vfs.Options{
|
||||||
|
NoModTime: false,
|
||||||
|
NoChecksum: false,
|
||||||
|
NoSeek: false,
|
||||||
|
DirCacheTime: 5 * 60 * time.Second,
|
||||||
|
PollInterval: time.Minute,
|
||||||
|
ReadOnly: false,
|
||||||
|
Umask: 0,
|
||||||
|
UID: ^uint32(0), // these values instruct WinFSP-FUSE to use the current user
|
||||||
|
GID: ^uint32(0), // overriden for non windows in mount_unix.go
|
||||||
|
DirPerms: os.FileMode(0777),
|
||||||
|
FilePerms: os.FileMode(0666),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// AddFlags adds the non filing system specific flags to the command
|
||||||
|
func AddFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.BoolVarP(&Opt.NoModTime, "no-modtime", "", Opt.NoModTime, "Don't read/write the modification time (can speed things up).")
|
||||||
|
flags.BoolVarP(&Opt.NoChecksum, "no-checksum", "", Opt.NoChecksum, "Don't compare checksums on up/download.")
|
||||||
|
flags.BoolVarP(&Opt.NoSeek, "no-seek", "", Opt.NoSeek, "Don't allow seeking in files.")
|
||||||
|
flags.DurationVarP(&Opt.DirCacheTime, "dir-cache-time", "", Opt.DirCacheTime, "Time to cache directory entries for.")
|
||||||
|
flags.DurationVarP(&Opt.PollInterval, "poll-interval", "", Opt.PollInterval, "Time to wait between polling for changes. Must be smaller than dir-cache-time. Only on supported remotes. Set to 0 to disable.")
|
||||||
|
flags.BoolVarP(&Opt.ReadOnly, "read-only", "", Opt.ReadOnly, "Mount read-only.")
|
||||||
|
platformFlags(flags)
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// +build !linux,!darwin,!freebsd
|
// +build !linux,!darwin,!freebsd
|
||||||
|
|
||||||
package vfs
|
package vfsflags
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
19
vfs/vfsflags/vfsflags_unix.go
Normal file
19
vfs/vfsflags/vfsflags_unix.go
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// +build linux darwin freebsd
|
||||||
|
|
||||||
|
package vfsflags
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// add any extra platform specific flags
|
||||||
|
func platformFlags(flags *pflag.FlagSet) {
|
||||||
|
flags.IntVarP(&Opt.Umask, "umask", "", Opt.Umask, "Override the permission bits set by the filesystem.")
|
||||||
|
Opt.Umask = unix.Umask(0) // read the umask
|
||||||
|
unix.Umask(Opt.Umask) // set it back to what it was
|
||||||
|
Opt.UID = uint32(unix.Geteuid())
|
||||||
|
Opt.GID = uint32(unix.Getegid())
|
||||||
|
flags.Uint32VarP(&Opt.UID, "uid", "", Opt.UID, "Override the uid field set by the filesystem.")
|
||||||
|
flags.Uint32VarP(&Opt.GID, "gid", "", Opt.GID, "Override the gid field set by the filesystem.")
|
||||||
|
}
|
Loading…
Reference in a new issue