]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore/bluestore_types: add blob_t unused
authorSage Weil <sage@redhat.com>
Thu, 19 May 2016 12:43:49 +0000 (08:43 -0400)
committerSage Weil <sage@redhat.com>
Wed, 1 Jun 2016 15:38:51 +0000 (11:38 -0400)
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 <sage@redhat.com>
src/os/bluestore/bluestore_types.cc
src/os/bluestore/bluestore_types.h

index 73682728f2560935d9c3633e899f771bd01de933..d537b9e1b97a8310880e5df163f5089bc66fb977 100644 (file)
@@ -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<bluestore_blob_t*>& ls)
@@ -502,6 +512,8 @@ void bluestore_blob_t::generate_test_instances(list<bluestore_blob_t*>& ls)
   ls.back()->csum_block_order = 16;
   ls.back()->csum_data = vector<char>{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;
 }
index 77648fbdd563ee4f0da9f198f95814b480b691cc..9b54c6b0a39ae09c7a10101f878f954e944dba76 100644 (file)
@@ -253,6 +253,7 @@ struct bluestore_blob_t {
   uint8_t csum_block_order;        ///< csum block size is 1<<block_order bytes
 
   bluestore_extent_ref_map_t ref_map; ///< references (empty when in onode)
+  interval_set<uint32_t> unused;   ///< portion that has never been written to
   vector<char> 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<uint32_t> 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<void(uint64_t,uint64_t)> f) {
     auto p = extents.begin();