1// Copyright 2018 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package poll
6
7import (
8	"errors"
9	"internal/syscall/unix"
10	"syscall"
11)
12
13// Fsync invokes SYS_FCNTL with SYS_FULLFSYNC because
14// on OS X, SYS_FSYNC doesn't fully flush contents to disk.
15// See Issue #26650 as well as the man page for fsync on OS X.
16func (fd *FD) Fsync() error {
17	if err := fd.incref(); err != nil {
18		return err
19	}
20	defer fd.decref()
21	return ignoringEINTR(func() error {
22		_, err := unix.Fcntl(fd.Sysfd, syscall.F_FULLFSYNC, 0)
23
24		// There are scenarios such as SMB mounts where fcntl will fail
25		// with ENOTSUP. In those cases fallback to fsync.
26		// See #64215
27		if err != nil && errors.Is(err, syscall.ENOTSUP) {
28			err = syscall.Fsync(fd.Sysfd)
29		}
30		return err
31	})
32}
33