Implement blockstore rollback operation
Rollback operation is required for the primary OSD to kill unstable object versions in OSD peers so they don't occupy journal space
This commit is contained in:
+52
-1
@@ -559,7 +559,7 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
||||
if (it == bs->dirty_db.end())
|
||||
{
|
||||
// journal contains a legitimate STABLE entry for a non-existing dirty write
|
||||
// this probably means that journal was trimmed between WRITTEN and STABLE entries
|
||||
// this probably means that journal was trimmed between WRITE and STABLE entries
|
||||
// skip it
|
||||
}
|
||||
else
|
||||
@@ -583,6 +583,57 @@ int blockstore_init_journal::handle_journal_part(void *buf, uint64_t done_pos, u
|
||||
bs->unstable_writes.erase(unstab_it);
|
||||
}
|
||||
}
|
||||
else if (je->type == JE_ROLLBACK)
|
||||
{
|
||||
#ifdef BLOCKSTORE_DEBUG
|
||||
printf("je_rollback oid=%lu:%lu ver=%lu\n", je->rollback.oid.inode, je->rollback.oid.stripe, je->rollback.version);
|
||||
#endif
|
||||
// rollback dirty writes of <oid> up to <version>
|
||||
auto it = bs->dirty_db.lower_bound((obj_ver_id){
|
||||
.oid = je->rollback.oid,
|
||||
.version = UINT64_MAX,
|
||||
});
|
||||
if (it != bs->dirty_db.begin())
|
||||
{
|
||||
uint64_t max_unstable = 0;
|
||||
auto rm_start = it;
|
||||
auto rm_end = it;
|
||||
it--;
|
||||
while (it->first.oid == je->rollback.oid &&
|
||||
it->first.version > je->rollback.version &&
|
||||
!IS_IN_FLIGHT(it->second.state) &&
|
||||
!IS_STABLE(it->second.state))
|
||||
{
|
||||
if (it->first.oid != je->rollback.oid)
|
||||
break;
|
||||
else if (it->first.version <= je->rollback.version)
|
||||
{
|
||||
if (!IS_STABLE(it->second.state))
|
||||
max_unstable = it->first.version;
|
||||
break;
|
||||
}
|
||||
else if (IS_STABLE(it->second.state))
|
||||
break;
|
||||
// Remove entry
|
||||
rm_start = it;
|
||||
if (it == bs->dirty_db.begin())
|
||||
break;
|
||||
it--;
|
||||
}
|
||||
if (rm_start != rm_end)
|
||||
{
|
||||
bs->erase_dirty(rm_start, rm_end, UINT64_MAX);
|
||||
}
|
||||
auto unstab_it = bs->unstable_writes.find(je->rollback.oid);
|
||||
if (unstab_it != bs->unstable_writes.end())
|
||||
{
|
||||
if (max_unstable == 0)
|
||||
bs->unstable_writes.erase(unstab_it);
|
||||
else
|
||||
unstab_it->second = max_unstable;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (je->type == JE_DELETE)
|
||||
{
|
||||
#ifdef BLOCKSTORE_DEBUG
|
||||
|
||||
Reference in New Issue
Block a user