From f63d207914d082056451453aa3cb017f117f7cf4 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 19 May 2016 08:43:49 -0400 Subject: [PATCH] os/bluestore/bluestore_types: add blob_t unused Keep track of which ranges of this blob have *never* been used. We do this as a negative so that the common case of a fully-written blob is an empty set. Signed-off-by: Sage Weil --- src/os/bluestore/bluestore_types.cc | 14 ++++++++++++++ src/os/bluestore/bluestore_types.h | 22 ++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/os/bluestore/bluestore_types.cc b/src/os/bluestore/bluestore_types.cc index 73682728f2560..d537b9e1b97a8 100644 --- a/src/os/bluestore/bluestore_types.cc +++ b/src/os/bluestore/bluestore_types.cc @@ -456,6 +456,7 @@ void bluestore_blob_t::encode(bufferlist& bl) const ::encode(csum_type, bl); ::encode(csum_block_order, bl); ::encode(ref_map, bl); + ::encode(unused, bl); ::encode(csum_data, bl); ENCODE_FINISH(bl); } @@ -469,6 +470,7 @@ void bluestore_blob_t::decode(bufferlist::iterator& p) ::decode(csum_type, p); ::decode(csum_block_order, p); ::decode(ref_map, p); + ::decode(unused, p); ::decode(csum_data, p); DECODE_FINISH(p); } @@ -490,6 +492,14 @@ void bluestore_blob_t::dump(Formatter *f) const for (unsigned i = 0; i < n; ++i) f->dump_unsigned("csum", get_csum_item(i)); f->close_section(); + f->open_array_section("unused"); + for (auto p = unused.begin(); p != unused.end(); ++p) { + f->open_object_section("range"); + f->dump_unsigned("offset", p.get_start()); + f->dump_unsigned("length", p.get_len()); + f->close_section(); + } + f->close_section(); } void bluestore_blob_t::generate_test_instances(list& ls) @@ -502,6 +512,8 @@ void bluestore_blob_t::generate_test_instances(list& ls) ls.back()->csum_block_order = 16; ls.back()->csum_data = vector{1, 2, 3, 4}; // one uint32_t ls.back()->ref_map.get(3, 5); + ls.back()->add_unused(0, 3); + ls.back()->add_unused(8, 8); } ostream& operator<<(ostream& out, const bluestore_blob_t& o) @@ -518,6 +530,8 @@ ostream& operator<<(ostream& out, const bluestore_blob_t& o) if (!o.ref_map.empty()) { out << " " << o.ref_map; } + if (!o.unused.empty()) + out << " unused=0x" << std::hex << o.unused << std::dec; out << ")"; return out; } diff --git a/src/os/bluestore/bluestore_types.h b/src/os/bluestore/bluestore_types.h index 77648fbdd563e..9b54c6b0a39ae 100644 --- a/src/os/bluestore/bluestore_types.h +++ b/src/os/bluestore/bluestore_types.h @@ -253,6 +253,7 @@ struct bluestore_blob_t { uint8_t csum_block_order; ///< csum block size is 1< unused; ///< portion that has never been written to vector csum_data; ///< opaque vector of csum data bluestore_blob_t(uint32_t l = 0, uint32_t f = 0) @@ -312,6 +313,27 @@ struct bluestore_blob_t { return !ref_map.intersects(offset, length); } + /// return true if the logical range has never been used + bool is_unused(uint64_t offset, uint64_t length) const { + return unused.contains(offset, length); + } + + /// mark a range that has never been used + void add_unused(uint64_t offset, uint64_t length) { + unused.insert(offset, length); + } + + /// indicate that a range has (now) been used. + void mark_used(uint64_t offset, uint64_t length) { + if (unused.empty()) + return; + interval_set t; + t.insert(offset, length); + t.intersection_of(unused); + if (!t.empty()) + unused.subtract(t); + } + void map(uint64_t x_off, uint64_t x_len, std::function f) { auto p = extents.begin(); -- 2.39.5