mirror of
https://github.com/ceph/ceph
synced 2025-01-29 14:34:40 +00:00
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:
parent
f72ad486ac
commit
6cad63650c
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user