Index: base/files/memory_mapped_file_posix.cc |
diff --git a/base/files/memory_mapped_file_posix.cc b/base/files/memory_mapped_file_posix.cc |
index 90ba6f49c1573f6fb4fb1f56bc33f35b36febb06..59acc4a30cea5e76f261fbe859c82914e2abb520 100644 |
--- a/base/files/memory_mapped_file_posix.cc |
+++ b/base/files/memory_mapped_file_posix.cc |
@@ -4,6 +4,9 @@ |
#include "base/files/memory_mapped_file.h" |
+#define _GNU_SOURCE 1 // Needed to get fallocate out of fcntl.h. |
+ |
+#include <fcntl.h> |
#include <stddef.h> |
#include <stdint.h> |
#include <sys/mman.h> |
@@ -71,9 +74,11 @@ bool MemoryMappedFile::MapFileRegionToMemory( |
case READ_ONLY: |
flags |= PROT_READ; |
break; |
+ |
case READ_WRITE: |
flags |= PROT_READ | PROT_WRITE; |
break; |
+ |
case READ_WRITE_EXTEND: |
// POSIX won't auto-extend the file when it is written so it must first |
// be explicitly extended to the maximum size. Zeros will fill the new |
@@ -83,10 +88,39 @@ bool MemoryMappedFile::MapFileRegionToMemory( |
DPLOG(ERROR) << "fstat " << file_.GetPlatformFile(); |
return false; |
} |
- file_.SetLength(std::max(file_len, region.offset + region.size)); |
flags |= PROT_READ | PROT_WRITE; |
+ |
+ // Increase the actual length of the file, if necessary. This can fail if |
+ // the disk is full and the OS doesn't support sparse files. |
+ if (!file_.SetLength(std::max(file_len, region.offset + region.size))) { |
Mark Mentovai
2017/05/04 21:00:47
This isn’t necessary if you’re going to call [posi
bcwhite
2017/05/05 18:06:59
Acknowledged.
|
+ DPLOG(ERROR) << "ftruncate " << file_.GetPlatformFile(); |
+ return false; |
+ } |
+ |
+// Realize the extent of the file so that it can't fail (and crash) later |
Mark Mentovai
2017/05/04 21:00:47
This is one of clang-format’s problems, these comm
bcwhite
2017/05/05 18:06:59
Done.
|
+// when trying to write to a memory page that can't be created. This can |
+// fail if the disk is full and the file is sparse. |
+#if defined(OS_MACOSX) |
+// Mac OSX doesn't support this call but the primary filesystem doesn't |
+// support sparse files so is unneeded. |
+#elif defined(OS_ANDROID) |
+ // Android doesn't support the POSIX call so use the native Linux one. |
Mark Mentovai
2017/05/04 21:00:46
Curious about this. It looks like both fallocate()
bcwhite
2017/05/05 15:48:00
Yeah, the Android builds all fail with either call
Primiano Tucci (use gerrit)
2017/05/05 16:23:33
FYI we currently ship 32 bit only chrome also on 6
bcwhite
2017/05/05 18:06:59
Acknowledged.
|
+ if (fallocate(file_.GetPlatformFile(), 0, region.offset, region.size) != |
Mark Mentovai
2017/05/04 21:00:46
Anyway, whether it’s fallocate() or posix_fallocat
bcwhite
2017/05/05 18:06:59
Done.
|
+ 0) { |
+ DPLOG(ERROR) << "fallocate " << file_.GetPlatformFile(); |
+ return false; |
+ } |
+#else |
+ if (posix_fallocate(file_.GetPlatformFile(), region.offset, |
+ region.size) != 0) { |
+ DPLOG(ERROR) << "posix_fallocate " << file_.GetPlatformFile(); |
+ return false; |
+ } |
+#endif |
+ |
break; |
} |
+ |
data_ = static_cast<uint8_t*>(mmap(NULL, map_size, flags, MAP_SHARED, |
file_.GetPlatformFile(), map_start)); |
if (data_ == MAP_FAILED) { |