Chromium Code Reviews| 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..b5720396446ede028bc352b5993e28e5b95c7b64 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| 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(REBUILD_ON_CORRUPTION)) |
| return false; |
| DCHECK(next); |
| std::string int_string; |
| @@ -413,20 +414,34 @@ 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(RecoveringOption recovering_option) { |
| + 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 (recovering_option == LEAVE_ON_CORRUPTION) |
| + return false; |
| + |
| + DCHECK_EQ(REBUILD_ON_CORRUPTION, recovering_option); |
| + LOG(WARNING) << "FileSystem API directory database is corrupted." |
| + << " Attempting cleanup."; |
| + if (leveldb::DestroyDB(path_, leveldb::Options()).ok()) { |
|
michaeln
2012/03/11 17:40:10
once we've lost the directory structure, have we o
ericu
2012/03/12 19:46:01
Yes. We've lost their paths, and there is no way
|
| + LOG(WARNING) << "FileSystem API directory database cleanup completed." |
| + << " Reopening."; |
| + return Init(LEAVE_ON_CORRUPTION); |
|
jsbell
2012/03/10 00:54:50
What will status metrics (when added) look like if
tzik
2012/03/13 06:40:29
Maybe, we will collect separate metrics with recov
|
| + } |
| + LOG(WARNING) << "Failed to cleanup FileSystem API directory database."; |
| + return false; |
| } |
| bool FileSystemDirectoryDatabase::StoreDefaultValues() { |
| @@ -456,7 +471,7 @@ bool FileSystemDirectoryDatabase::StoreDefaultValues() { |
| } |
| bool FileSystemDirectoryDatabase::GetLastFileId(FileId* file_id) { |
| - if (!Init()) |
| + if (!Init(REBUILD_ON_CORRUPTION)) |
| return false; |
| DCHECK(file_id); |
| std::string id_string; |