github.com/10XDev/rclone@v1.52.3-0.20200626220027-16af9ab76b2a/cmd/mount/file.go (about)

     1  // +build linux,go1.13 darwin,go1.13 freebsd,go1.13
     2  
     3  package mount
     4  
     5  import (
     6  	"context"
     7  	"time"
     8  
     9  	"bazil.org/fuse"
    10  	fusefs "bazil.org/fuse/fs"
    11  	"github.com/rclone/rclone/cmd/mountlib"
    12  	"github.com/rclone/rclone/fs/log"
    13  	"github.com/rclone/rclone/vfs"
    14  )
    15  
    16  // File represents a file
    17  type File struct {
    18  	*vfs.File
    19  }
    20  
    21  // Check interface satisfied
    22  var _ fusefs.Node = (*File)(nil)
    23  
    24  // Attr fills out the attributes for the file
    25  func (f *File) Attr(ctx context.Context, a *fuse.Attr) (err error) {
    26  	defer log.Trace(f, "")("a=%+v, err=%v", a, &err)
    27  	a.Valid = mountlib.AttrTimeout
    28  	modTime := f.File.ModTime()
    29  	Size := uint64(f.File.Size())
    30  	Blocks := (Size + 511) / 512
    31  	a.Gid = f.VFS().Opt.GID
    32  	a.Uid = f.VFS().Opt.UID
    33  	a.Mode = f.VFS().Opt.FilePerms
    34  	a.Size = Size
    35  	a.Atime = modTime
    36  	a.Mtime = modTime
    37  	a.Ctime = modTime
    38  	a.Crtime = modTime
    39  	a.Blocks = Blocks
    40  	return nil
    41  }
    42  
    43  // Check interface satisfied
    44  var _ fusefs.NodeSetattrer = (*File)(nil)
    45  
    46  // Setattr handles attribute changes from FUSE. Currently supports ModTime and Size only
    47  func (f *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *fuse.SetattrResponse) (err error) {
    48  	defer log.Trace(f, "a=%+v", req)("err=%v", &err)
    49  	if !f.VFS().Opt.NoModTime {
    50  		if req.Valid.Mtime() {
    51  			err = f.File.SetModTime(req.Mtime)
    52  		} else if req.Valid.MtimeNow() {
    53  			err = f.File.SetModTime(time.Now())
    54  		}
    55  	}
    56  	if req.Valid.Size() {
    57  		err = f.File.Truncate(int64(req.Size))
    58  	}
    59  	return translateError(err)
    60  }
    61  
    62  // Check interface satisfied
    63  var _ fusefs.NodeOpener = (*File)(nil)
    64  
    65  // Open the file for read or write
    66  func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenResponse) (fh fusefs.Handle, err error) {
    67  	defer log.Trace(f, "flags=%v", req.Flags)("fh=%v, err=%v", &fh, &err)
    68  
    69  	// fuse flags are based off syscall flags as are os flags, so
    70  	// should be compatible
    71  	handle, err := f.File.Open(int(req.Flags))
    72  	if err != nil {
    73  		return nil, translateError(err)
    74  	}
    75  
    76  	// If size unknown then use direct io to read
    77  	if entry := handle.Node().DirEntry(); entry != nil && entry.Size() < 0 {
    78  		resp.Flags |= fuse.OpenDirectIO
    79  	}
    80  
    81  	return &FileHandle{handle}, nil
    82  }
    83  
    84  // Check interface satisfied
    85  var _ fusefs.NodeFsyncer = (*File)(nil)
    86  
    87  // Fsync the file
    88  //
    89  // Note that we don't do anything except return OK
    90  func (f *File) Fsync(ctx context.Context, req *fuse.FsyncRequest) (err error) {
    91  	defer log.Trace(f, "")("err=%v", &err)
    92  	return nil
    93  }
    94  
    95  // Getxattr gets an extended attribute by the given name from the
    96  // node.
    97  //
    98  // If there is no xattr by that name, returns fuse.ErrNoXattr.
    99  func (f *File) Getxattr(ctx context.Context, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
   100  	return fuse.ENOSYS // we never implement this
   101  }
   102  
   103  var _ fusefs.NodeGetxattrer = (*File)(nil)
   104  
   105  // Listxattr lists the extended attributes recorded for the node.
   106  func (f *File) Listxattr(ctx context.Context, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
   107  	return fuse.ENOSYS // we never implement this
   108  }
   109  
   110  var _ fusefs.NodeListxattrer = (*File)(nil)
   111  
   112  // Setxattr sets an extended attribute with the given name and
   113  // value for the node.
   114  func (f *File) Setxattr(ctx context.Context, req *fuse.SetxattrRequest) error {
   115  	return fuse.ENOSYS // we never implement this
   116  }
   117  
   118  var _ fusefs.NodeSetxattrer = (*File)(nil)
   119  
   120  // Removexattr removes an extended attribute for the name.
   121  //
   122  // If there is no xattr by that name, returns fuse.ErrNoXattr.
   123  func (f *File) Removexattr(ctx context.Context, req *fuse.RemovexattrRequest) error {
   124  	return fuse.ENOSYS // we never implement this
   125  }
   126  
   127  var _ fusefs.NodeRemovexattrer = (*File)(nil)