【问题标题】:Windows: FlushFileBuffers system call fails on network mapped driveWindows:网络映射驱动器上的 FlushFileBuffers 系统调用失败
【发布时间】:2019-11-01 20:34:25
【问题描述】:

fsync 文档状态

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

我正在尝试使用 Windows 上的 SMB 将目录同步到网络映射驱动器,类似于 fsync 在 Linux 上所做的。

如果目录存储在本地驱动器上,则以下 go 代码 sn-p 可以正常工作,但如果目录存储在网络映射文件夹上则失败。

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 上同步目录? 还是window的缓冲I/O与POSIX根本不同,当目录中的文件被修改时我们不需要刷新目录?

【问题讨论】:

  • 你实际上想用这段代码实现什么?
  • 以上代码只是示例代码。我的目的是将目录内容同步到 Windows 上的文件系统。有关实际问题,请参阅github.com/dgraph-io/badger/issues/699
  • 通常,当网络文件离线时,会在本地生成一个临时缓存文件(在 C:\Windows\CSC 中。不幸的是,非常严格的权限甚至无法让管理员查看缓存内部 - 只有 SYSTEM 有完全访问权限。)并在在线时更新到共享文件夹。您还可以通过设置共享文件夹的属性来禁用缓存。

标签: windows winapi system-calls fsync


【解决方案1】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多