[PATCH] D42925: Call FlushFileBuffers on readwrite file mappings.

Zachary Turner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 5 11:38:59 PST 2018


zturner created this revision.
zturner added reviewers: compnerd, rnk, Bigcheese.
Herald added a subscriber: hiraditya.

Due to a Windows kernel bug, calling FlushFileBuffers is necessary to ensure that subsequent processes can correctly read the data we write.  More information is available in this connect issue <https://developercommunity.visualstudio.com/content/problem/191590/linker-needs-workaround-for-windows-kernel-bug.html>.  The Windows Kernel team is also aware and from my understanding they are investigating.  Until we have more clear guidance about what versions of Windows this affects, I'm adding this call to `FlushFileBuffers` for all readwrite mappings on all versions of Windows.


https://reviews.llvm.org/D42925

Files:
  llvm/include/llvm/Support/FileSystem.h
  llvm/lib/Support/Windows/Path.inc


Index: llvm/lib/Support/Windows/Path.inc
===================================================================
--- llvm/lib/Support/Windows/Path.inc
+++ llvm/lib/Support/Windows/Path.inc
@@ -822,6 +822,8 @@
 
 std::error_code mapped_file_region::init(int FD, uint64_t Offset,
                                          mapmode Mode) {
+  this->FD = FD;
+  this->Mode = Mode;
   HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
   if (FileHandle == INVALID_HANDLE_VALUE)
     return make_error_code(errc::bad_file_descriptor);
@@ -887,8 +889,20 @@
 }
 
 mapped_file_region::~mapped_file_region() {
-  if (Mapping)
+  if (Mapping) {
     ::UnmapViewOfFile(Mapping);
+
+    if (Mode == mapmode::readwrite) {
+      // There is a Windows kernel bug, the exact trigger conditions of which
+      // are not well understood.  When triggered, dirty pages are not properly
+      // flushed and subsequent process's attempts to read a file can return
+      // invalid data.  Calling FlushFileBuffers on the write handle is
+      // sufficient to ensure that this bug is not triggered.
+      HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+      if (FileHandle != INVALID_HANDLE_VALUE)
+        ::FlushFileBuffers(FileHandle);
+    }
+  }
 }
 
 size_t mapped_file_region::size() const {
Index: llvm/include/llvm/Support/FileSystem.h
===================================================================
--- llvm/include/llvm/Support/FileSystem.h
+++ llvm/include/llvm/Support/FileSystem.h
@@ -819,6 +819,8 @@
   /// Platform-specific mapping state.
   size_t Size;
   void *Mapping;
+  int FD;
+  mapmode Mode;
 
   std::error_code init(int FD, uint64_t Offset, mapmode Mode);
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D42925.132872.patch
Type: text/x-patch
Size: 1704 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180205/a51ebce5/attachment.bin>


More information about the llvm-commits mailing list