Add a test for redirect_intent

This commit is contained in:
Vitaliy Filippov
2026-02-07 15:09:58 +03:00
parent 2618e559d1
commit 9f8c686321
+129 -1
View File
@@ -1871,8 +1871,135 @@ void test_recalc_stats()
printf("OK test_recalc_stats\n");
}
void test_redirect_intent_csums()
{
blockstore_disk_t dsk;
_test_init(dsk, true /*csum*/);
dsk.disable_journal_fsync = dsk.disable_meta_fsync = false;
std::vector<uint8_t> buffer_area(dsk.journal_device_size);
memset(buffer_area.data(), 0xab, 4096);
memset(buffer_area.data()+4096, 0xac, 4096);
std::vector<uint8_t> tmp;
{
blockstore_heap_t heap(&dsk, buffer_area.data());
heap.finish_load();
_test_big_write(heap, dsk, 1, 0, 1, 0x20000, true, 0, 4096, buffer_area.data());
uint32_t mblock = 999999;
object_id oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0 };
uint8_t ext_bitmap[dsk.clean_entry_bitmap_size];
memset(ext_bitmap, 0x8e, dsk.clean_entry_bitmap_size);
heap_entry_t *obj = heap.read_entry(oid);
int res = heap.add_redirect_intent(oid, &obj, 2, 32768, 4096, 0x40000, ext_bitmap, buffer_area.data()+4096, &mblock);
assert(res == 0);
assert(mblock == 0);
heap.start_block_write(mblock);
heap.complete_block_write(mblock);
// persist
assert(heap.get_meta_block_used_space(0) > 0);
tmp.resize(dsk.meta_block_size);
heap.get_meta_block(0, tmp.data());
}
// reload heap to check that the write is still here
{
blockstore_heap_t heap(&dsk, buffer_area.data(), 10);
uint64_t entries_loaded;
heap.load_blocks(0, dsk.meta_block_size, tmp.data(), false, entries_loaded);
int calls = 0;
bool done = heap.recheck_small_writes([&](bool is_data, uint64_t offset, uint64_t len, uint8_t *buf, std::function<void()> cb)
{
calls++;
if (len)
{
assert(is_data);
assert(offset == 0x40000+32768 && len == 4096);
memcpy(buf, buffer_area.data()+4096, len);
assert(cb);
cb();
}
}, 1);
assert(done);
assert(calls == 2);
heap.finish_load();
auto mod = heap.get_recheck_modified_blocks();
assert(mod.size() == 0);
// read object 1 - big_intent should be there
object_id oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0 };
heap_entry_t *obj = heap.read_entry(oid);
assert(obj);
assert(count_writes(heap, obj) == 2);
assert(obj->lsn == 2);
assert(obj->entry_type == BS_HEAP_BIG_INTENT|BS_HEAP_STABLE);
assert(obj->version == 2);
assert(obj->big_location(&heap) == 0x40000);
// verify csums
uint32_t ref_csums[dsk.data_block_size/4096];
memset(ref_csums, 0, dsk.data_block_size/4096*4);
ref_csums[8] = crc32c(0, buffer_area.data()+4096, 4096);
assert(!memcmp(obj->get_checksums(&heap), ref_csums, dsk.data_block_size/dsk.csum_block_size*4));
// verify bitmap
uint8_t ref_bmp[dsk.clean_entry_bitmap_size];
memset(ref_bmp, 0, dsk.clean_entry_bitmap_size);
bitmap_set(ref_bmp, 32768, 4096, 4096);
assert(!memcmp(obj->get_int_bitmap(&heap), ref_bmp, dsk.clean_entry_bitmap_size));
uint8_t ext_bitmap[dsk.clean_entry_bitmap_size];
memset(ext_bitmap, 0x8e, dsk.clean_entry_bitmap_size);
assert(!memcmp(obj->get_ext_bitmap(&heap), ext_bitmap, dsk.clean_entry_bitmap_size));
}
// reload heap to check that the write is removed if data is invalid
{
blockstore_heap_t heap(&dsk, buffer_area.data(), 10);
uint64_t entries_loaded;
heap.load_blocks(0, dsk.meta_block_size, tmp.data(), false, entries_loaded);
int calls = 0;
bool done = heap.recheck_small_writes([&](bool is_data, uint64_t offset, uint64_t len, uint8_t *buf, std::function<void()> cb)
{
calls++;
if (len)
{
memset(buf, 0xaa, len);
assert(cb);
cb();
}
}, 1);
assert(done);
assert(calls == 2);
heap.finish_load();
auto mod = heap.get_recheck_modified_blocks();
assert(mod.size() == 1);
assert(mod[0] == 0);
// read object 1 - big_intent should be absent
object_id oid = { .inode = INODE_WITH_POOL(1, 1), .stripe = 0 };
heap_entry_t *obj = heap.read_entry(oid);
assert(obj);
assert(count_writes(heap, obj) == 1);
assert(obj->lsn == 1);
assert(obj->entry_type == BS_HEAP_BIG_WRITE|BS_HEAP_STABLE);
assert(obj->version == 1);
assert(obj->big_location(&heap) == 0x20000);
}
printf("OK test_redirect_intent_csums\n");
}
// FIXME: Add a test for big_intent, incl. explicit_complete with big_intent over big_write over deletion over big_write :)
// FIXME: Add a test for redirect_intent
int main(int narg, char *args[])
{
@@ -1909,5 +2036,6 @@ int main(int narg, char *args[])
test_intent_write(false);
test_big_intent_csums();
test_recalc_stats();
test_redirect_intent_csums();
return 0;
}