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

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

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