]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: add explicit BlueFS space allocation method to BlueStore
authorIgor Fedotov <ifedotov@suse.com>
Fri, 29 Jun 2018 13:37:07 +0000 (16:37 +0300)
committerIgor Fedotov <ifedotov@suse.com>
Tue, 2 Oct 2018 12:07:54 +0000 (15:07 +0300)
Signed-off-by: Igor Fedotov <ifedotov@suse.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h
src/test/objectstore/store_test.cc

index fa1aa01b4238ac7e8394f15759007a8346d7c3f3..280fba4a9175f65bd8a9156ebc71ed657a4a46cd 100644 (file)
@@ -5269,6 +5269,56 @@ void BlueStore::_dump_alloc_on_rebalance_failure()
   }
 }
 
+
+int BlueStore::allocate_bluefs_freespace(uint64_t size)
+{
+  PExtentVector extents;
+
+  if (size) {
+    // round up to alloc size
+    size = p2roundup(size, cct->_conf->bluefs_alloc_size);
+
+    uint64_t gift;
+    do {
+      // hard cap to fit into 32 bits
+      gift = std::min<uint64_t>(size, 1ull << 31);
+      dout(10) << __func__ << " gifting " << gift
+              << " (" << byte_u_t(gift) << ")" << dendl;
+
+      int64_t alloc_len = alloc->allocate(gift, cct->_conf->bluefs_alloc_size,
+                                         0, 0, &extents);
+
+      if (alloc_len < (int64_t)gift) {
+       dout(0) << __func__ << " no allocate on 0x" << std::hex << gift
+               << " min_alloc_size 0x" << cct->_conf->bluefs_alloc_size
+               << std::dec << dendl;
+        alloc->dump();
+        alloc->release(extents);
+       return -ENOSPC;
+      }
+      size -= gift;
+    } while (size);
+    KeyValueDB::Transaction synct = db->get_transaction();
+    for (auto& e : extents) {
+      dout(1) << __func__ << " gifting " << e << " to bluefs" << dendl;
+      bluefs->add_block_extent( bluefs_shared_bdev, e.offset, e.length);
+      bluefs_extents.insert(e.offset, e.length);
+    }
+
+    bufferlist bl;
+
+    encode(bluefs_extents, bl);
+    dout(10) << __func__ << " bluefs_extents now 0x" << std::hex
+             << bluefs_extents << std::dec << dendl;
+    synct->set(PREFIX_SUPER, "bluefs_extents", bl);
+
+    int r = db->submit_transaction_sync(synct);
+    assert(r == 0);
+
+  }
+  return 0;
+}
+
 int BlueStore::_balance_bluefs_freespace(PExtentVector *extents)
 {
   int ret = 0;
@@ -5353,12 +5403,13 @@ int BlueStore::_balance_bluefs_freespace(PExtentVector *extents)
 
     if (alloc_len <= 0) {
       dout(0) << __func__ << " no allocate on 0x" << std::hex << gift
-              << " min_alloc_size 0x" << min_alloc_size << std::dec << dendl;
+              << " min_alloc_size 0x" << cct->_conf->bluefs_alloc_size
+             << std::dec << dendl;
       _dump_alloc_on_rebalance_failure();
       return 0;
     } else if (alloc_len < (int64_t)gift) {
       dout(0) << __func__ << " insufficient allocate on 0x" << std::hex << gift
-              << " min_alloc_size 0x" << min_alloc_size 
+              << " min_alloc_size 0x" << cct->_conf->bluefs_alloc_size
              << " allocated 0x" << alloc_len
              << std::dec << dendl;
       _dump_alloc_on_rebalance_failure();
@@ -6812,7 +6863,7 @@ int BlueStore::_fsck(bool deep, bool repair)
       apply(
         e.get_start(), e.get_len(), fm->get_alloc_size(), used_blocks,
         [&](uint64_t pos, mempool_dynamic_bitset &bs) {
-       ceph_assert(pos < bs.size());
+         ceph_assert(pos < bs.size());
          bs.reset(pos);
         }
       );
index 6c15953dd2da0d4cfcbca678eaaa4f411fe58c7a..098311f32cec3efad1f1e408f015d59abb8fc97d 100644 (file)
@@ -2529,6 +2529,8 @@ public:
     return true;
   }
 
+  int allocate_bluefs_freespace(uint64_t size);
+
 private:
   bool _debug_data_eio(const ghobject_t& o) {
     if (!cct->_conf->bluestore_debug_inject_read_err) {
index 6aef9a49b1c838d64a7ba7eee83106bba7df26dc..98706a1d23e40e211d7b058948a7aa9cd745d279 100644 (file)
@@ -7315,6 +7315,30 @@ TEST_P(StoreTest, SpuriousReadErrorTest) {
   }
 }
 
+TEST_P(StoreTest, allocateBlueFSTest) {
+  if (string(GetParam()) != "bluestore")
+    return;
+
+  BlueStore* bstore = NULL;
+  EXPECT_NO_THROW(bstore = dynamic_cast<BlueStore*> (store.get()));
+
+  struct store_statfs_t statfs;
+  store->statfs(&statfs);
+
+  uint64_t to_alloc = g_conf().get_val<uint64_t>("bluefs_alloc_size");
+
+  int r = bstore->allocate_bluefs_freespace(to_alloc);
+  ASSERT_EQ(r, 0);
+  r = bstore->allocate_bluefs_freespace(statfs.total);
+  ASSERT_EQ(r, -ENOSPC);
+  r = bstore->allocate_bluefs_freespace(to_alloc * 16);
+  ASSERT_EQ(r, 0);
+  store->umount();
+  ASSERT_EQ(store->fsck(false), 0); // do fsck explicitly
+  r = store->mount();
+  ASSERT_EQ(r, 0);
+}
+
 #endif  // WITH_BLUESTORE
 
 int main(int argc, char **argv) {