fsync
Состояния документа
Вызов fsync () не обязательно гарантирует, что запись в каталоге, содержащем файл, также достигла диска. Для этого явный fsync () в дескрипторе файла для каталога
также необходимо.
Я пытаюсь синхронизировать каталог с подключенным сетевым диском с помощью SMB в Windows, аналогично тому, что fsync
делает в Linux.
Следующий фрагмент кода go, который отлично работает, если каталог хранится на локальном диске, но не работает, если он находится в сетевой папке.
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)
}
Программа завершается с
Z:\\smb-test Incorrect function.
MSDN утверждает, что переданный дескриптор должен быть либо дескриптором файла, либо тома, но ничего не говорит о каталогах.
https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers
И FlushFileBuffers не указан как функция, которая принимает дескрипторы каталога
https://docs.microsoft.com/en-us/windows/desktop/fileio/obtaining-a-handle-to-a-directory
Я также заметил, что системный вызов flushfilebuffers завершается неудачно с Invalid Device Request
для сетевого подключенного диска
Итак, вопрос в том, как синхронизировать каталог в Windows?
Или буферизованный ввод / вывод окна принципиально отличается от POSIX, и нам не нужно очищать каталог, когда файл внутри него модифицируется?