]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
os/bluestore: duplicate zone refs when cloning
authorSage Weil <sage@newdream.net>
Tue, 7 Sep 2021 21:56:14 +0000 (16:56 -0500)
committerSage Weil <sage@newdream.net>
Fri, 29 Oct 2021 13:55:57 +0000 (09:55 -0400)
When we clone an object, add zone refs pointing to the new object for
any relevant extents.

This is only half of the solution; we will want to make sure the cleaner
is clever enough to keep shared blobs shared when they are relocated.

Signed-off-by: Sage Weil <sage@newdream.net>
src/os/bluestore/BlueStore.cc

index f1269c757b5f17f5c5c77fcebec4a81347c0aa5a..3744a3b9a1ea460449d65abb53cc26244bd4e0bb 100644 (file)
@@ -15781,6 +15781,38 @@ int BlueStore::_do_clone_range(
   _dump_onode<30>(cct, *newo);
 
   oldo->extent_map.dup(this, txc, c, oldo, newo, srcoff, length, dstoff);
+
+#ifdef HAVE_LIBZBD
+  if (bdev->is_smr()) {
+    // duplicate the refs for the shared region.
+    Extent dummy(dstoff);
+    for (auto e = newo->extent_map.extent_map.lower_bound(dummy);
+        e != newo->extent_map.extent_map.end();
+        ++e) {
+      if (e->logical_offset >= dstoff + length) {
+       break;
+      }
+      for (auto& ex : e->blob->get_blob().get_extents()) {
+       // note that we may introduce a new extent reference that is
+       // earlier than the first zone ref.  we allow this since it is
+       // a lot of work to avoid and has marginal impact on cleaning
+       // performance.
+       if (!ex.is_valid()) {
+         continue;
+       }
+       uint32_t zone = ex.offset / zone_size;
+       if (!newo->onode.zone_offset_refs.count(zone)) {
+         uint64_t zoff = ex.offset % zone_size;
+         dout(20) << __func__ << " add ref zone 0x" << std::hex << zone
+                  << " offset 0x" << zoff << std::dec
+                  << " -> " << newo->oid << dendl;
+         txc->note_write_zone_offset(newo, zone, zoff);
+       }
+      }
+    }
+  }
+#endif
+
   _dump_onode<30>(cct, *oldo);
   _dump_onode<30>(cct, *newo);
   return 0;