diff options
author | Chris Wilson <chris+github@qwirx.com> | 2014-03-02 09:01:01 +0000 |
---|---|---|
committer | Chris Wilson <chris+github@qwirx.com> | 2014-03-02 09:01:01 +0000 |
commit | 4b57c48df150b4eb440078bd85a28c046dee8c63 (patch) | |
tree | 4deb395681f7ec1aacb82ef5e988134adf065afc /lib | |
parent | 15677eb9461ef9f868d0cb56b1b7fb2c8601d377 (diff) |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/backupstore/HousekeepStoreAccount.cpp | 26 |
1 files changed, 14 insertions, 12 deletions
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<BackupStoreRefCountDatabase> 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 |