summaryrefslogtreecommitdiff
path: root/lib
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 /lib
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.
Diffstat (limited to 'lib')
-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