summaryrefslogtreecommitdiff
path: root/chromium/components/leveldb/env_mojo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/leveldb/env_mojo.cc')
-rw-r--r--chromium/components/leveldb/env_mojo.cc171
1 files changed, 120 insertions, 51 deletions
diff --git a/chromium/components/leveldb/env_mojo.cc b/chromium/components/leveldb/env_mojo.cc
index 4f82181a5a3..9b98405d125 100644
--- a/chromium/components/leveldb/env_mojo.cc
+++ b/chromium/components/leveldb/env_mojo.cc
@@ -8,13 +8,17 @@
#include <memory>
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "base/strings/string_util.h"
#include "base/task_scheduler/post_task.h"
#include "base/trace_event/trace_event.h"
#include "third_party/leveldatabase/chromium_logger.h"
-#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/status.h"
+using filesystem::mojom::FileError;
+using leveldb_env::UMALogger;
+
namespace leveldb {
namespace {
@@ -29,10 +33,10 @@ base::File::Error LastFileError() {
#endif
}
-Status FilesystemErrorToStatus(filesystem::mojom::FileError error,
+Status FilesystemErrorToStatus(FileError error,
const std::string& filename,
leveldb_env::MethodID method) {
- if (error == filesystem::mojom::FileError::OK)
+ if (error == FileError::OK)
return Status::OK();
std::string err_str =
@@ -65,8 +69,10 @@ class MojoFileLock : public FileLock {
class MojoSequentialFile : public leveldb::SequentialFile {
public:
- MojoSequentialFile(const std::string& fname, base::File f)
- : filename_(fname), file_(std::move(f)) {}
+ MojoSequentialFile(const std::string& fname,
+ base::File f,
+ const UMALogger* uma_logger)
+ : filename_(fname), file_(std::move(f)), uma_logger_(uma_logger) {}
~MojoSequentialFile() override {}
Status Read(size_t n, Slice* result, char* scratch) override {
@@ -75,17 +81,20 @@ class MojoSequentialFile : public leveldb::SequentialFile {
static_cast<int>(n));
if (bytes_read == -1) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kSequentialFileRead, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kSequentialFileRead, error);
- } else {
- *result = Slice(scratch, bytes_read);
- return Status::OK();
}
+ if (bytes_read > 0)
+ uma_logger_->RecordBytesRead(bytes_read);
+ *result = Slice(scratch, bytes_read);
+ return Status::OK();
}
Status Skip(uint64_t n) override {
if (file_.Seek(base::File::FROM_CURRENT, n) == -1) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kSequentialFileSkip, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kSequentialFileSkip, error);
} else {
@@ -96,34 +105,40 @@ class MojoSequentialFile : public leveldb::SequentialFile {
private:
std::string filename_;
base::File file_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoSequentialFile);
};
class MojoRandomAccessFile : public leveldb::RandomAccessFile {
public:
- MojoRandomAccessFile(const std::string& fname, base::File file)
- : filename_(fname), file_(std::move(file)) {}
+ MojoRandomAccessFile(const std::string& fname,
+ base::File file,
+ const UMALogger* uma_logger)
+ : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {}
~MojoRandomAccessFile() override {}
Status Read(uint64_t offset,
size_t n,
Slice* result,
char* scratch) const override {
- Status s;
- int r = file_.Read(offset, scratch, static_cast<int>(n));
- *result = Slice(scratch, (r < 0) ? 0 : r);
- if (r < 0) {
- // An error: return a non-ok status
- s = MakeIOError(filename_, "Could not perform read",
- leveldb_env::kRandomAccessFileRead);
+ int bytes_read = file_.Read(offset, scratch, static_cast<int>(n));
+ *result = Slice(scratch, (bytes_read < 0) ? 0 : bytes_read);
+ if (bytes_read < 0) {
+ uma_logger_->RecordOSError(leveldb_env::kRandomAccessFileRead,
+ LastFileError());
+ return MakeIOError(filename_, "Could not perform read",
+ leveldb_env::kRandomAccessFileRead);
}
- return s;
+ if (bytes_read > 0)
+ uma_logger_->RecordBytesRead(bytes_read);
+ return Status::OK();
}
private:
std::string filename_;
mutable base::File file_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoRandomAccessFile);
};
@@ -133,12 +148,14 @@ class MojoWritableFile : public leveldb::WritableFile {
MojoWritableFile(LevelDBMojoProxy::OpaqueDir* dir,
const std::string& fname,
base::File f,
- scoped_refptr<LevelDBMojoProxy> thread)
+ scoped_refptr<LevelDBMojoProxy> thread,
+ const UMALogger* uma_logger)
: filename_(fname),
file_(std::move(f)),
file_type_(kOther),
dir_(dir),
- thread_(thread) {
+ thread_(thread),
+ uma_logger_(uma_logger) {
base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
if (base::StartsWith(path.BaseName().AsUTF8Unsafe(), "MANIFEST",
base::CompareCase::SENSITIVE)) {
@@ -153,14 +170,16 @@ class MojoWritableFile : public leveldb::WritableFile {
~MojoWritableFile() override {}
leveldb::Status Append(const leveldb::Slice& data) override {
- size_t bytes_written = file_.WriteAtCurrentPos(
- data.data(), static_cast<int>(data.size()));
- if (bytes_written != data.size()) {
+ int bytes_written =
+ file_.WriteAtCurrentPos(data.data(), static_cast<int>(data.size()));
+ if (bytes_written != static_cast<int>(data.size())) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kWritableFileAppend, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kWritableFileAppend, error);
}
-
+ if (bytes_written > 0)
+ uma_logger_->RecordBytesWritten(bytes_written);
return Status::OK();
}
@@ -171,8 +190,7 @@ class MojoWritableFile : public leveldb::WritableFile {
leveldb::Status Flush() override {
// base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing
- // to
- // flush.
+ // to flush.
return Status::OK();
}
@@ -181,6 +199,7 @@ class MojoWritableFile : public leveldb::WritableFile {
if (!file_.Flush()) {
base::File::Error error = LastFileError();
+ uma_logger_->RecordOSError(leveldb_env::kWritableFileSync, error);
return MakeIOError(filename_, base::File::ErrorToString(error),
leveldb_env::kWritableFileSync, error);
}
@@ -198,9 +217,8 @@ class MojoWritableFile : public leveldb::WritableFile {
enum Type { kManifest, kTable, kOther };
leveldb::Status SyncParent() {
- filesystem::mojom::FileError error =
- thread_->SyncDirectory(dir_, parent_dir_);
- return error == filesystem::mojom::FileError::OK
+ FileError error = thread_->SyncDirectory(dir_, parent_dir_);
+ return error == FileError::OK
? Status::OK()
: Status::IOError(filename_,
base::File::ErrorToString(base::File::Error(
@@ -213,6 +231,7 @@ class MojoWritableFile : public leveldb::WritableFile {
LevelDBMojoProxy::OpaqueDir* dir_;
std::string parent_dir_;
scoped_refptr<LevelDBMojoProxy> thread_;
+ const UMALogger* uma_logger_;
DISALLOW_COPY_AND_ASSIGN(MojoWritableFile);
};
@@ -255,11 +274,12 @@ Status MojoEnv::NewSequentialFile(const std::string& fname,
dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewSequentialFile, f.error_details());
return MakeIOError(fname, "Unable to create sequential file",
leveldb_env::kNewSequentialFile, f.error_details());
}
- *result = new MojoSequentialFile(fname, std::move(f));
+ *result = new MojoSequentialFile(fname, std::move(f), this);
return Status::OK();
}
@@ -271,11 +291,12 @@ Status MojoEnv::NewRandomAccessFile(const std::string& fname,
if (!f.IsValid()) {
*result = nullptr;
base::File::Error error_code = f.error_details();
+ RecordOSError(leveldb_env::kNewRandomAccessFile, error_code);
return MakeIOError(fname, base::File::ErrorToString(error_code),
leveldb_env::kNewRandomAccessFile, error_code);
}
- *result = new MojoRandomAccessFile(fname, std::move(f));
+ *result = new MojoRandomAccessFile(fname, std::move(f), this);
return Status::OK();
}
@@ -287,11 +308,12 @@ Status MojoEnv::NewWritableFile(const std::string& fname,
filesystem::mojom::kFlagWrite);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewWritableFile, f.error_details());
return MakeIOError(fname, "Unable to create writable file",
leveldb_env::kNewWritableFile, f.error_details());
}
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
+ *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
return Status::OK();
}
@@ -303,11 +325,12 @@ Status MojoEnv::NewAppendableFile(const std::string& fname,
filesystem::mojom::kFlagAppend);
if (!f.IsValid()) {
*result = nullptr;
+ RecordOSError(leveldb_env::kNewAppendableFile, f.error_details());
return MakeIOError(fname, "Unable to create appendable file",
leveldb_env::kNewAppendableFile, f.error_details());
}
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_);
+ *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
return Status::OK();
}
@@ -319,48 +342,62 @@ bool MojoEnv::FileExists(const std::string& fname) {
Status MojoEnv::GetChildren(const std::string& path,
std::vector<std::string>* result) {
TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
- return FilesystemErrorToStatus(thread_->GetChildren(dir_, path, result), path,
- leveldb_env::kGetChildren);
+ FileError error = thread_->GetChildren(dir_, path, result);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kGetChildren, error);
+ return FilesystemErrorToStatus(error, path, leveldb_env::kGetChildren);
}
Status MojoEnv::DeleteFile(const std::string& fname) {
TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
- return FilesystemErrorToStatus(thread_->Delete(dir_, fname, 0), fname,
- leveldb_env::kDeleteFile);
+ FileError error = thread_->Delete(dir_, fname, 0);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kDeleteFile, error);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kDeleteFile);
}
Status MojoEnv::CreateDir(const std::string& dirname) {
TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
- return FilesystemErrorToStatus(thread_->CreateDir(dir_, dirname), dirname,
- leveldb_env::kCreateDir);
+ FileError error = thread_->CreateDir(dir_, dirname);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kCreateDir, error);
+ return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir);
}
Status MojoEnv::DeleteDir(const std::string& dirname) {
TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
- return FilesystemErrorToStatus(
- thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive),
- dirname, leveldb_env::kDeleteDir);
+ FileError error =
+ thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kDeleteDir, error);
+ return FilesystemErrorToStatus(error, dirname, leveldb_env::kDeleteDir);
}
Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
- return FilesystemErrorToStatus(thread_->GetFileSize(dir_, fname, file_size),
- fname,
- leveldb_env::kGetFileSize);
+ FileError error = thread_->GetFileSize(dir_, fname, file_size);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kGetFileSize, error);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kGetFileSize);
}
Status MojoEnv::RenameFile(const std::string& src, const std::string& target) {
TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target);
- return FilesystemErrorToStatus(thread_->RenameFile(dir_, src, target), src,
- leveldb_env::kRenameFile);
+ FileError error = thread_->RenameFile(dir_, src, target);
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kRenameFile, error);
+ return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile);
}
Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) {
TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
- std::pair<filesystem::mojom::FileError, LevelDBMojoProxy::OpaqueLock*> p =
+ std::pair<FileError, LevelDBMojoProxy::OpaqueLock*> p =
thread_->LockFile(dir_, fname);
+ if (p.first != FileError::OK)
+ RecordFileError(leveldb_env::kLockFile, p.first);
+
if (p.second)
*lock = new MojoFileLock(p.second, fname);
@@ -373,9 +410,11 @@ Status MojoEnv::UnlockFile(FileLock* lock) {
std::string fname = my_lock ? my_lock->name() : "(invalid)";
TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname);
- filesystem::mojom::FileError err = thread_->UnlockFile(my_lock->TakeLock());
+ FileError error = thread_->UnlockFile(my_lock->TakeLock());
+ if (error != FileError::OK)
+ RecordFileError(leveldb_env::kUnlockFile, error);
delete my_lock;
- return FilesystemErrorToStatus(err, fname, leveldb_env::kUnlockFile);
+ return FilesystemErrorToStatus(error, fname, leveldb_env::kUnlockFile);
}
Status MojoEnv::GetTestDirectory(std::string* path) {
@@ -395,6 +434,7 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite));
if (!f.IsValid()) {
*result = NULL;
+ RecordOSError(leveldb_env::kNewLogger, f.error_details());
return MakeIOError(fname, "Unable to create log file",
leveldb_env::kNewLogger, f.error_details());
} else {
@@ -403,6 +443,32 @@ Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
}
}
+void MojoEnv::RecordErrorAt(leveldb_env::MethodID method) const {
+ UMA_HISTOGRAM_ENUMERATION("MojoLevelDBEnv.IOError", method,
+ leveldb_env::kNumEntries);
+}
+
+void MojoEnv::RecordOSError(leveldb_env::MethodID method,
+ base::File::Error error) const {
+ RecordErrorAt(method);
+ std::string uma_name =
+ std::string("MojoLevelDBEnv.IOError.BFE.") + MethodIDToString(method);
+ base::UmaHistogramExactLinear(uma_name, -error, -base::File::FILE_ERROR_MAX);
+}
+
+void MojoEnv::RecordBytesRead(int amount) const {
+ UMA_HISTOGRAM_COUNTS_10M("Storage.BytesRead.MojoLevelDBEnv", amount);
+}
+
+void MojoEnv::RecordBytesWritten(int amount) const {
+ UMA_HISTOGRAM_COUNTS_10M("Storage.BytesWritten.MojoLevelDBEnv", amount);
+}
+
+void MojoEnv::RecordFileError(leveldb_env::MethodID method,
+ FileError error) const {
+ RecordOSError(method, static_cast<base::File::Error>(error));
+}
+
uint64_t MojoEnv::NowMicros() {
return base::TimeTicks::Now().ToInternalValue();
}
@@ -413,7 +479,10 @@ void MojoEnv::SleepForMicroseconds(int micros) {
}
void MojoEnv::Schedule(void (*function)(void* arg), void* arg) {
- base::PostTask(FROM_HERE, base::Bind(function, arg));
+ base::PostTaskWithTraits(FROM_HERE,
+ {base::MayBlock(), base::WithBaseSyncPrimitives(),
+ base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
+ base::Bind(function, arg));
}
void MojoEnv::StartThread(void (*function)(void* arg), void* arg) {