Fix iterate_compaction for the case of unfinished commit/rollback
This commit is contained in:
@@ -1624,9 +1624,9 @@ heap_compact_t blockstore_heap_t::iterate_compaction(heap_entry_t *obj, uint64_t
|
|||||||
res.do_delete = true;
|
res.do_delete = true;
|
||||||
for (heap_entry_t *wr = obj; wr; wr = prev(wr))
|
for (heap_entry_t *wr = obj; wr; wr = prev(wr))
|
||||||
{
|
{
|
||||||
if (wr->type() == BS_HEAP_ROLLBACK)
|
if (wr->type() == BS_HEAP_ROLLBACK && wr->lsn <= fsynced_lsn)
|
||||||
{
|
{
|
||||||
if (wr->lsn <= fsynced_lsn && !res.compact_lsn)
|
if (!res.compact_lsn)
|
||||||
{
|
{
|
||||||
res.compact_lsn = wr->lsn;
|
res.compact_lsn = wr->lsn;
|
||||||
res.compact_version = wr->version;
|
res.compact_version = wr->version;
|
||||||
@@ -1634,9 +1634,9 @@ heap_compact_t blockstore_heap_t::iterate_compaction(heap_entry_t *obj, uint64_t
|
|||||||
rollback_version = wr->version;
|
rollback_version = wr->version;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (wr->type() == BS_HEAP_COMMIT)
|
if (wr->type() == BS_HEAP_COMMIT && wr->lsn <= fsynced_lsn)
|
||||||
{
|
{
|
||||||
if (wr->lsn <= fsynced_lsn && !res.compact_lsn)
|
if (!res.compact_lsn)
|
||||||
{
|
{
|
||||||
res.compact_lsn = wr->lsn;
|
res.compact_lsn = wr->lsn;
|
||||||
res.compact_version = wr->version;
|
res.compact_version = wr->version;
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ int blockstore_impl_t::dequeue_read(blockstore_op_t *op)
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
heap->iterate_with_stable(obj, obj->lsn, [&](heap_entry_t *wr, bool stable)
|
heap->iterate_with_stable(obj, obj->lsn, [&](heap_entry_t *wr, bool stable)
|
||||||
{
|
{
|
||||||
|
if (wr->type() == BS_HEAP_DELETE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (op->version < wr->version)
|
if (op->version < wr->version)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -404,8 +404,8 @@ void osd_t::handle_primary_subop(osd_op_t *subop, osd_op_t *cur_op)
|
|||||||
if (op_data->fact_ver != 0 && op_data->fact_ver != version)
|
if (op_data->fact_ver != 0 && op_data->fact_ver != version)
|
||||||
{
|
{
|
||||||
fprintf(
|
fprintf(
|
||||||
stderr, "different fact_versions returned from %s subops: %ju vs %ju\n",
|
stderr, "different fact_versions returned from %s %jx:%jx subops: %ju vs %ju\n",
|
||||||
osd_op_names[opcode], version, op_data->fact_ver
|
osd_op_names[opcode], subop->req.sec_rw.oid.inode, subop->req.sec_rw.oid.stripe, version, op_data->fact_ver
|
||||||
);
|
);
|
||||||
retval = -ERANGE;
|
retval = -ERANGE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -513,6 +513,40 @@ void test_iterate_compaction()
|
|||||||
assert(small_writes == 4);
|
assert(small_writes == 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
blockstore_heap_t heap(&dsk, buffer_area.data());
|
||||||
|
heap.finish_load();
|
||||||
|
|
||||||
|
// Case: BIG_STABLE(v1 l1) -> SMALL(v2 l2) -> COMMIT(v2 l3) -> SMALL(v3 l4) -> COMMIT(v3 l5) unfinished
|
||||||
|
uint32_t mblock = 0;
|
||||||
|
_test_big_write(heap, dsk, 1, 0, 1, 0, true, 0, 4096, buffer_area.data());
|
||||||
|
_test_small_write(heap, dsk, 1, 0, 2, 0, 4096, 0, false, buffer_area.data(), false);
|
||||||
|
object_id oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0 };
|
||||||
|
auto obj = heap.read_entry(oid);
|
||||||
|
res = heap.add_commit(obj, 2, &mblock);
|
||||||
|
assert(res == 0);
|
||||||
|
heap.start_block_write(mblock);
|
||||||
|
heap.complete_block_write(mblock);
|
||||||
|
|
||||||
|
_test_small_write(heap, dsk, 1, 0, 3, 4*1024, 4096, 4096, false, buffer_area.data(), false);
|
||||||
|
obj = heap.read_entry(oid);
|
||||||
|
res = heap.add_commit(obj, 3, &mblock);
|
||||||
|
assert(res == 0);
|
||||||
|
heap.start_block_write(mblock);
|
||||||
|
|
||||||
|
assert(heap.get_fsynced_lsn() == 4);
|
||||||
|
int small_writes = 0;
|
||||||
|
obj = heap.read_entry(oid);
|
||||||
|
auto compact_info = heap.iterate_compaction(obj, heap.get_fsynced_lsn(), false, [&](heap_entry_t *wr)
|
||||||
|
{
|
||||||
|
small_writes++;
|
||||||
|
});
|
||||||
|
assert(compact_info.compact_lsn == 3);
|
||||||
|
assert(compact_info.compact_version == 2);
|
||||||
|
assert(compact_info.clean_wr->lsn == 1);
|
||||||
|
assert(small_writes == 1);
|
||||||
|
}
|
||||||
|
|
||||||
printf("OK test_iterate_compaction\n");
|
printf("OK test_iterate_compaction\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user