pkg/fileutil: use fcntl syscall wrappers from golang.org/x/sys/unix (#12316)

Direct syscalls using syscall.Syscall(SYS_*, ...) should no longer be
used on darwin, see [1]. Instead, use the fcntl libSystem wrappers
provided by the golang.org/x/sys/unix package which implement the same
functionality.

[1] https://golang.org/doc/go1.12#darwin
This commit is contained in:
Tobias Klauser
2020-09-25 08:02:32 +02:00
committed by GitHub
parent 4136df7933
commit add86bbd1a
5 changed files with 19 additions and 17 deletions

View File

@@ -19,7 +19,8 @@ package fileutil
import (
"os"
"syscall"
"unsafe"
"golang.org/x/sys/unix"
)
func preallocExtend(f *os.File, sizeInBytes int64) error {
@@ -32,18 +33,18 @@ func preallocExtend(f *os.File, sizeInBytes int64) error {
func preallocFixed(f *os.File, sizeInBytes int64) error {
// allocate all requested space or no space at all
// TODO: allocate contiguous space on disk with F_ALLOCATECONTIG flag
fstore := &syscall.Fstore_t{
Flags: syscall.F_ALLOCATEALL,
Posmode: syscall.F_PEOFPOSMODE,
Length: sizeInBytes}
p := unsafe.Pointer(fstore)
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_PREALLOCATE), uintptr(p))
if errno == 0 || errno == syscall.ENOTSUP {
fstore := &unix.Fstore_t{
Flags: unix.F_ALLOCATEALL,
Posmode: unix.F_PEOFPOSMODE,
Length: sizeInBytes,
}
err := unix.FcntlFstore(f.Fd(), unix.F_PREALLOCATE, fstore)
if err == nil || err == unix.ENOTSUP {
return nil
}
// wrong argument to fallocate syscall
if errno == syscall.EINVAL {
if err == unix.EINVAL {
// filesystem "st_blocks" are allocated in the units of
// "Allocation Block Size" (run "diskutil info /" command)
var stat syscall.Stat_t
@@ -61,5 +62,5 @@ func preallocFixed(f *os.File, sizeInBytes int64) error {
return nil
}
}
return errno
return err
}

View File

@@ -18,7 +18,8 @@ package fileutil
import (
"os"
"syscall"
"golang.org/x/sys/unix"
)
// Fsync on HFS/OSX flushes the data on to the physical drive but the drive
@@ -26,11 +27,8 @@ import (
// written in out-of-order sequence. Using F_FULLFSYNC ensures that the
// physical drive's buffer will also get flushed to the media.
func Fsync(f *os.File) error {
_, _, errno := syscall.Syscall(syscall.SYS_FCNTL, f.Fd(), uintptr(syscall.F_FULLFSYNC), uintptr(0))
if errno == 0 {
return nil
}
return errno
_, err := unix.FcntlInt(f.Fd(), unix.F_FULLFSYNC, 0)
return err
}
// Fdatasync on darwin platform invokes fcntl(F_FULLFSYNC) for actual persistence