OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/files/memory_mapped_file.h" | 5 #include "base/files/memory_mapped_file.h" |
6 | 6 |
7 #define _GNU_SOURCE 1 // Needed to get fallocate out of fcntl.h. | |
8 | |
9 #include <fcntl.h> | |
7 #include <stddef.h> | 10 #include <stddef.h> |
8 #include <stdint.h> | 11 #include <stdint.h> |
9 #include <sys/mman.h> | 12 #include <sys/mman.h> |
10 #include <sys/stat.h> | 13 #include <sys/stat.h> |
11 #include <unistd.h> | 14 #include <unistd.h> |
12 | 15 |
13 #include "base/logging.h" | 16 #include "base/logging.h" |
14 #include "base/threading/thread_restrictions.h" | 17 #include "base/threading/thread_restrictions.h" |
15 #include "build/build_config.h" | 18 #include "build/build_config.h" |
16 | 19 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
64 map_start = static_cast<off_t>(aligned_start); | 67 map_start = static_cast<off_t>(aligned_start); |
65 map_size = static_cast<size_t>(aligned_size); | 68 map_size = static_cast<size_t>(aligned_size); |
66 length_ = static_cast<size_t>(region.size); | 69 length_ = static_cast<size_t>(region.size); |
67 } | 70 } |
68 | 71 |
69 int flags = 0; | 72 int flags = 0; |
70 switch (access) { | 73 switch (access) { |
71 case READ_ONLY: | 74 case READ_ONLY: |
72 flags |= PROT_READ; | 75 flags |= PROT_READ; |
73 break; | 76 break; |
77 | |
74 case READ_WRITE: | 78 case READ_WRITE: |
75 flags |= PROT_READ | PROT_WRITE; | 79 flags |= PROT_READ | PROT_WRITE; |
76 break; | 80 break; |
81 | |
77 case READ_WRITE_EXTEND: | 82 case READ_WRITE_EXTEND: |
78 // POSIX won't auto-extend the file when it is written so it must first | 83 // POSIX won't auto-extend the file when it is written so it must first |
79 // be explicitly extended to the maximum size. Zeros will fill the new | 84 // be explicitly extended to the maximum size. Zeros will fill the new |
80 // space. | 85 // space. |
81 auto file_len = file_.GetLength(); | 86 auto file_len = file_.GetLength(); |
82 if (file_len < 0) { | 87 if (file_len < 0) { |
83 DPLOG(ERROR) << "fstat " << file_.GetPlatformFile(); | 88 DPLOG(ERROR) << "fstat " << file_.GetPlatformFile(); |
84 return false; | 89 return false; |
85 } | 90 } |
86 file_.SetLength(std::max(file_len, region.offset + region.size)); | |
87 flags |= PROT_READ | PROT_WRITE; | 91 flags |= PROT_READ | PROT_WRITE; |
92 | |
93 // Increase the actual length of the file, if necessary. This can fail if | |
94 // the disk is full and the OS doesn't support sparse files. | |
95 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.
| |
96 DPLOG(ERROR) << "ftruncate " << file_.GetPlatformFile(); | |
97 return false; | |
98 } | |
99 | |
100 // 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.
| |
101 // when trying to write to a memory page that can't be created. This can | |
102 // fail if the disk is full and the file is sparse. | |
103 #if defined(OS_MACOSX) | |
104 // Mac OSX doesn't support this call but the primary filesystem doesn't | |
105 // support sparse files so is unneeded. | |
106 #elif defined(OS_ANDROID) | |
107 // 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.
| |
108 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.
| |
109 0) { | |
110 DPLOG(ERROR) << "fallocate " << file_.GetPlatformFile(); | |
111 return false; | |
112 } | |
113 #else | |
114 if (posix_fallocate(file_.GetPlatformFile(), region.offset, | |
115 region.size) != 0) { | |
116 DPLOG(ERROR) << "posix_fallocate " << file_.GetPlatformFile(); | |
117 return false; | |
118 } | |
119 #endif | |
120 | |
88 break; | 121 break; |
89 } | 122 } |
123 | |
90 data_ = static_cast<uint8_t*>(mmap(NULL, map_size, flags, MAP_SHARED, | 124 data_ = static_cast<uint8_t*>(mmap(NULL, map_size, flags, MAP_SHARED, |
91 file_.GetPlatformFile(), map_start)); | 125 file_.GetPlatformFile(), map_start)); |
92 if (data_ == MAP_FAILED) { | 126 if (data_ == MAP_FAILED) { |
93 DPLOG(ERROR) << "mmap " << file_.GetPlatformFile(); | 127 DPLOG(ERROR) << "mmap " << file_.GetPlatformFile(); |
94 return false; | 128 return false; |
95 } | 129 } |
96 | 130 |
97 data_ += data_offset; | 131 data_ += data_offset; |
98 return true; | 132 return true; |
99 } | 133 } |
100 #endif | 134 #endif |
101 | 135 |
102 void MemoryMappedFile::CloseHandles() { | 136 void MemoryMappedFile::CloseHandles() { |
103 ThreadRestrictions::AssertIOAllowed(); | 137 ThreadRestrictions::AssertIOAllowed(); |
104 | 138 |
105 if (data_ != NULL) | 139 if (data_ != NULL) |
106 munmap(data_, length_); | 140 munmap(data_, length_); |
107 file_.Close(); | 141 file_.Close(); |
108 | 142 |
109 data_ = NULL; | 143 data_ = NULL; |
110 length_ = 0; | 144 length_ = 0; |
111 } | 145 } |
112 | 146 |
113 } // namespace base | 147 } // namespace base |
OLD | NEW |