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)
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);