]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
seastore: make alloc_extent to allocate continuous blocks
authormyoungwon oh <ohmyoungwon@gmail.com>
Thu, 20 May 2021 04:45:33 +0000 (13:45 +0900)
committermyoungwon oh <ohmyoungwon@gmail.com>
Tue, 15 Jun 2021 02:09:06 +0000 (11:09 +0900)
If there is no continous blocks, alloc_extent() returns nospc

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
src/crimson/os/seastore/randomblock_manager.cc
src/crimson/os/seastore/randomblock_manager.h

index 672b7f6f35ed79722fdb3b2edc4d0d84d49ae286..cbaf50b673bbe0037f049813a5cbfb6dd5d92c9d 100644 (file)
@@ -9,6 +9,7 @@
 #include "include/buffer.h"
 #include "randomblock_manager.h"
 #include "crimson/os/seastore/nvmedevice/nvmedevice.h"
+#include "include/interval_set.h"
 
 namespace {
   seastar::logger& logger() {
@@ -160,71 +161,64 @@ RandomBlockManager::find_block_ret
 RandomBlockManager::find_free_block(Transaction &t, size_t size)
 {
   auto bp = bufferptr(ceph::buffer::create_page_aligned(super.block_size));
-  return seastar::do_with(uint64_t(0), uint64_t(super.start_alloc_area),
-         [&, this] (auto &allocated, auto addr) mutable {
+  return seastar::do_with(uint64_t(0), uint64_t(super.start_alloc_area), interval_set<blk_id_t>(), bp,
+         [&, this] (auto &allocated, auto &addr, auto &alloc_extent, auto &bp) mutable {
     return crimson::do_until(
        [&, this] () mutable {
        return device->read(
            addr,
            bp
-           ).safe_then([bp, addr, size, &allocated, &t, this]() mutable {
+           ).safe_then([&bp, &addr, size, &allocated, &t, &alloc_extent, this]() mutable {
              logger().debug("find_free_list: allocate {}, addr {}", allocated, 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();
-             auto prev_alloc_blocks = allocated;
              auto allocated_blocks = t.get_rbm_allocated_blocks();
-             std::vector<blk_id_t> ids;
-             for (uint64_t i = 0; i < max; i++) {
-               bool alloc = false;
+             for (uint64_t i = 0; i < max && (uint64_t)size/super.block_size > allocated; i++) {
+               auto block_id = convert_bitmap_block_no_to_block_id(i, addr);
                for (auto b : allocated_blocks) {
-                 if (std::find(b.blk_ids.begin(), b.blk_ids.end(), convert_bitmap_block_no_to_block_id(i, addr))
-                     != b.blk_ids.end()) {
-                   alloc = true;
-                   break;
+                 if (b.alloc_blk_ids.intersects(block_id, 1)) {
+                   continue;
                  }
                }
-               if (b_block.is_allocated(i) || alloc) {
+               if (b_block.is_allocated(i)) {
                  continue;
                }
-               b_block.set_bit(i);
                logger().debug("find_free_list: allocated block no {} i {}",
                               convert_bitmap_block_no_to_block_id(i, addr), i);
-               ids.push_back(convert_bitmap_block_no_to_block_id(i, addr));
-               allocated += 1;
-               if (((uint64_t)size)/super.block_size <= allocated ||
-                   addr > super.end) {
-                 break;
+               if (allocated != 0 && alloc_extent.range_end() != block_id) {
+                 /*
+                  * if not continous block, just restart to find continuous blocks at the next block.
+                  * in-memory allocator can handle this efficiently.
+                  */
+                 allocated = 0;
+                 alloc_extent.clear(); // a range of block allocation
+                 logger().debug("find_free_list: rety to find continuous blocks");
+                 continue;
                }
+               allocated += 1;
+               alloc_extent.insert(block_id);
              }
-
-             if (allocated - prev_alloc_blocks > 0) {
-               bufferlist bl;
-               encode(b_block, bl);
-               rbm_extent_t extent{
-                 extent_types_t::RBM_ALLOC_INFO,
-                 ids,
-                 addr,
-                 bl
-               };
-               t.add_rbm_allocated_blocks(extent);
-             }
-             if (((uint64_t)size)/super.block_size <= allocated ||
-                 addr > super.end) {
-               logger().debug(" allocated: {} ", allocated);
+             addr += super.block_size;
+             logger().debug("find_free_list: allocated: {} alloc_extent {}", allocated, alloc_extent);
+             if (((uint64_t)size)/super.block_size == allocated) {
+               return find_block_ertr::make_ready_future<bool>(true);
+             } else if (addr >= super.start_data_area) {
+               alloc_extent.clear();
                return find_block_ertr::make_ready_future<bool>(true);
              }
-
-             addr += super.block_size;
              return find_block_ertr::make_ready_future<bool>(false);
              });
-       }).safe_then([&allocated, &t] () {
-         logger().debug(" allocated: {} size {} ", allocated, t.get_rbm_allocated_blocks().size());
+       }).safe_then([&allocated, &alloc_extent, &t, size, this] () {
+         logger().debug(" allocated: {} size {} ", allocated * super.block_size, size);
+         if (allocated * super.block_size < size) {
+           alloc_extent.clear();
+         }
          return find_block_ret(
              find_block_ertr::ready_future_marker{},
-             allocated);
+             alloc_extent);
          }).handle_error(
              find_block_ertr::pass_further{},
              crimson::ct_error::assert_all{
@@ -248,10 +242,17 @@ RandomBlockManager::alloc_extent(Transaction &t, size_t size)
    *
    */
   return find_free_block(t, size
-      ).safe_then([this, &t, size] (auto allocated) mutable -> allocate_ertr::future<> {
-       logger().debug("after find_free_block: allocated {}", allocated);
-       if (allocated * super.block_size < size) {
-         t.clear_rbm_allocated_blocks();
+      ).safe_then([this, &t, size] (auto alloc_extent) mutable -> allocate_ertr::future<> {
+       logger().debug("after find_free_block: allocated {}", alloc_extent);
+       if (!alloc_extent.empty()) {
+         // add alloc info to delta
+         rbm_alloc_delta_t alloc_info {
+           extent_types_t::RBM_ALLOC_INFO,
+           alloc_extent,
+           rbm_alloc_delta_t::op_types_t::SET
+         };
+         t.add_rbm_allocated_blocks(alloc_info);
+       } else {
          return crimson::ct_error::enospc::make();
        }
        return allocate_ertr::now();
index 53cf69b53b8e57e61cb9881fb6b4098891ce8843..dde04a8ae7891e07e5cedb861a762d35df2ebea3 100644 (file)
@@ -288,7 +288,7 @@ public:
   using find_block_ertr = crimson::errorator<
     crimson::ct_error::input_output_error,
     crimson::ct_error::enoent>;
-  using find_block_ret = find_block_ertr::future<uint32_t>;
+  using find_block_ret = find_block_ertr::future<interval_set<blk_id_t>>;
   /*
    * find_free_block
    *