]> granicus.if.org Git - llvm/commitdiff
FileOutputBuffer: handle mmap(2) failure
authorRui Ueyama <ruiu@google.com>
Tue, 22 Jan 2019 21:49:56 +0000 (21:49 +0000)
committerRui Ueyama <ruiu@google.com>
Tue, 22 Jan 2019 21:49:56 +0000 (21:49 +0000)
If the underlying filesystem does not support mmap system call,
FileOutputBuffer may fail when it attempts to mmap an output temporary
file. This patch handles such situation.

Unfortunately, it looks like it is very hard to test this functionality
without a filesystem that doesn't support mmap using llvm-lit. I tested
this locally by passing an invalid parameter to mmap so that it fails and
falls back to the in-memory buffer. Maybe that's all what we can do.
I believe it is reasonable to submit this without a test.

Differential Revision: https://reviews.llvm.org/D56949

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351883 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Support/FileOutputBuffer.cpp

index cf21cc19c0122a86a73c3d1b8e0fd9acccdb5e3f..b0b817b4bdd03bf9b753654f6eda5f4f1cd29163 100644 (file)
@@ -120,7 +120,7 @@ createInMemoryBuffer(StringRef Path, size_t Size, unsigned Mode) {
   return llvm::make_unique<InMemoryBuffer>(Path, MB, Mode);
 }
 
-static Expected<std::unique_ptr<OnDiskBuffer>>
+static Expected<std::unique_ptr<FileOutputBuffer>>
 createOnDiskBuffer(StringRef Path, size_t Size, unsigned Mode) {
   Expected<fs::TempFile> FileOrErr =
       fs::TempFile::create(Path + ".tmp%%%%%%%", Mode);
@@ -144,10 +144,14 @@ createOnDiskBuffer(StringRef Path, size_t Size, unsigned Mode) {
   std::error_code EC;
   auto MappedFile = llvm::make_unique<fs::mapped_file_region>(
       File.FD, fs::mapped_file_region::readwrite, Size, 0, EC);
+
+  // mmap(2) can fail if the underlying filesystem does not support it.
+  // If that happens, we fall back to in-memory buffer as the last resort.
   if (EC) {
     consumeError(File.discard());
-    return errorCodeToError(EC);
+    return createInMemoryBuffer(Path, Size, Mode);
   }
+
   return llvm::make_unique<OnDiskBuffer>(Path, std::move(File),
                                          std::move(MappedFile));
 }