fsync
doc states
Calling fsync() does not necessarily ensure that the entry in the directory containing the file has also reached disk. For that an explicit fsync() on a file descriptor for the directory is also needed.
I'm trying to sync a directory to the network mapped drive using SMB on windows, similar to what fsync
does on Linux.
The following go code snippet which works fine if the directory is stored on a local drive but fails if it is on a network mapped folder.
func main() {
dir := "Z:\\smb-test" // Path to network mapped drive
f, err := openDir(dir)
if err != nil {
log.Fatal(err)
}
// Works fine if the path is located on a local disk but
// fails if the directory is on a network mapped drive
if err := f.Sync(); err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
func openDir(path string) (*os.File, error) {
fd, err := openDirWin(path)
if err != nil {
return nil, err
}
return os.NewFile(uintptr(fd), path), nil
}
func openDirWin(path string) (fd syscall.Handle, err error) {
pathp, err := syscall.UTF16PtrFromString(path)
if err != nil {
return syscall.InvalidHandle, err
}
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE)
sharemode := uint32(syscall.FILE_SHARE_READ | syscall.FILE_SHARE_WRITE)
createmode := uint32(syscall.OPEN_EXISTING)
fl := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
return syscall.CreateFile(pathp, access, sharemode, nil, createmode, fl, 0)
}
The program fails with
Z:\\smb-test Incorrect function.
MSDN states that the handle passed in should either be a handle to a file, or to a volume, but says nothing about directories. https://learn.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers
And FlushFileBuffers is not listed as a function that accepts directory handles https://learn.microsoft.com/en-us/windows/desktop/fileio/obtaining-a-handle-to-a-directory
I also noticed the flushfilebuffers system call fails with Invalid Device Request
for a network mapped drive
So the question is how do I sync a directory on windows? Or is window's buffered I/O fundamentally different from POSIX and we don't need to flush a directory when a file inside it is modified?