mirror of
https://github.com/rclone/rclone.git
synced 2024-12-01 21:04:56 +01:00
119 lines
3.6 KiB
Go
119 lines
3.6 KiB
Go
|
// +build darwin
|
||
|
|
||
|
// Copyright 2019 the Go-FUSE Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package fs
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"syscall"
|
||
|
"time"
|
||
|
"unsafe"
|
||
|
|
||
|
"github.com/hanwen/go-fuse/v2/fuse"
|
||
|
"github.com/hanwen/go-fuse/v2/internal/utimens"
|
||
|
)
|
||
|
|
||
|
func (n *loopbackNode) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) {
|
||
|
return 0, syscall.ENOSYS
|
||
|
}
|
||
|
|
||
|
func (n *loopbackNode) Setxattr(ctx context.Context, attr string, data []byte, flags uint32) syscall.Errno {
|
||
|
return syscall.ENOSYS
|
||
|
}
|
||
|
|
||
|
func (n *loopbackNode) Removexattr(ctx context.Context, attr string) syscall.Errno {
|
||
|
return syscall.ENOSYS
|
||
|
}
|
||
|
|
||
|
func (n *loopbackNode) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errno) {
|
||
|
return 0, syscall.ENOSYS
|
||
|
}
|
||
|
|
||
|
func (n *loopbackNode) renameExchange(name string, newparent *loopbackNode, newName string) syscall.Errno {
|
||
|
return syscall.ENOSYS
|
||
|
}
|
||
|
|
||
|
func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno {
|
||
|
// TODO: Handle `mode` parameter.
|
||
|
|
||
|
// From `man fcntl` on OSX:
|
||
|
// The F_PREALLOCATE command operates on the following structure:
|
||
|
//
|
||
|
// typedef struct fstore {
|
||
|
// u_int32_t fst_flags; /* IN: flags word */
|
||
|
// int fst_posmode; /* IN: indicates offset field */
|
||
|
// off_t fst_offset; /* IN: start of the region */
|
||
|
// off_t fst_length; /* IN: size of the region */
|
||
|
// off_t fst_bytesalloc; /* OUT: number of bytes allocated */
|
||
|
// } fstore_t;
|
||
|
//
|
||
|
// The flags (fst_flags) for the F_PREALLOCATE command are as follows:
|
||
|
//
|
||
|
// F_ALLOCATECONTIG Allocate contiguous space.
|
||
|
//
|
||
|
// F_ALLOCATEALL Allocate all requested space or no space at all.
|
||
|
//
|
||
|
// The position modes (fst_posmode) for the F_PREALLOCATE command indicate how to use the offset field. The modes are as fol-
|
||
|
// lows:
|
||
|
//
|
||
|
// F_PEOFPOSMODE Allocate from the physical end of file.
|
||
|
//
|
||
|
// F_VOLPOSMODE Allocate from the volume offset.
|
||
|
|
||
|
k := struct {
|
||
|
Flags uint32 // u_int32_t
|
||
|
Posmode int64 // int
|
||
|
Offset int64 // off_t
|
||
|
Length int64 // off_t
|
||
|
Bytesalloc int64 // off_t
|
||
|
}{
|
||
|
0,
|
||
|
0,
|
||
|
int64(off),
|
||
|
int64(sz),
|
||
|
0,
|
||
|
}
|
||
|
|
||
|
// Linux version for reference:
|
||
|
// err := syscall.Fallocate(int(f.File.Fd()), mode, int64(off), int64(sz))
|
||
|
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.fd), uintptr(syscall.F_PREALLOCATE), uintptr(unsafe.Pointer(&k)))
|
||
|
|
||
|
return errno
|
||
|
}
|
||
|
|
||
|
// timeToTimeval - Convert time.Time to syscall.Timeval
|
||
|
//
|
||
|
// Note: This does not use syscall.NsecToTimespec because
|
||
|
// that does not work properly for times before 1970,
|
||
|
// see https://github.com/golang/go/issues/12777
|
||
|
func timeToTimeval(t *time.Time) syscall.Timeval {
|
||
|
var tv syscall.Timeval
|
||
|
tv.Usec = int32(t.Nanosecond() / 1000)
|
||
|
tv.Sec = t.Unix()
|
||
|
return tv
|
||
|
}
|
||
|
|
||
|
// MacOS before High Sierra lacks utimensat() and UTIME_OMIT.
|
||
|
// We emulate using utimes() and extra Getattr() calls.
|
||
|
func (f *loopbackFile) utimens(a *time.Time, m *time.Time) syscall.Errno {
|
||
|
var attr fuse.AttrOut
|
||
|
if a == nil || m == nil {
|
||
|
errno := f.Getattr(context.Background(), &attr)
|
||
|
if errno != 0 {
|
||
|
return errno
|
||
|
}
|
||
|
}
|
||
|
tv := utimens.Fill(a, m, &attr.Attr)
|
||
|
err := syscall.Futimes(int(f.fd), tv)
|
||
|
return ToErrno(err)
|
||
|
}
|
||
|
|
||
|
func (n *loopbackNode) CopyFileRange(ctx context.Context, fhIn FileHandle,
|
||
|
offIn uint64, out *Inode, fhOut FileHandle, offOut uint64,
|
||
|
len uint64, flags uint64) (uint32, syscall.Errno) {
|
||
|
return 0, syscall.ENOSYS
|
||
|
}
|