github.com/ncw/rclone@v1.48.1-0.20190724201158-a35aa1360e3e/cmd/mount/file.go (about)

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