From 4b57c48df150b4eb440078bd85a28c046dee8c63 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 2 Mar 2014 09:01:01 +0000 Subject: Fix an exception checking refcounts in housekeeping. If the old refcount database was shorter than the new one, then we could end up trying to access a nonexistent refcount, triggering an exception, which prevented all comparison of the old and new refcount databases. Also, from now on, a mismatch between old and new refcounts is treated as a housekeeping error, which is detectable in tests. --- lib/backupstore/HousekeepStoreAccount.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'lib/backupstore') diff --git a/lib/backupstore/HousekeepStoreAccount.cpp b/lib/backupstore/HousekeepStoreAccount.cpp index 75e7c8ca..0bcc6a44 100644 --- a/lib/backupstore/HousekeepStoreAccount.cpp +++ b/lib/backupstore/HousekeepStoreAccount.cpp @@ -210,24 +210,25 @@ bool HousekeepStoreAccount::DoHousekeeping(bool KeepTryingForever) std::auto_ptr apOldRefs = BackupStoreRefCountDatabase::Load(account, false); - int64_t LastUsedObjectIdOnDisk = mapNewRefs->GetLastObjectIDUsed(); - - if (apOldRefs->GetLastObjectIDUsed() > LastUsedObjectIdOnDisk) - { - LastUsedObjectIdOnDisk = apOldRefs->GetLastObjectIDUsed(); - } + int64_t MaxOldObjectId = apOldRefs->GetLastObjectIDUsed(); + int64_t MaxNewObjectId = mapNewRefs->GetLastObjectIDUsed(); for (int64_t ObjectID = BACKUPSTORE_ROOT_DIRECTORY_ID; - ObjectID < LastUsedObjectIdOnDisk; ObjectID++) + ObjectID < std::max(MaxOldObjectId, MaxNewObjectId); + ObjectID++) { - if (apOldRefs->GetRefCount(ObjectID) != - mapNewRefs->GetRefCount(ObjectID)) + typedef BackupStoreRefCountDatabase::refcount_t refcount_t; + refcount_t OldRefs = (ObjectID <= MaxOldObjectId) ? + apOldRefs->GetRefCount(ObjectID) : 0; + refcount_t NewRefs = (ObjectID <= MaxNewObjectId) ? + mapNewRefs->GetRefCount(ObjectID) : 0; + + if (OldRefs != NewRefs) { BOX_WARNING("Reference count of object " << BOX_FORMAT_OBJECTID(ObjectID) << - " changed from " << - apOldRefs->GetRefCount(ObjectID) << - " to " << mapNewRefs->GetRefCount(ObjectID)); + " changed from " << OldRefs << + " to " << NewRefs); mErrorCount++; } } @@ -237,6 +238,7 @@ bool HousekeepStoreAccount::DoHousekeeping(bool KeepTryingForever) BOX_WARNING("Reference count database was missing or " "corrupted during housekeeping, cannot check it for " "errors."); + mErrorCount++; } // Go and delete items from the accounts -- cgit v1.2.3