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

Unified Diff: sync/syncable/on_disk_directory_backing_store.cc

Issue 10821121: sync: Attempt to recover from directory corruption (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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: sync/syncable/on_disk_directory_backing_store.cc
diff --git a/sync/syncable/on_disk_directory_backing_store.cc b/sync/syncable/on_disk_directory_backing_store.cc
index 1f43da6ada6744be7eacba8293c0801d12b7c730..10e694fccc996d9309e759fd6f3a1894737f9b6e 100644
--- a/sync/syncable/on_disk_directory_backing_store.cc
+++ b/sync/syncable/on_disk_directory_backing_store.cc
@@ -5,19 +5,33 @@
#include "sync/syncable/on_disk_directory_backing_store.h"
#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "sync/syncable/syncable-inl.h"
namespace syncer {
namespace syncable {
+namespace {
+
+enum HistogramResultEnum {
+ FIRST_TRY_SUCCESS,
+ SECOND_TRY_SUCCESS,
+ SECOND_TRY_FAILURE,
+ RESULT_COUNT
+};
+
+} // namespace
+
OnDiskDirectoryBackingStore::OnDiskDirectoryBackingStore(
const std::string& dir_name, const FilePath& backing_filepath)
: DirectoryBackingStore(dir_name),
+ allow_failure_for_test_(false),
backing_filepath_(backing_filepath) {
db_->set_exclusive_locking();
db_->set_page_size(4096);
}
-DirOpenResult OnDiskDirectoryBackingStore::Load(
+DirOpenResult OnDiskDirectoryBackingStore::TryLoad(
MetahandlesIndex* entry_bucket,
Directory::KernelLoadInfo* kernel_load_info) {
DCHECK(CalledOnValidThread());
@@ -35,8 +49,50 @@ DirOpenResult OnDiskDirectoryBackingStore::Load(
return FAILED_DATABASE_CORRUPT;
if (!LoadInfo(kernel_load_info))
return FAILED_DATABASE_CORRUPT;
+ if (!VerifyReferenceIntegrity(*entry_bucket))
+ return FAILED_DATABASE_CORRUPT;
return OPENED;
+
+}
+
+DirOpenResult OnDiskDirectoryBackingStore::Load(
+ MetahandlesIndex* entry_bucket,
+ Directory::KernelLoadInfo* kernel_load_info) {
+ DirOpenResult result = TryLoad(entry_bucket, kernel_load_info);
+ if (result == OPENED) {
+ HISTOGRAM_ENUMERATION(
+ "Sync.DirectoryOpenResult", FIRST_TRY_SUCCESS, RESULT_COUNT);
+ return OPENED;
+ }
+
+ // In debug builds, the last thing we want is to silently clear the database.
+ // It's full of evidence that might help us determine what went wrong. It
+ // might be sqlite's fault, but it could also be a bug in sync. We crash
+ // immediately so a developer can investigate.
tim (not reviewing) 2012/08/01 21:31:59 Let's keep an eye on this. I've seen similar dche
rlarocque 2012/08/01 22:37:51 I've updated the comment with instructions on how
+ if (!allow_failure_for_test_)
+ NOTREACHED() << "Crashing to preserve corrupt sync database";
+
+ // The fallback: delete the current database and return a fresh one. We can
+ // fetch the user's data from the could.
+ entry_bucket->clear();
+ db_.reset(new sql::Connection);
tim (not reviewing) 2012/08/01 21:31:59 A bit nervous to swap this out since we set it in
+ file_util::Delete(backing_filepath_, false);
+
+ result = TryLoad(entry_bucket, kernel_load_info);
+ if (result == OPENED) {
+ HISTOGRAM_ENUMERATION(
+ "Sync.DirectoryOpenResult", SECOND_TRY_SUCCESS, RESULT_COUNT);
+ } else {
+ HISTOGRAM_ENUMERATION(
+ "Sync.DirectoryOpenResult", SECOND_TRY_FAILURE, RESULT_COUNT);
+ }
+
+ return result;
+}
+
+void OnDiskDirectoryBackingStore::AllowFailureForTest() {
tim (not reviewing) 2012/08/01 21:31:59 I think it would be clearer / preferable to have a
rlarocque 2012/08/01 21:53:50 Yet another implementation of DirectoryBackingStor
+ allow_failure_for_test_ = true;
}
} // namespace syncable

Powered by Google App Engine
This is Rietveld 408576698