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

Unified Diff: chrome/browser/chromeos/drive/resource_metadata_storage.cc

Issue 54223003: drive: Recover cache entries from trashed DB to filter out non-dirty cache files (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 2 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: chrome/browser/chromeos/drive/resource_metadata_storage.cc
diff --git a/chrome/browser/chromeos/drive/resource_metadata_storage.cc b/chrome/browser/chromeos/drive/resource_metadata_storage.cc
index 6b2c3030d25479b7fd84d67d7181d9232045da17..213c9ef3e96d7db152a4bdc77da00c3188b58cbd 100644
--- a/chrome/browser/chromeos/drive/resource_metadata_storage.cc
+++ b/chrome/browser/chromeos/drive/resource_metadata_storage.cc
@@ -41,6 +41,10 @@ const base::FilePath::CharType kResourceMapDBName[] =
const base::FilePath::CharType kPreservedResourceMapDBName[] =
FILE_PATH_LITERAL("resource_metadata_preserved_resource_map.db");
+// The name of the DB which couldn't be opened, and was replaced with a new one.
+const base::FilePath::CharType kTrashedResourceMapDBName[] =
+ FILE_PATH_LITERAL("resource_metadata_trashed_resource_map.db");
+
// Meant to be a character which never happen to be in real IDs.
const char kDBKeyDelimeter = '\0';
@@ -137,6 +141,10 @@ ResourceMetadataHeader GetDefaultHeaderEntry() {
return header;
}
+bool MoveIfPossible(const base::FilePath& from, const base::FilePath& to) {
+ return !base::PathExists(from) || base::Move(from, to);
+}
+
} // namespace
ResourceMetadataStorage::Iterator::Iterator(scoped_ptr<leveldb::Iterator> it)
@@ -374,6 +382,15 @@ bool ResourceMetadataStorage::Initialize() {
directory_path_.Append(kResourceMapDBName);
const base::FilePath preserved_resource_map_path =
directory_path_.Append(kPreservedResourceMapDBName);
+ const base::FilePath trashed_resource_map_path =
+ directory_path_.Append(kTrashedResourceMapDBName);
+
+ // Discard unneeded DBs.
+ if (!base::DeleteFile(preserved_resource_map_path, true /* recursive */) ||
+ !base::DeleteFile(trashed_resource_map_path, true /* recursive */)) {
+ LOG(ERROR) << "Failed to remove unneeded DBs.";
+ return false;
+ }
// Try to open the existing DB.
leveldb::DB* db = NULL;
@@ -425,9 +442,7 @@ bool ResourceMetadataStorage::Initialize() {
// Move the existing DB to the preservation path. The moved old DB is
// deleted once the new DB creation succeeds, or is restored later in
// UpgradeOldDB() when the creation fails.
- if (base::PathExists(resource_map_path) &&
- base::DeleteFile(preserved_resource_map_path, true /* recursive */))
- base::Move(resource_map_path, preserved_resource_map_path);
+ MoveIfPossible(resource_map_path, preserved_resource_map_path);
// Create DB.
options.max_open_files = 0; // Use minimum.
@@ -439,8 +454,8 @@ bool ResourceMetadataStorage::Initialize() {
resource_map_.reset(db);
if (!PutHeader(GetDefaultHeaderEntry()) || // Set up header.
- !base::DeleteFile(preserved_resource_map_path,
- true /* recursive */)) { // Remove the old DB.
+ !MoveIfPossible(preserved_resource_map_path, // Trash the old DB.
+ trashed_resource_map_path)) {
init_result = DB_INIT_FAILED;
resource_map_.reset();
}
@@ -456,6 +471,61 @@ bool ResourceMetadataStorage::Initialize() {
return resource_map_;
}
+void ResourceMetadataStorage::RecoverCacheEntriesFromTrashedResourceMap(
+ std::map<std::string, FileCacheEntry>* out_entries) {
+ const base::FilePath trashed_resource_map_path =
+ directory_path_.Append(kTrashedResourceMapDBName);
+
+ if (!base::PathExists(trashed_resource_map_path))
+ return;
+
+ leveldb::Options options;
+ options.max_open_files = 0; // Use minimum.
+ options.create_if_missing = false;
+
+ // Trashed DB may be broken, repair it first.
+ leveldb::Status status;
+ status = leveldb::RepairDB(trashed_resource_map_path.AsUTF8Unsafe(), options);
+ if (!status.ok()) {
+ LOG(ERROR) << "Failed to repair trashed DB: " << status.ToString();
+ return;
+ }
+
+ // Open it.
+ leveldb::DB* db = NULL;
+ status = leveldb::DB::Open(options, trashed_resource_map_path.AsUTF8Unsafe(),
+ &db);
+ if (!status.ok()) {
+ LOG(ERROR) << "Failed to open trashed DB: " << status.ToString();
+ return;
+ }
+ scoped_ptr<leveldb::DB> resource_map(db);
+
+ // Check DB version.
+ std::string serialized_header;
+ ResourceMetadataHeader header;
+ if (!resource_map->Get(leveldb::ReadOptions(),
+ leveldb::Slice(GetHeaderDBKey()),
+ &serialized_header).ok() ||
+ !header.ParseFromString(serialized_header) ||
+ header.version() != kDBVersion) {
+ LOG(ERROR) << "Incompatible DB version: " << header.version();
+ return;
+ }
+
+ // Collect cache entries.
+ scoped_ptr<leveldb::Iterator> it(
+ resource_map->NewIterator(leveldb::ReadOptions()));
+ for (it->SeekToFirst(); it->Valid(); it->Next()) {
+ if (IsCacheEntryKey(it->key())) {
+ const std::string& id = GetIdFromCacheEntryKey(it->key());
+ FileCacheEntry cache_entry;
+ if (cache_entry.ParseFromArray(it->value().data(), it->value().size()))
+ (*out_entries)[id] = cache_entry;
+ }
+ }
+}
+
bool ResourceMetadataStorage::SetLargestChangestamp(
int64 largest_changestamp) {
base::ThreadRestrictions::AssertIOAllowed();

Powered by Google App Engine
This is Rietveld 408576698