Return success for already finished rollback operations

There was a FIXME and I actually hit it during tests :)
Vitaliy Filippov 2020-10-24 18:46:13 +03:00
parent 720985e4c7
commit 0a174bb313
1 changed files with 20 additions and 12 deletions

View File

@ -9,10 +9,14 @@ int blockstore_impl_t::dequeue_rollback(blockstore_op_t *op)
{ {
return continue_rollback(op); return continue_rollback(op);
} }
obj_ver_id* v; obj_ver_id *v, *nv;
int i, todo = op->len; int i, todo = op->len;
for (i = 0, v = (obj_ver_id*)op->buf; i < op->len; i++, v++) for (i = 0, v = (obj_ver_id*)op->buf, nv = (obj_ver_id*)op->buf; i < op->len; i++, v++, nv++)
{ {
if (nv != v)
{
*nv = *v;
}
// Check that there are some versions greater than v->version (which may be zero), // Check that there are some versions greater than v->version (which may be zero),
// check that they're unstable, synced, and not currently written to // check that they're unstable, synced, and not currently written to
auto dirty_it = dirty_db.lower_bound((obj_ver_id){ auto dirty_it = dirty_db.lower_bound((obj_ver_id){
@ -21,22 +25,18 @@ int blockstore_impl_t::dequeue_rollback(blockstore_op_t *op)
}); });
if (dirty_it == dirty_db.begin()) if (dirty_it == dirty_db.begin())
{ {
if (v->version == 0) skip_ov:
{ // Already rolled back, skip this object version
// Already rolled back todo--;
// FIXME Skip this object version nv--;
} continue;
bad_op:
op->retval = -ENOENT;
FINISH_OP(op);
return 1;
} }
else else
{ {
dirty_it--; dirty_it--;
if (dirty_it->first.oid != v->oid || dirty_it->first.version < v->version) if (dirty_it->first.oid != v->oid || dirty_it->first.version < v->version)
{ {
goto bad_op; goto skip_ov;
} }
while (dirty_it->first.oid == v->oid && dirty_it->first.version > v->version) while (dirty_it->first.oid == v->oid && dirty_it->first.version > v->version)
{ {
@ -60,6 +60,14 @@ int blockstore_impl_t::dequeue_rollback(blockstore_op_t *op)
} }
} }
} }
op->len = todo;
if (!todo)
{
// Already rolled back
op->retval = 0;
FINISH_OP(op);
return 1;
}
// Check journal space // Check journal space
blockstore_journal_check_t space_check(this); blockstore_journal_check_t space_check(this);
if (!space_check.check_available(op, todo, sizeof(journal_entry_rollback), 0)) if (!space_check.check_available(op, todo, sizeof(journal_entry_rollback), 0))