]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
seastore/rbm: add check_bitmap_blocks when open()
authormyoungwon oh <ohmyoungwon@gmail.com>
Wed, 26 May 2021 07:19:47 +0000 (16:19 +0900)
committermyoungwon oh <ohmyoungwon@gmail.com>
Tue, 15 Jun 2021 02:09:06 +0000 (11:09 +0900)
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>
src/crimson/os/seastore/randomblock_manager.cc
src/crimson/os/seastore/randomblock_manager.h
src/test/crimson/seastore/test_randomblock_manager.cc

index 46e140bcd3b9cbaceb40ddeef26d7d70bca9ef90..ae1a6738554e64c1925f961ba91dc916e69ac00d 100644 (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,
index 41112301bff7f6326cb3fe85524c5ba22507016f..7a292aef3c78e44151ace5f85513e9927f87c888 100644 (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.
index 5279f873f1eb67d9c37663bd9e3a93351e5f005b..43ad88ef3a35177ab2891ed4ecbe4c4a740eec06 100644 (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);
+ });
+}