From: Sage Weil Date: Thu, 29 Sep 2016 15:20:44 +0000 (-0400) Subject: os/bluestore: prune deallocated blob tails X-Git-Tag: v11.0.1~15^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=ed450d681b5570f15edd6924d904d82118a39a7d;p=ceph.git os/bluestore: prune deallocated blob tails This saves us space: no invalid extent, and no unused csum_data. Signed-off-by: Sage Weil --- diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index b166305e9c3d..af80303c0e27 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -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; + } } } diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index a6af3ccdf640..5d8642d898c9 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -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) diff --git a/src/test/objectstore/test_bluestore_types.cc b/src/test/objectstore/test_bluestore_types.cc index 74e3b1ff908c..39f4310cc9e8 100644 --- a/src/test/objectstore/test_bluestore_types.cc +++ b/src/test/objectstore/test_bluestore_types.cc @@ -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);