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

Unified Diff: webkit/fileapi/file_system_directory_database.cc

Issue 9663021: Add database recovery for FileSystemOriginDatabase (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add tests Created 8 years, 9 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 side-by-side diff with in-line comments
Download patch
Index: webkit/fileapi/file_system_directory_database.cc
diff --git a/webkit/fileapi/file_system_directory_database.cc b/webkit/fileapi/file_system_directory_database.cc
index 217b98ffbff74be110ffd358b3425f8b5ed586b2..1cad6b3a23a1533009b9de138faf8cb4967abd25 100644
--- a/webkit/fileapi/file_system_directory_database.cc
+++ b/webkit/fileapi/file_system_directory_database.cc
@@ -12,6 +12,7 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
+#include "third_party/leveldatabase/src/include/leveldb/status.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
#include "webkit/fileapi/file_system_util.h"
@@ -130,7 +131,7 @@ FileSystemDirectoryDatabase::~FileSystemDirectoryDatabase() {
bool FileSystemDirectoryDatabase::GetChildWithName(
FileId parent_id, const FilePath::StringType& name, FileId* child_id) {
- if (!Init())
+ if (!Init(true))
jsbell 2012/03/09 23:10:11 The Boolean argument isn't very readable. Use an e
tzik 2012/03/10 00:16:55 Done.
return false;
DCHECK(child_id);
std::string child_key = GetChildLookupKey(parent_id, name);
@@ -171,7 +172,7 @@ bool FileSystemDirectoryDatabase::GetFileWithPath(
bool FileSystemDirectoryDatabase::ListChildren(
FileId parent_id, std::vector<FileId>* children) {
// Check to add later: fail if parent is a file, at least in debug builds.
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(children);
std::string child_key_prefix = GetChildListingKeyPrefix(parent_id);
@@ -194,7 +195,7 @@ bool FileSystemDirectoryDatabase::ListChildren(
}
bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) {
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(info);
std::string file_key = GetFileLookupKey(file_id);
@@ -221,7 +222,7 @@ bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) {
bool FileSystemDirectoryDatabase::AddFileInfo(
const FileInfo& info, FileId* file_id) {
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(file_id);
std::string child_key = GetChildLookupKey(info.parent_id, info.name);
@@ -263,7 +264,7 @@ bool FileSystemDirectoryDatabase::AddFileInfo(
}
bool FileSystemDirectoryDatabase::RemoveFileInfo(FileId file_id) {
- if (!Init())
+ if (!Init(true))
return false;
leveldb::WriteBatch batch;
if (!RemoveFileInfoHelper(file_id, &batch))
@@ -280,7 +281,7 @@ bool FileSystemDirectoryDatabase::UpdateFileInfo(
FileId file_id, const FileInfo& new_info) {
// TODO: We should also check to see that this doesn't create a loop, but
// perhaps only in a debug build.
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(file_id); // You can't remove the root, ever. Just delete the DB.
FileInfo old_info;
@@ -364,7 +365,7 @@ bool FileSystemDirectoryDatabase::OverwritingMoveFile(
}
bool FileSystemDirectoryDatabase::GetNextInteger(int64* next) {
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(next);
std::string int_string;
@@ -413,20 +414,40 @@ bool FileSystemDirectoryDatabase::DestroyDatabase(const FilePath& path) {
return false;
}
-bool FileSystemDirectoryDatabase::Init() {
- if (db_.get())
- return true;
-
- leveldb::Options options;
- options.create_if_missing = true;
- leveldb::DB* db;
- leveldb::Status status = leveldb::DB::Open(options, path_, &db);
- if (status.ok()) {
- db_.reset(db);
- return true;
- }
- HandleError(FROM_HERE, status);
- return false;
+bool FileSystemDirectoryDatabase::Init(bool cleanup_if_corrupted) {
+ if (db_.get())
+ return true;
+
+ leveldb::Options options;
+ options.create_if_missing = true;
+ leveldb::DB* db;
+ leveldb::Status status = leveldb::DB::Open(options, path_, &db);
+ // TODO(tzik): Collect status metrics here.
+ if (status.ok()) {
+ db_.reset(db);
+ return true;
+ }
+ HandleError(FROM_HERE, status);
+
+ if (cleanup_if_corrupted && CheckIfDatabaseCorrupted(status)) {
+ LOG(WARNING) << "FileSystem API directory database is corrupted."
+ << " Attempting cleanup.";
+ if (leveldb::DestroyDB(path_, leveldb::Options()).ok()) {
+ LOG(WARNING) << "FileSystem API directory database cleanup completed."
+ << " Reopening.";
+ return Init(false);
+ }
+ LOG(WARNING) << "Failed to cleanup FileSystem API directory database.";
+ }
+
+ return false;
+}
+
+bool FileSystemDirectoryDatabase::CheckIfDatabaseCorrupted(
jsbell 2012/03/09 23:10:11 What is the benefit in factoring this method out?
tzik 2012/03/10 00:16:55 I'd initially thought, we have many thing to do he
+ const leveldb::Status& status) const {
+ // TODO(tzik): Return status.code() == leveldb::Status::kCorruption, after
+ // leveldb roll.
+ return !status.ok();
}
bool FileSystemDirectoryDatabase::StoreDefaultValues() {
@@ -456,7 +477,7 @@ bool FileSystemDirectoryDatabase::StoreDefaultValues() {
}
bool FileSystemDirectoryDatabase::GetLastFileId(FileId* file_id) {
- if (!Init())
+ if (!Init(true))
return false;
DCHECK(file_id);
std::string id_string;
« no previous file with comments | « webkit/fileapi/file_system_directory_database.h ('k') | webkit/fileapi/file_system_directory_database_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698