Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: components/leveldb/env_mojo.cc

Issue 2752963002: Add UMA histograms to mojo leveldb env (Closed)
Patch Set: better logging Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/leveldb/env_mojo.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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 "components/leveldb/env_mojo.h" 5 #include "components/leveldb/env_mojo.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/metrics/histogram_macros.h"
11 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
12 #include "base/task_scheduler/post_task.h" 13 #include "base/task_scheduler/post_task.h"
13 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
14 #include "third_party/leveldatabase/chromium_logger.h" 15 #include "third_party/leveldatabase/chromium_logger.h"
15 #include "third_party/leveldatabase/env_chromium.h"
16 #include "third_party/leveldatabase/src/include/leveldb/status.h" 16 #include "third_party/leveldatabase/src/include/leveldb/status.h"
17 17
18 using filesystem::mojom::FileError;
19 using leveldb_env::UMALogger;
20
18 namespace leveldb { 21 namespace leveldb {
19 22
20 namespace { 23 namespace {
21 24
22 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb"); 25 const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb");
23 26
24 base::File::Error LastFileError() { 27 base::File::Error LastFileError() {
25 #if defined(OS_WIN) 28 #if defined(OS_WIN)
26 return base::File::OSErrorToFileError(GetLastError()); 29 return base::File::OSErrorToFileError(GetLastError());
27 #else 30 #else
28 return base::File::OSErrorToFileError(errno); 31 return base::File::OSErrorToFileError(errno);
29 #endif 32 #endif
30 } 33 }
31 34
32 Status FilesystemErrorToStatus(filesystem::mojom::FileError error, 35 Status FilesystemErrorToStatus(FileError error,
33 const std::string& filename, 36 const std::string& filename,
34 leveldb_env::MethodID method) { 37 leveldb_env::MethodID method) {
35 if (error == filesystem::mojom::FileError::OK) 38 if (error == FileError::OK)
36 return Status::OK(); 39 return Status::OK();
37 40
38 std::string err_str = 41 std::string err_str =
39 base::File::ErrorToString(base::File::Error(static_cast<int>(error))); 42 base::File::ErrorToString(base::File::Error(static_cast<int>(error)));
40 43
41 char buf[512]; 44 char buf[512];
42 snprintf(buf, sizeof(buf), "%s (MojoFSError: %d::%s)", err_str.c_str(), 45 snprintf(buf, sizeof(buf), "%s (MojoFSError: %d::%s)", err_str.c_str(),
43 method, MethodIDToString(method)); 46 method, MethodIDToString(method));
44 return Status::IOError(filename, buf); 47 return Status::IOError(filename, buf);
45 } 48 }
(...skipping 12 matching lines...) Expand all
58 return to_return; 61 return to_return;
59 } 62 }
60 63
61 private: 64 private:
62 std::string fname_; 65 std::string fname_;
63 LevelDBMojoProxy::OpaqueLock* lock_; 66 LevelDBMojoProxy::OpaqueLock* lock_;
64 }; 67 };
65 68
66 class MojoSequentialFile : public leveldb::SequentialFile { 69 class MojoSequentialFile : public leveldb::SequentialFile {
67 public: 70 public:
68 MojoSequentialFile(const std::string& fname, base::File f) 71 MojoSequentialFile(const std::string& fname,
69 : filename_(fname), file_(std::move(f)) {} 72 base::File f,
73 const UMALogger* uma_logger)
74 : filename_(fname), file_(std::move(f)), uma_logger_(uma_logger) {}
70 ~MojoSequentialFile() override {} 75 ~MojoSequentialFile() override {}
71 76
72 Status Read(size_t n, Slice* result, char* scratch) override { 77 Status Read(size_t n, Slice* result, char* scratch) override {
73 int bytes_read = file_.ReadAtCurrentPosNoBestEffort( 78 int bytes_read = file_.ReadAtCurrentPosNoBestEffort(
74 scratch, 79 scratch,
75 static_cast<int>(n)); 80 static_cast<int>(n));
76 if (bytes_read == -1) { 81 if (bytes_read == -1) {
77 base::File::Error error = LastFileError(); 82 base::File::Error error = LastFileError();
83 uma_logger_->RecordOSError(leveldb_env::kSequentialFileRead, error);
78 return MakeIOError(filename_, base::File::ErrorToString(error), 84 return MakeIOError(filename_, base::File::ErrorToString(error),
79 leveldb_env::kSequentialFileRead, error); 85 leveldb_env::kSequentialFileRead, error);
80 } else { 86 } else {
81 *result = Slice(scratch, bytes_read); 87 *result = Slice(scratch, bytes_read);
82 return Status::OK(); 88 return Status::OK();
83 } 89 }
84 } 90 }
85 91
86 Status Skip(uint64_t n) override { 92 Status Skip(uint64_t n) override {
87 if (file_.Seek(base::File::FROM_CURRENT, n) == -1) { 93 if (file_.Seek(base::File::FROM_CURRENT, n) == -1) {
88 base::File::Error error = LastFileError(); 94 base::File::Error error = LastFileError();
95 uma_logger_->RecordOSError(leveldb_env::kSequentialFileSkip, error);
89 return MakeIOError(filename_, base::File::ErrorToString(error), 96 return MakeIOError(filename_, base::File::ErrorToString(error),
90 leveldb_env::kSequentialFileSkip, error); 97 leveldb_env::kSequentialFileSkip, error);
91 } else { 98 } else {
92 return Status::OK(); 99 return Status::OK();
93 } 100 }
94 } 101 }
95 102
96 private: 103 private:
97 std::string filename_; 104 std::string filename_;
98 base::File file_; 105 base::File file_;
106 const UMALogger* uma_logger_;
99 107
100 DISALLOW_COPY_AND_ASSIGN(MojoSequentialFile); 108 DISALLOW_COPY_AND_ASSIGN(MojoSequentialFile);
101 }; 109 };
102 110
103 class MojoRandomAccessFile : public leveldb::RandomAccessFile { 111 class MojoRandomAccessFile : public leveldb::RandomAccessFile {
104 public: 112 public:
105 MojoRandomAccessFile(const std::string& fname, base::File file) 113 MojoRandomAccessFile(const std::string& fname,
106 : filename_(fname), file_(std::move(file)) {} 114 base::File file,
115 const UMALogger* uma_logger)
116 : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {}
107 ~MojoRandomAccessFile() override {} 117 ~MojoRandomAccessFile() override {}
108 118
109 Status Read(uint64_t offset, 119 Status Read(uint64_t offset,
110 size_t n, 120 size_t n,
111 Slice* result, 121 Slice* result,
112 char* scratch) const override { 122 char* scratch) const override {
113 Status s; 123 Status s;
114 int r = file_.Read(offset, scratch, static_cast<int>(n)); 124 int r = file_.Read(offset, scratch, static_cast<int>(n));
115 *result = Slice(scratch, (r < 0) ? 0 : r); 125 *result = Slice(scratch, (r < 0) ? 0 : r);
116 if (r < 0) { 126 if (r < 0) {
117 // An error: return a non-ok status 127 // An error: return a non-ok status
118 s = MakeIOError(filename_, "Could not perform read", 128 s = MakeIOError(filename_, "Could not perform read",
119 leveldb_env::kRandomAccessFileRead); 129 leveldb_env::kRandomAccessFileRead);
130 uma_logger_->RecordOSError(leveldb_env::kRandomAccessFileRead,
131 LastFileError());
120 } 132 }
121 return s; 133 return s;
122 } 134 }
123 135
124 private: 136 private:
125 std::string filename_; 137 std::string filename_;
126 mutable base::File file_; 138 mutable base::File file_;
139 const UMALogger* uma_logger_;
127 140
128 DISALLOW_COPY_AND_ASSIGN(MojoRandomAccessFile); 141 DISALLOW_COPY_AND_ASSIGN(MojoRandomAccessFile);
129 }; 142 };
130 143
131 class MojoWritableFile : public leveldb::WritableFile { 144 class MojoWritableFile : public leveldb::WritableFile {
132 public: 145 public:
133 MojoWritableFile(LevelDBMojoProxy::OpaqueDir* dir, 146 MojoWritableFile(LevelDBMojoProxy::OpaqueDir* dir,
134 const std::string& fname, 147 const std::string& fname,
135 base::File f, 148 base::File f,
136 scoped_refptr<LevelDBMojoProxy> thread) 149 scoped_refptr<LevelDBMojoProxy> thread,
150 const UMALogger* uma_logger)
137 : filename_(fname), 151 : filename_(fname),
138 file_(std::move(f)), 152 file_(std::move(f)),
139 file_type_(kOther), 153 file_type_(kOther),
140 dir_(dir), 154 dir_(dir),
141 thread_(thread) { 155 thread_(thread),
156 uma_logger_(uma_logger) {
142 base::FilePath path = base::FilePath::FromUTF8Unsafe(fname); 157 base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
143 if (base::StartsWith(path.BaseName().AsUTF8Unsafe(), "MANIFEST", 158 if (base::StartsWith(path.BaseName().AsUTF8Unsafe(), "MANIFEST",
144 base::CompareCase::SENSITIVE)) { 159 base::CompareCase::SENSITIVE)) {
145 file_type_ = kManifest; 160 file_type_ = kManifest;
146 } else if (path.MatchesExtension(table_extension)) { 161 } else if (path.MatchesExtension(table_extension)) {
147 file_type_ = kTable; 162 file_type_ = kTable;
148 } 163 }
149 parent_dir_ = 164 parent_dir_ =
150 base::FilePath::FromUTF8Unsafe(fname).DirName().AsUTF8Unsafe(); 165 base::FilePath::FromUTF8Unsafe(fname).DirName().AsUTF8Unsafe();
151 } 166 }
152 167
153 ~MojoWritableFile() override {} 168 ~MojoWritableFile() override {}
154 169
155 leveldb::Status Append(const leveldb::Slice& data) override { 170 leveldb::Status Append(const leveldb::Slice& data) override {
156 size_t bytes_written = file_.WriteAtCurrentPos( 171 size_t bytes_written = file_.WriteAtCurrentPos(
157 data.data(), static_cast<int>(data.size())); 172 data.data(), static_cast<int>(data.size()));
158 if (bytes_written != data.size()) { 173 if (bytes_written != data.size()) {
159 base::File::Error error = LastFileError(); 174 base::File::Error error = LastFileError();
175 uma_logger_->RecordOSError(leveldb_env::kWritableFileAppend, error);
160 return MakeIOError(filename_, base::File::ErrorToString(error), 176 return MakeIOError(filename_, base::File::ErrorToString(error),
161 leveldb_env::kWritableFileAppend, error); 177 leveldb_env::kWritableFileAppend, error);
162 } 178 }
163 179
164 return Status::OK(); 180 return Status::OK();
165 } 181 }
166 182
167 leveldb::Status Close() override { 183 leveldb::Status Close() override {
168 file_.Close(); 184 file_.Close();
169 return Status::OK(); 185 return Status::OK();
170 } 186 }
171 187
172 leveldb::Status Flush() override { 188 leveldb::Status Flush() override {
173 // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing 189 // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing
174 // to 190 // to
175 // flush. 191 // flush.
176 return Status::OK(); 192 return Status::OK();
177 } 193 }
178 194
179 leveldb::Status Sync() override { 195 leveldb::Status Sync() override {
180 TRACE_EVENT0("leveldb", "MojoWritableFile::Sync"); 196 TRACE_EVENT0("leveldb", "MojoWritableFile::Sync");
181 197
182 if (!file_.Flush()) { 198 if (!file_.Flush()) {
183 base::File::Error error = LastFileError(); 199 base::File::Error error = LastFileError();
200 uma_logger_->RecordOSError(leveldb_env::kWritableFileSync, error);
184 return MakeIOError(filename_, base::File::ErrorToString(error), 201 return MakeIOError(filename_, base::File::ErrorToString(error),
185 leveldb_env::kWritableFileSync, error); 202 leveldb_env::kWritableFileSync, error);
186 } 203 }
187 204
188 // leveldb's implicit contract for Sync() is that if this instance is for a 205 // leveldb's implicit contract for Sync() is that if this instance is for a
189 // manifest file then the directory is also sync'ed. See leveldb's 206 // manifest file then the directory is also sync'ed. See leveldb's
190 // env_posix.cc. 207 // env_posix.cc.
191 if (file_type_ == kManifest) 208 if (file_type_ == kManifest)
192 return SyncParent(); 209 return SyncParent();
193 210
194 return Status::OK(); 211 return Status::OK();
195 } 212 }
196 213
197 private: 214 private:
198 enum Type { kManifest, kTable, kOther }; 215 enum Type { kManifest, kTable, kOther };
199 216
200 leveldb::Status SyncParent() { 217 leveldb::Status SyncParent() {
201 filesystem::mojom::FileError error = 218 FileError error = thread_->SyncDirectory(dir_, parent_dir_);
202 thread_->SyncDirectory(dir_, parent_dir_); 219 return error == FileError::OK
203 return error == filesystem::mojom::FileError::OK
204 ? Status::OK() 220 ? Status::OK()
205 : Status::IOError(filename_, 221 : Status::IOError(filename_,
206 base::File::ErrorToString(base::File::Error( 222 base::File::ErrorToString(base::File::Error(
207 static_cast<int>(error)))); 223 static_cast<int>(error))));
208 } 224 }
209 225
210 std::string filename_; 226 std::string filename_;
211 base::File file_; 227 base::File file_;
212 Type file_type_; 228 Type file_type_;
213 LevelDBMojoProxy::OpaqueDir* dir_; 229 LevelDBMojoProxy::OpaqueDir* dir_;
214 std::string parent_dir_; 230 std::string parent_dir_;
215 scoped_refptr<LevelDBMojoProxy> thread_; 231 scoped_refptr<LevelDBMojoProxy> thread_;
232 const UMALogger* uma_logger_;
216 233
217 DISALLOW_COPY_AND_ASSIGN(MojoWritableFile); 234 DISALLOW_COPY_AND_ASSIGN(MojoWritableFile);
218 }; 235 };
219 236
220 class Thread : public base::PlatformThread::Delegate { 237 class Thread : public base::PlatformThread::Delegate {
221 public: 238 public:
222 Thread(void (*function)(void* arg), void* arg) 239 Thread(void (*function)(void* arg), void* arg)
223 : function_(function), arg_(arg) { 240 : function_(function), arg_(arg) {
224 base::PlatformThreadHandle handle; 241 base::PlatformThreadHandle handle;
225 bool success = base::PlatformThread::Create(0, this, &handle); 242 bool success = base::PlatformThread::Create(0, this, &handle);
(...skipping 22 matching lines...) Expand all
248 thread_->UnregisterDirectory(dir_); 265 thread_->UnregisterDirectory(dir_);
249 } 266 }
250 267
251 Status MojoEnv::NewSequentialFile(const std::string& fname, 268 Status MojoEnv::NewSequentialFile(const std::string& fname,
252 SequentialFile** result) { 269 SequentialFile** result) {
253 TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname); 270 TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname);
254 base::File f = thread_->OpenFileHandle( 271 base::File f = thread_->OpenFileHandle(
255 dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead); 272 dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
256 if (!f.IsValid()) { 273 if (!f.IsValid()) {
257 *result = nullptr; 274 *result = nullptr;
275 RecordOSError(leveldb_env::kNewSequentialFile, f.error_details());
258 return MakeIOError(fname, "Unable to create sequential file", 276 return MakeIOError(fname, "Unable to create sequential file",
259 leveldb_env::kNewSequentialFile, f.error_details()); 277 leveldb_env::kNewSequentialFile, f.error_details());
260 } 278 }
261 279
262 *result = new MojoSequentialFile(fname, std::move(f)); 280 *result = new MojoSequentialFile(fname, std::move(f), this);
263 return Status::OK(); 281 return Status::OK();
264 } 282 }
265 283
266 Status MojoEnv::NewRandomAccessFile(const std::string& fname, 284 Status MojoEnv::NewRandomAccessFile(const std::string& fname,
267 RandomAccessFile** result) { 285 RandomAccessFile** result) {
268 TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname); 286 TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname);
269 base::File f = thread_->OpenFileHandle( 287 base::File f = thread_->OpenFileHandle(
270 dir_, fname, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen); 288 dir_, fname, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen);
271 if (!f.IsValid()) { 289 if (!f.IsValid()) {
272 *result = nullptr; 290 *result = nullptr;
273 base::File::Error error_code = f.error_details(); 291 base::File::Error error_code = f.error_details();
292 RecordOSError(leveldb_env::kNewRandomAccessFile, error_code);
274 return MakeIOError(fname, base::File::ErrorToString(error_code), 293 return MakeIOError(fname, base::File::ErrorToString(error_code),
275 leveldb_env::kNewRandomAccessFile, error_code); 294 leveldb_env::kNewRandomAccessFile, error_code);
276 } 295 }
277 296
278 *result = new MojoRandomAccessFile(fname, std::move(f)); 297 *result = new MojoRandomAccessFile(fname, std::move(f), this);
279 return Status::OK(); 298 return Status::OK();
280 } 299 }
281 300
282 Status MojoEnv::NewWritableFile(const std::string& fname, 301 Status MojoEnv::NewWritableFile(const std::string& fname,
283 WritableFile** result) { 302 WritableFile** result) {
284 TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname); 303 TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname);
285 base::File f = 304 base::File f =
286 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kCreateAlways | 305 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kCreateAlways |
287 filesystem::mojom::kFlagWrite); 306 filesystem::mojom::kFlagWrite);
288 if (!f.IsValid()) { 307 if (!f.IsValid()) {
289 *result = nullptr; 308 *result = nullptr;
309 RecordOSError(leveldb_env::kNewWritableFile, f.error_details());
290 return MakeIOError(fname, "Unable to create writable file", 310 return MakeIOError(fname, "Unable to create writable file",
291 leveldb_env::kNewWritableFile, f.error_details()); 311 leveldb_env::kNewWritableFile, f.error_details());
292 } 312 }
293 313
294 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_); 314 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
295 return Status::OK(); 315 return Status::OK();
296 } 316 }
297 317
298 Status MojoEnv::NewAppendableFile(const std::string& fname, 318 Status MojoEnv::NewAppendableFile(const std::string& fname,
299 WritableFile** result) { 319 WritableFile** result) {
300 TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname); 320 TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname);
301 base::File f = 321 base::File f =
302 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kFlagOpenAlways | 322 thread_->OpenFileHandle(dir_, fname, filesystem::mojom::kFlagOpenAlways |
303 filesystem::mojom::kFlagAppend); 323 filesystem::mojom::kFlagAppend);
304 if (!f.IsValid()) { 324 if (!f.IsValid()) {
305 *result = nullptr; 325 *result = nullptr;
326 RecordOSError(leveldb_env::kNewAppendableFile, f.error_details());
306 return MakeIOError(fname, "Unable to create appendable file", 327 return MakeIOError(fname, "Unable to create appendable file",
307 leveldb_env::kNewAppendableFile, f.error_details()); 328 leveldb_env::kNewAppendableFile, f.error_details());
308 } 329 }
309 330
310 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_); 331 *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
311 return Status::OK(); 332 return Status::OK();
312 } 333 }
313 334
314 bool MojoEnv::FileExists(const std::string& fname) { 335 bool MojoEnv::FileExists(const std::string& fname) {
315 TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname); 336 TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname);
316 return thread_->FileExists(dir_, fname); 337 return thread_->FileExists(dir_, fname);
317 } 338 }
318 339
319 Status MojoEnv::GetChildren(const std::string& path, 340 Status MojoEnv::GetChildren(const std::string& path,
320 std::vector<std::string>* result) { 341 std::vector<std::string>* result) {
321 TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path); 342 TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
322 return FilesystemErrorToStatus(thread_->GetChildren(dir_, path, result), path, 343 FileError error = thread_->GetChildren(dir_, path, result);
323 leveldb_env::kGetChildren); 344 if (error != FileError::OK)
345 RecordFileError(leveldb_env::kGetChildren, error);
346 return FilesystemErrorToStatus(error, path, leveldb_env::kGetChildren);
324 } 347 }
325 348
326 Status MojoEnv::DeleteFile(const std::string& fname) { 349 Status MojoEnv::DeleteFile(const std::string& fname) {
327 TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname); 350 TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
328 return FilesystemErrorToStatus(thread_->Delete(dir_, fname, 0), fname, 351 FileError error = thread_->Delete(dir_, fname, 0);
329 leveldb_env::kDeleteFile); 352 if (error != FileError::OK)
353 RecordFileError(leveldb_env::kDeleteFile, error);
354 return FilesystemErrorToStatus(error, fname, leveldb_env::kDeleteFile);
330 } 355 }
331 356
332 Status MojoEnv::CreateDir(const std::string& dirname) { 357 Status MojoEnv::CreateDir(const std::string& dirname) {
333 TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname); 358 TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
334 return FilesystemErrorToStatus(thread_->CreateDir(dir_, dirname), dirname, 359 FileError error = thread_->CreateDir(dir_, dirname);
335 leveldb_env::kCreateDir); 360 if (error != FileError::OK)
361 RecordFileError(leveldb_env::kCreateDir, error);
362 return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir);
336 } 363 }
337 364
338 Status MojoEnv::DeleteDir(const std::string& dirname) { 365 Status MojoEnv::DeleteDir(const std::string& dirname) {
339 TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname); 366 TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
340 return FilesystemErrorToStatus( 367 FileError error =
341 thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive), 368 thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive);
342 dirname, leveldb_env::kDeleteDir); 369 if (error != FileError::OK)
370 RecordFileError(leveldb_env::kDeleteDir, error);
371 return FilesystemErrorToStatus(error, dirname, leveldb_env::kDeleteDir);
343 } 372 }
344 373
345 Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) { 374 Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
346 TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname); 375 TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
347 return FilesystemErrorToStatus(thread_->GetFileSize(dir_, fname, file_size), 376 FileError error = thread_->GetFileSize(dir_, fname, file_size);
348 fname, 377 if (error != FileError::OK)
349 leveldb_env::kGetFileSize); 378 RecordFileError(leveldb_env::kGetFileSize, error);
379 return FilesystemErrorToStatus(error, fname, leveldb_env::kGetFileSize);
350 } 380 }
351 381
352 Status MojoEnv::RenameFile(const std::string& src, const std::string& target) { 382 Status MojoEnv::RenameFile(const std::string& src, const std::string& target) {
353 TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target); 383 TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target);
354 return FilesystemErrorToStatus(thread_->RenameFile(dir_, src, target), src, 384 FileError error = thread_->RenameFile(dir_, src, target);
355 leveldb_env::kRenameFile); 385 if (error != FileError::OK)
386 RecordFileError(leveldb_env::kRenameFile, error);
387 return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile);
356 } 388 }
357 389
358 Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) { 390 Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) {
359 TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname); 391 TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
360 392
361 std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p = 393 std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p =
cmumford 2017/05/17 17:58:37 Can remove namespaces on this FileError (and below
Marijn Kruisselbrink 2017/05/17 19:00:21 Done
362 thread_->LockFile(dir_, fname); 394 thread_->LockFile(dir_, fname);
363 395
396 if (p.first != FileError::OK)
397 RecordFileError(leveldb_env::kLockFile, p.first);
398
364 if (p.second) 399 if (p.second)
365 *lock = new MojoFileLock(p.second, fname); 400 *lock = new MojoFileLock(p.second, fname);
366 401
367 return FilesystemErrorToStatus(p.first, fname, leveldb_env::kLockFile); 402 return FilesystemErrorToStatus(p.first, fname, leveldb_env::kLockFile);
368 } 403 }
369 404
370 Status MojoEnv::UnlockFile(FileLock* lock) { 405 Status MojoEnv::UnlockFile(FileLock* lock) {
371 MojoFileLock* my_lock = reinterpret_cast<MojoFileLock*>(lock); 406 MojoFileLock* my_lock = reinterpret_cast<MojoFileLock*>(lock);
372 407
373 std::string fname = my_lock ? my_lock->name() : "(invalid)"; 408 std::string fname = my_lock ? my_lock->name() : "(invalid)";
374 TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname); 409 TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname);
375 410
376 filesystem::mojom::FileError err = thread_->UnlockFile(my_lock->TakeLock()); 411 filesystem::mojom::FileError error = thread_->UnlockFile(my_lock->TakeLock());
412 if (error != FileError::OK)
413 RecordFileError(leveldb_env::kUnlockFile, error);
377 delete my_lock; 414 delete my_lock;
378 return FilesystemErrorToStatus(err, fname, leveldb_env::kUnlockFile); 415 return FilesystemErrorToStatus(error, fname, leveldb_env::kUnlockFile);
379 } 416 }
380 417
381 Status MojoEnv::GetTestDirectory(std::string* path) { 418 Status MojoEnv::GetTestDirectory(std::string* path) {
382 // TODO(erg): This method is actually only used from the test harness in 419 // TODO(erg): This method is actually only used from the test harness in
383 // leveldb. And when we go and port that test stuff to a 420 // leveldb. And when we go and port that test stuff to a
384 // service_manager::ServiceTest, 421 // service_manager::ServiceTest,
385 // we probably won't use it since the mojo filesystem actually handles 422 // we probably won't use it since the mojo filesystem actually handles
386 // temporary filesystems just fine. 423 // temporary filesystems just fine.
387 NOTREACHED(); 424 NOTREACHED();
388 return Status::OK(); 425 return Status::OK();
389 } 426 }
390 427
391 Status MojoEnv::NewLogger(const std::string& fname, Logger** result) { 428 Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
392 TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname); 429 TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname);
393 base::File f(thread_->OpenFileHandle( 430 base::File f(thread_->OpenFileHandle(
394 dir_, fname, 431 dir_, fname,
395 filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite)); 432 filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite));
396 if (!f.IsValid()) { 433 if (!f.IsValid()) {
397 *result = NULL; 434 *result = NULL;
435 RecordOSError(leveldb_env::kNewLogger, f.error_details());
398 return MakeIOError(fname, "Unable to create log file", 436 return MakeIOError(fname, "Unable to create log file",
399 leveldb_env::kNewLogger, f.error_details()); 437 leveldb_env::kNewLogger, f.error_details());
400 } else { 438 } else {
401 *result = new leveldb::ChromiumLogger(std::move(f)); 439 *result = new leveldb::ChromiumLogger(std::move(f));
402 return Status::OK(); 440 return Status::OK();
403 } 441 }
404 } 442 }
405 443
444 void MojoEnv::RecordErrorAt(leveldb_env::MethodID method) const {
445 UMA_HISTOGRAM_ENUMERATION("MojoLevelDBEnv.IOError", method,
446 leveldb_env::kNumEntries);
447 }
448
449 void MojoEnv::RecordOSError(leveldb_env::MethodID method,
450 base::File::Error error) const {
451 RecordErrorAt(method);
452 std::string uma_name =
453 std::string("MojoLevelDBEnv.IOError.BFE.") + MethodIDToString(method);
454 base::LinearHistogram::FactoryGet(uma_name, 1, -base::File::FILE_ERROR_MAX,
455 -base::File::FILE_ERROR_MAX + 1,
456 base::Histogram::kUmaTargetedHistogramFlag)
457 ->Add(-error);
458 }
459
460 void MojoEnv::RecordFileError(leveldb_env::MethodID method,
461 FileError error) const {
462 RecordOSError(method, static_cast<base::File::Error>(error));
463 }
464
406 uint64_t MojoEnv::NowMicros() { 465 uint64_t MojoEnv::NowMicros() {
407 return base::TimeTicks::Now().ToInternalValue(); 466 return base::TimeTicks::Now().ToInternalValue();
408 } 467 }
409 468
410 void MojoEnv::SleepForMicroseconds(int micros) { 469 void MojoEnv::SleepForMicroseconds(int micros) {
411 // Round up to the next millisecond. 470 // Round up to the next millisecond.
412 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros)); 471 base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros));
413 } 472 }
414 473
415 void MojoEnv::Schedule(void (*function)(void* arg), void* arg) { 474 void MojoEnv::Schedule(void (*function)(void* arg), void* arg) {
416 base::PostTaskWithTraits(FROM_HERE, 475 base::PostTaskWithTraits(FROM_HERE,
417 {base::MayBlock(), base::WithBaseSyncPrimitives(), 476 {base::MayBlock(), base::WithBaseSyncPrimitives(),
418 base::TaskShutdownBehavior::BLOCK_SHUTDOWN}, 477 base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
419 base::Bind(function, arg)); 478 base::Bind(function, arg));
420 } 479 }
421 480
422 void MojoEnv::StartThread(void (*function)(void* arg), void* arg) { 481 void MojoEnv::StartThread(void (*function)(void* arg), void* arg) {
423 new Thread(function, arg); // Will self-delete. 482 new Thread(function, arg); // Will self-delete.
424 } 483 }
425 484
426 } // namespace leveldb 485 } // namespace leveldb
OLDNEW
« no previous file with comments | « components/leveldb/env_mojo.h ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698