]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore: prune deallocated blob tails
authorSage Weil <sage@redhat.com>
Thu, 29 Sep 2016 15:20:44 +0000 (11:20 -0400)
committerSage Weil <sage@redhat.com>
Tue, 4 Oct 2016 13:37:00 +0000 (09:37 -0400)
This saves us space: no invalid extent, and no unused csum_data.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc
src/os/bluestore/bluestore_types.h
src/test/objectstore/test_bluestore_types.cc

index b166305e9c3d3c4925aaf4d92100efe9ffe5ec3f..af80303c0e27bb246a4df3d9c1797cca6244f0f8 100644 (file)
@@ -1294,6 +1294,11 @@ void BlueStore::Blob::discard_unallocated()
       }
       pos += e.length;
     }
+    if (blob.can_prune_tail()) {
+      dirty_blob();
+      blob.prune_tail();
+      dout(20) << __func__ << " pruned tail, now " << blob << dendl;
+    }
   }
 }
 
index a6af3ccdf64095c821437a275e1608e3f8d126c9..5d8642d898c9e178ac0d1529dbb28f916ab3c400 100644 (file)
@@ -579,6 +579,22 @@ struct bluestore_blob_t {
   int verify_csum(uint64_t b_off, const bufferlist& bl, int* b_bad_off,
                  uint64_t *bad_csum) const;
 
+  bool can_prune_tail() const {
+    return
+      extents.size() > 1 &&  // if it's all invalid it's not pruning.
+      !extents.back().is_valid() &&
+      !has_unused();
+  }
+  void prune_tail() {
+    extents.pop_back();
+    if (has_csum()) {
+      bufferptr t;
+      t.swap(csum_data);
+      csum_data = bufferptr(t.c_str(),
+                           get_logical_length() / get_csum_chunk_size() *
+                           get_csum_value_size());
+    }
+  }
 };
 WRITE_CLASS_ENCODER(bluestore_blob_t)
 
index 74e3b1ff908cb6cf1162aeddacb3bfb0086f8cf7..39f4310cc9e82d0b845870c1e6bf7e2d05a01fbf 100644 (file)
@@ -695,6 +695,38 @@ TEST(bluestore_blob_t, can_split_at)
   ASSERT_FALSE(a.can_split_at(0x2800));
 }
 
+TEST(bluestore_blob_t, prune_tail)
+{
+  bluestore_blob_t a;
+  a.flags = bluestore_blob_t::FLAG_MUTABLE;
+  a.extents.emplace_back(bluestore_pextent_t(0x10000, 0x2000));
+  a.extents.emplace_back(bluestore_pextent_t(0x20000, 0x2000));
+  ASSERT_FALSE(a.can_prune_tail());
+  a.extents.emplace_back(
+    bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  ASSERT_TRUE(a.can_prune_tail());
+  a.prune_tail();
+  ASSERT_FALSE(a.can_prune_tail());
+  ASSERT_EQ(2u, a.extents.size());
+  ASSERT_EQ(0x4000u, a.get_logical_length());
+
+  a.extents.emplace_back(
+    bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  a.init_csum(bluestore_blob_t::CSUM_CRC32C_8, 12, 0x6000);
+  ASSERT_EQ(6u, a.csum_data.length());
+  ASSERT_TRUE(a.can_prune_tail());
+  a.prune_tail();
+  ASSERT_FALSE(a.can_prune_tail());
+  ASSERT_EQ(2u, a.extents.size());
+  ASSERT_EQ(0x4000u, a.get_logical_length());
+  ASSERT_EQ(4u, a.csum_data.length());
+
+  bluestore_blob_t b;
+  b.extents.emplace_back(
+    bluestore_pextent_t(bluestore_pextent_t::INVALID_OFFSET, 0x2000));
+  ASSERT_FALSE(a.can_prune_tail());
+}
+
 TEST(Blob, split)
 {
   BlueStore::Cache *cache = BlueStore::Cache::create("lru", NULL);