summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2014-03-02 09:01:01 +0000
committerChris Wilson <chris+github@qwirx.com>2014-03-02 09:01:01 +0000
commit4b57c48df150b4eb440078bd85a28c046dee8c63 (patch)
tree4deb395681f7ec1aacb82ef5e988134adf065afc
parent15677eb9461ef9f868d0cb56b1b7fb2c8601d377 (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.
-rw-r--r--lib/backupstore/HousekeepStoreAccount.cpp26
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