title: Windows: FlushFileBuffers system call fails on network mapped drive
body: <p><code>fsync</code> doc states</p>
  
  <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>I'm trying to sync a directory to the network mapped drive using SMB on windows, similar to what <code>fsync</code> does on Linux.</p>
  
  <p>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.</p>
  
  <pre class="lang-golang prettyprint-override"><code>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)
  }
  </code></pre>
  
  <p>The program fails with</p>
  
  <pre><code>Z:\\smb-test Incorrect function.
  </code></pre>
  
  <p>MSDN states that the handle passed in should either be a handle to a file, or to a volume, but says nothing about directories.
  <a href="https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-flushfilebuffers</a></p>
  
  <p>And FlushFileBuffers is not listed as a function that accepts directory handles
  <a href="https://docs.microsoft.com/en-us/windows/desktop/fileio/obtaining-a-handle-to-a-directory" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/windows/desktop/fileio/obtaining-a-handle-to-a-directory</a></p>
  
  <p>I also noticed the flushfilebuffers system call fails with <code>Invalid Device Request</code> for a network mapped drive</p>
  
  <p><img src="https://user-images.githubusercontent.com/12949454/59709749-15480f00-9225-11e9-8f01-f834046044de.png" alt="Untitled"></p>
  
  <p>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?</p>