Windows:网络映射的驱动器上的FlushFileBuffers系统调用失败

时间:2019-06-19 07:11:00

标签: windows winapi system-calls fsync

fsync文档状态

  

调用fsync()不一定确保包含文件的目录中的条目也已到达磁盘。为此,目录的文件描述符上的显式fsync()是          也需要。

我正在尝试在Windows上使用SMB将目录同步到网络映射的驱动器,类似于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

Untitled

所以问题是如何在Windows上同步目录? 还是窗口的缓冲I / O与POSIX本质上是不同的,并且当其中的文件被修改时我们不需要刷新目录吗?

1 个答案:

答案 0 :(得分:0)