1// +build darwin 2 3// Copyright 2019 the Go-FUSE Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7package fs 8 9import ( 10 "context" 11 "syscall" 12 "time" 13 "unsafe" 14 15 "github.com/hanwen/go-fuse/v2/fuse" 16 "github.com/hanwen/go-fuse/v2/internal/utimens" 17) 18 19func (n *LoopbackNode) Getxattr(ctx context.Context, attr string, dest []byte) (uint32, syscall.Errno) { 20 return 0, syscall.ENOSYS 21} 22 23func (n *LoopbackNode) Setxattr(ctx context.Context, attr string, data []byte, flags uint32) syscall.Errno { 24 return syscall.ENOSYS 25} 26 27func (n *LoopbackNode) Removexattr(ctx context.Context, attr string) syscall.Errno { 28 return syscall.ENOSYS 29} 30 31func (n *LoopbackNode) Listxattr(ctx context.Context, dest []byte) (uint32, syscall.Errno) { 32 return 0, syscall.ENOSYS 33} 34 35func (n *LoopbackNode) renameExchange(name string, newparent InodeEmbedder, newName string) syscall.Errno { 36 return syscall.ENOSYS 37} 38 39func (f *loopbackFile) Allocate(ctx context.Context, off uint64, sz uint64, mode uint32) syscall.Errno { 40 // TODO: Handle `mode` parameter. 41 42 // From `man fcntl` on OSX: 43 // The F_PREALLOCATE command operates on the following structure: 44 // 45 // typedef struct fstore { 46 // u_int32_t fst_flags; /* IN: flags word */ 47 // int fst_posmode; /* IN: indicates offset field */ 48 // off_t fst_offset; /* IN: start of the region */ 49 // off_t fst_length; /* IN: size of the region */ 50 // off_t fst_bytesalloc; /* OUT: number of bytes allocated */ 51 // } fstore_t; 52 // 53 // The flags (fst_flags) for the F_PREALLOCATE command are as follows: 54 // 55 // F_ALLOCATECONTIG Allocate contiguous space. 56 // 57 // F_ALLOCATEALL Allocate all requested space or no space at all. 58 // 59 // The position modes (fst_posmode) for the F_PREALLOCATE command indicate how to use the offset field. The modes are as fol- 60 // lows: 61 // 62 // F_PEOFPOSMODE Allocate from the physical end of file. 63 // 64 // F_VOLPOSMODE Allocate from the volume offset. 65 66 k := struct { 67 Flags uint32 // u_int32_t 68 Posmode int64 // int 69 Offset int64 // off_t 70 Length int64 // off_t 71 Bytesalloc int64 // off_t 72 }{ 73 0, 74 0, 75 int64(off), 76 int64(sz), 77 0, 78 } 79 80 // Linux version for reference: 81 // err := syscall.Fallocate(int(f.File.Fd()), mode, int64(off), int64(sz)) 82 _, _, errno := syscall.Syscall(syscall.SYS_FCNTL, uintptr(f.fd), uintptr(syscall.F_PREALLOCATE), uintptr(unsafe.Pointer(&k))) 83 84 return errno 85} 86 87// timeToTimeval - Convert time.Time to syscall.Timeval 88// 89// Note: This does not use syscall.NsecToTimespec because 90// that does not work properly for times before 1970, 91// see https://github.com/golang/go/issues/12777 92func timeToTimeval(t *time.Time) syscall.Timeval { 93 var tv syscall.Timeval 94 tv.Usec = int32(t.Nanosecond() / 1000) 95 tv.Sec = t.Unix() 96 return tv 97} 98 99// MacOS before High Sierra lacks utimensat() and UTIME_OMIT. 100// We emulate using utimes() and extra Getattr() calls. 101func (f *loopbackFile) utimens(a *time.Time, m *time.Time) syscall.Errno { 102 var attr fuse.AttrOut 103 if a == nil || m == nil { 104 errno := f.Getattr(context.Background(), &attr) 105 if errno != 0 { 106 return errno 107 } 108 } 109 tv := utimens.Fill(a, m, &attr.Attr) 110 err := syscall.Futimes(int(f.fd), tv) 111 return ToErrno(err) 112} 113 114func (n *LoopbackNode) CopyFileRange(ctx context.Context, fhIn FileHandle, 115 offIn uint64, out *Inode, fhOut FileHandle, offOut uint64, 116 len uint64, flags uint64) (uint32, syscall.Errno) { 117 return 0, syscall.ENOSYS 118} 119