mirror of
https://github.com/golang/go
synced 2024-11-23 14:30:02 -07:00
internal/poll: use F_FULLFSYNC fcntl for FD.Fsync on OS X
As reported in #26650 and also cautioned on the man page for fsync on OS X, fsync doesn't properly flush content to permanent storage, and might cause corruption of data if the OS crashes or if the drive loses power. Thus it is recommended to use the F_FULLFSYNC fcntl, which flushes all buffered data to permanent storage and is important for applications such as databases that require a strict ordering of writes. Also added a note in syscall_darwin.go that syscall.Fsync is not invoked for os.File.Sync. Fixes #26650. Change-Id: Idecd9adbbdd640b9c5b02e73b60ed254c98b48b6 Reviewed-on: https://go-review.googlesource.com/130676 Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
ccb70bd19c
commit
be10ad7622
23
src/internal/poll/fd_fsync_darwin.go
Normal file
23
src/internal/poll/fd_fsync_darwin.go
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright 2018 The Go 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 poll
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
|
||||
// on OS X, SYS_FSYNC doesn't fully flush contents to disk.
|
||||
// See Issue #26650 as well as the man page for fsync on OS X.
|
||||
func (fd *FD) Fsync() error {
|
||||
if err := fd.incref(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.decref()
|
||||
|
||||
_, _, e1 := syscall.Syscall(syscall.SYS_FCNTL, uintptr(fd.Sysfd), syscall.F_FULLFSYNC, 0)
|
||||
if e1 != 0 {
|
||||
return e1
|
||||
}
|
||||
return nil
|
||||
}
|
18
src/internal/poll/fd_fsync_posix.go
Normal file
18
src/internal/poll/fd_fsync_posix.go
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd js,wasm linux nacl netbsd openbsd solaris windows
|
||||
|
||||
package poll
|
||||
|
||||
import "syscall"
|
||||
|
||||
// Fsync wraps syscall.Fsync.
|
||||
func (fd *FD) Fsync() error {
|
||||
if err := fd.incref(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.decref()
|
||||
return syscall.Fsync(fd.Sysfd)
|
||||
}
|
@ -46,12 +46,3 @@ func (fd *FD) Ftruncate(size int64) error {
|
||||
defer fd.decref()
|
||||
return syscall.Ftruncate(fd.Sysfd, size)
|
||||
}
|
||||
|
||||
// Fsync wraps syscall.Fsync.
|
||||
func (fd *FD) Fsync() error {
|
||||
if err := fd.incref(); err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.decref()
|
||||
return syscall.Fsync(fd.Sysfd)
|
||||
}
|
||||
|
@ -252,6 +252,7 @@ func Kill(pid int, signum Signal) (err error) { return kill(pid, int(signum), 1)
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
//sys Fsync(fd int) (err error)
|
||||
// Fsync is not called for os.File.Sync(). Please see internal/poll/fd_fsync_darwin.go
|
||||
//sys Ftruncate(fd int, length int64) (err error)
|
||||
//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||
//sys Getdtablesize() (size int)
|
||||
|
Loading…
Reference in New Issue
Block a user