341d880027
Before this change rclone marked files opened for write without VFS cache with the non seekable flag. This caused problems with rclone mount layerd with mergerfs. This change removes the hint and lets rclone do all the checking for seekability.
122 lines
3.3 KiB
Go
122 lines
3.3 KiB
Go
// +build linux darwin freebsd
|
|
|
|
package mount
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"bazil.org/fuse"
|
|
fusefs "bazil.org/fuse/fs"
|
|
"github.com/rclone/rclone/cmd/mountlib"
|
|
"github.com/rclone/rclone/fs/log"
|
|
"github.com/rclone/rclone/vfs"
|
|
)
|
|
|
|
// File represents a file
|
|
type File struct {
|
|
*vfs.File
|
|
}
|
|
|
|
// Check interface satisfied
|
|
var _ fusefs.Node = (*File)(nil)
|
|
|
|
// Attr fills out the attributes for the file
|
|
func (f *File) Attr(ctx context.Context, a *fuse.Attr) (err error) {
|
|
defer log.Trace(f, "")("a=%+v, err=%v", a, &err)
|
|
a.Valid = mountlib.AttrTimeout
|
|
modTime := f.File.ModTime()
|
|
Size := uint64(f.File.Size())
|
|
Blocks := (Size + 511) / 512
|
|
a.Gid = f.VFS().Opt.GID
|
|
a.Uid = f.VFS().Opt.UID
|
|
a.Mode = f.VFS().Opt.FilePerms
|
|
a.Size = Size
|
|
a.Atime = modTime
|
|
a.Mtime = modTime
|
|
a.Ctime = modTime
|
|
a.Crtime = modTime
|
|
a.Blocks = Blocks
|
|
return nil
|
|
}
|
|
|
|
// Check interface satisfied
|
|
var _ fusefs.NodeSetattrer = (*File)(nil)
|
|
|
|
// Setattr handles attribute changes from FUSE. Currently supports ModTime and Size only
|
|
func (f *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
|
|
defer log.Trace(f, "a=%+v", req)("err=%v", &err)
|
|
if !f.VFS().Opt.NoModTime {
|
|
if req.Valid.Mtime() {
|
|
err = f.File.SetModTime(req.Mtime)
|
|
} else if req.Valid.MtimeNow() {
|
|
err = f.File.SetModTime(time.Now())
|
|
}
|
|
}
|
|
if req.Valid.Size() {
|
|
err = f.File.Truncate(int64(req.Size))
|
|
}
|
|
return translateError(err)
|
|
}
|
|
|
|
// Check interface satisfied
|
|
var _ fusefs.NodeOpener = (*File)(nil)
|
|
|
|
// Open the file for read or write
|
|
func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fh fusefs.Handle, err error) {
|
|
defer log.Trace(f, "flags=%v", req.Flags)("fh=%v, err=%v", &fh, &err)
|
|
|
|
// fuse flags are based off syscall flags as are os flags, so
|
|
// should be compatible
|
|
handle, err := f.File.Open(int(req.Flags))
|
|
if err != nil {
|
|
return nil, translateError(err)
|
|
}
|
|
|
|
return &FileHandle{handle}, nil
|
|
}
|
|
|
|
// Check interface satisfied
|
|
var _ fusefs.NodeFsyncer = (*File)(nil)
|
|
|
|
// Fsync the file
|
|
//
|
|
// Note that we don't do anything except return OK
|
|
func (f *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) (err error) {
|
|
defer log.Trace(f, "")("err=%v", &err)
|
|
return nil
|
|
}
|
|
|
|
// Getxattr gets an extended attribute by the given name from the
|
|
// node.
|
|
//
|
|
// If there is no xattr by that name, returns fuse.ErrNoXattr.
|
|
func (f *File) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
|
|
return fuse.ENOSYS // we never implement this
|
|
}
|
|
|
|
var _ fusefs.NodeGetxattrer = (*File)(nil)
|
|
|
|
// Listxattr lists the extended attributes recorded for the node.
|
|
func (f *File) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
|
|
return fuse.ENOSYS // we never implement this
|
|
}
|
|
|
|
var _ fusefs.NodeListxattrer = (*File)(nil)
|
|
|
|
// Setxattr sets an extended attribute with the given name and
|
|
// value for the node.
|
|
func (f *File) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
|
|
return fuse.ENOSYS // we never implement this
|
|
}
|
|
|
|
var _ fusefs.NodeSetxattrer = (*File)(nil)
|
|
|
|
// Removexattr removes an extended attribute for the name.
|
|
//
|
|
// If there is no xattr by that name, returns fuse.ErrNoXattr.
|
|
func (f *File) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
|
|
return fuse.ENOSYS // we never implement this
|
|
}
|
|
|
|
var _ fusefs.NodeRemovexattrer = (*File)(nil)
|