seastore/rbm: add check_bitmap_blocks when open()

This commits adds check_bitmap_blocks to check free_block_count
is correct whenever open() is called

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
This commit is contained in:
myoungwon oh 2021-05-26 16:19:47 +09:00
parent f72ad486ac
commit 6cad63650c
3 changed files with 64 additions and 1 deletions

View File

@ -464,7 +464,9 @@ RandomBlockManager::open(const std::string &path, blk_paddr_t addr)
return crimson::ct_error::enoent::make();
}
super = s;
return open_ertr::now();
return check_bitmap_blocks().safe_then([]() {
return open_ertr::now();
});
}
).handle_error(
open_ertr::pass_further{},
@ -586,6 +588,49 @@ RandomBlockManager::read_rbm_header(blk_paddr_t addr)
);
}
RandomBlockManager::check_bitmap_blocks_ertr::future<>
RandomBlockManager::check_bitmap_blocks()
{
auto bp = bufferptr(ceph::buffer::create_page_aligned(super.block_size));
return seastar::do_with(uint64_t(super.start_alloc_area), uint64_t(0), bp,
[&, this] (auto &addr, auto &free_blocks, auto &bp) mutable {
return crimson::do_until(
[&, this] () mutable {
return device->read(
addr,
bp
).safe_then([&bp, &addr, &free_blocks, this]() mutable {
logger().debug("verify_bitmap_blocks: addr {}", addr);
rbm_bitmap_block_t b_block(super.block_size);
bufferlist bl_bitmap_block;
bl_bitmap_block.append(bp);
decode(b_block, bl_bitmap_block);
auto max = max_block_by_bitmap_block();
for (uint64_t i = 0; i < max; i++) {
if (!b_block.is_allocated(i)) {
free_blocks++;
}
}
addr += super.block_size;
if (addr >= super.start_data_area) {
return find_block_ertr::make_ready_future<bool>(true);
}
return find_block_ertr::make_ready_future<bool>(false);
});
}).safe_then([&free_blocks, this] () {
logger().debug(" free_blocks: {} ", free_blocks);
super.free_block_count = free_blocks;
return check_bitmap_blocks_ertr::now();
}).handle_error(
check_bitmap_blocks_ertr::pass_further{},
crimson::ct_error::assert_all{
"Invalid error in RandomBlockManager::find_free_block"
}
);
});
}
RandomBlockManager::write_ertr::future<>
RandomBlockManager::write(
blk_paddr_t addr,

View File

@ -337,6 +337,13 @@ public:
*/
write_ertr::future<> rbm_sync_block_bitmap(rbm_bitmap_block_t &block, blk_id_t block_no);
using check_bitmap_blocks_ertr = crimson::errorator<
crimson::ct_error::input_output_error,
crimson::ct_error::invarg>;
check_bitmap_blocks_ertr::future<> check_bitmap_blocks();
uint64_t get_free_blocks() {
return super.free_block_count;
}
/*
* We will have mulitple partitions (circularjournals and randbomblockmanagers) on a device,
* so start and end location of the device are needed to support such case.

View File

@ -322,3 +322,14 @@ TEST_F(rbm_test_t, many_block_alloc)
ASSERT_TRUE(check_ids_are_allocated(alloc_ids, false));
});
}
TEST_F(rbm_test_t, check_free_blocks)
{
run_async([this] {
mkfs();
open();
rbm_manager->rbm_sync_block_bitmap_by_range(10, 12, bitmap_op_types_t::ALL_SET).unsafe_get0();
rbm_manager->check_bitmap_blocks().unsafe_get0();
ASSERT_TRUE(rbm_manager->get_free_blocks() == DEFAULT_TEST_SIZE/DEFAULT_BLOCK_SIZE - 5);
});
}