summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/sync_file_system/drive_backend/drive_backend_util.cc12
-rw-r--r--chrome/browser/sync_file_system/drive_backend/metadata_database.cc26
-rw-r--r--chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc4
-rw-r--r--chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc13
-rw-r--r--chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc9
5 files changed, 52 insertions, 12 deletions
diff --git a/chrome/browser/sync_file_system/drive_backend/drive_backend_util.cc b/chrome/browser/sync_file_system/drive_backend/drive_backend_util.cc
index 031e1d7..d743980 100644
--- a/chrome/browser/sync_file_system/drive_backend/drive_backend_util.cc
+++ b/chrome/browser/sync_file_system/drive_backend/drive_backend_util.cc
@@ -169,12 +169,18 @@ scoped_ptr<ServiceMetadata> InitializeServiceMetadata(LevelDBWrapper* db) {
base::ThreadRestrictions::AssertIOAllowed();
DCHECK(db);
+ scoped_ptr<ServiceMetadata> service_metadata;
+
std::string value;
leveldb::Status status = db->Get(kServiceMetadataKey, &value);
-
- scoped_ptr<ServiceMetadata> service_metadata(new ServiceMetadata);
- if (!status.ok() || !service_metadata->ParseFromString(value))
+ if (status.ok()) {
+ service_metadata.reset(new ServiceMetadata);
+ if (!service_metadata->ParseFromString(value))
+ service_metadata.reset();
+ } else if (status.IsNotFound()) {
+ service_metadata.reset(new ServiceMetadata);
service_metadata->set_next_tracker_id(1);
+ }
return service_metadata.Pass();
}
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
index 5456f52..73aa434 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database.cc
@@ -1424,11 +1424,25 @@ void MetadataDatabase::CreateOnWorkerTaskRunner(
new MetadataDatabase(create_param->worker_task_runner,
create_param->database_path,
create_param->env_override));
+
SyncStatusCode status = metadata_database->Initialize();
+ if (status == SYNC_DATABASE_ERROR_FAILED) {
+ // Delete the previous instance to avoid creating a LevelDB instance for
+ // the same path.
+ metadata_database.reset();
+
+ metadata_database.reset(
+ new MetadataDatabase(create_param->worker_task_runner,
+ create_param->database_path,
+ create_param->env_override));
+ status = metadata_database->Initialize();
+ }
+
if (status != SYNC_STATUS_OK)
metadata_database.reset();
- metadata_database->DetachFromSequence();
+ if (metadata_database)
+ metadata_database->DetachFromSequence();
create_param->worker_task_runner->PostTask(
FROM_HERE,
base::Bind(
@@ -1460,6 +1474,16 @@ SyncStatusCode MetadataDatabase::Initialize() {
} else {
index_ = MetadataDatabaseIndex::Create(db_.get());
}
+ if (!index_) {
+ // Delete all entries in |db_| to reset it.
+ // TODO(peria): Make LevelDBWrapper::DestroyDB() to avoid a full scan.
+ scoped_ptr<LevelDBWrapper::Iterator> itr = db_->NewIterator();
+ for (itr->SeekToFirst(); itr->Valid();)
+ itr->Delete();
+ db_->Commit();
+
+ return SYNC_DATABASE_ERROR_FAILED;
+ }
status = LevelDBStatusToSyncStatusCode(db_->Commit());
if (status != SYNC_STATUS_OK)
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc
index 4e0c10b..90fb183 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index.cc
@@ -204,8 +204,10 @@ MetadataDatabaseIndex::Create(LevelDBWrapper* db) {
DCHECK(db);
scoped_ptr<ServiceMetadata> service_metadata = InitializeServiceMetadata(db);
- DatabaseContents contents;
+ if (!service_metadata)
+ return scoped_ptr<MetadataDatabaseIndex>();
+ DatabaseContents contents;
PutVersionToDB(kCurrentDatabaseVersion, db);
ReadDatabaseContents(db, &contents);
RemoveUnreachableItems(&contents,
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
index 1199a13..51899b8 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_index_on_disk.cc
@@ -144,7 +144,7 @@ std::string GenerateDemotedDirtyIDKey(int64 tracker_id) {
return kDemotedDirtyIDKeyPrefix + base::Int64ToString(tracker_id);
}
-void RemoveUnreachableItems(LevelDBWrapper* db) {
+void RemoveUnreachableItems(LevelDBWrapper* db, int64 sync_root_tracker_id) {
DCHECK(db);
typedef std::map<int64, std::set<int64> > ChildTrackersByParent;
@@ -181,9 +181,6 @@ void RemoveUnreachableItems(LevelDBWrapper* db) {
// Traverse tracker tree from sync-root.
std::set<int64> visited_trackers;
{
- scoped_ptr<ServiceMetadata> service_metadata =
- InitializeServiceMetadata(db);
- int64 sync_root_tracker_id = service_metadata->sync_root_tracker_id();
std::vector<int64> pending;
if (sync_root_tracker_id != kInvalidTrackerID)
pending.push_back(sync_root_tracker_id);
@@ -255,10 +252,12 @@ scoped_ptr<MetadataDatabaseIndexOnDisk>
MetadataDatabaseIndexOnDisk::Create(LevelDBWrapper* db) {
DCHECK(db);
+ scoped_ptr<ServiceMetadata> service_metadata = InitializeServiceMetadata(db);
+ if (!service_metadata)
+ return scoped_ptr<MetadataDatabaseIndexOnDisk>();
+
PutVersionToDB(kDatabaseOnDiskVersion, db);
- // TODO(peria): It is not good to call RemoveUnreachableItems on every
- // creation.
- RemoveUnreachableItems(db);
+ RemoveUnreachableItems(db, service_metadata->sync_root_tracker_id());
scoped_ptr<MetadataDatabaseIndexOnDisk>
index(new MetadataDatabaseIndexOnDisk(db));
diff --git a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
index 733797a..370f93d 100644
--- a/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
+++ b/chrome/browser/sync_file_system/drive_backend/metadata_database_unittest.cc
@@ -641,6 +641,15 @@ TEST_F(MetadataDatabaseTest, InitializationTest_Empty) {
EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
DropDatabase();
EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
+
+ DropDatabase();
+
+ scoped_ptr<LevelDBWrapper> db = InitializeLevelDB();
+ db->Put(kServiceMetadataKey, "Unparsable string");
+ EXPECT_TRUE(db->Commit().ok());
+ db.reset();
+
+ EXPECT_EQ(SYNC_STATUS_OK, InitializeMetadataDatabase());
}
TEST_F(MetadataDatabaseTest, InitializationTest_SimpleTree) {