]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
librbd: new hook for pre-processing copyup data
authorJason Dillaman <dillaman@redhat.com>
Wed, 23 Sep 2020 19:57:20 +0000 (15:57 -0400)
committerJason Dillaman <dillaman@redhat.com>
Tue, 13 Oct 2020 12:40:29 +0000 (08:40 -0400)
This will permit the crypto layer to properly encrypt and potentially
align the sparse copyup data prior to it being written. It passes
potentially multiple sets of data in one pass to permit the deep-copy
state machine to utilize the same API and allow the crypto layer to
potentially handle layered alignment issues.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
14 files changed:
src/librbd/cache/ObjectCacherObjectDispatch.h
src/librbd/cache/ParentCacheObjectDispatch.h
src/librbd/cache/WriteAroundObjectDispatch.h
src/librbd/crypto/CryptoObjectDispatch.h
src/librbd/io/ObjectDispatch.h
src/librbd/io/ObjectDispatchInterface.h
src/librbd/io/ObjectDispatcher.cc
src/librbd/io/ObjectDispatcher.h
src/librbd/io/ObjectDispatcherInterface.h
src/librbd/io/SimpleSchedulerObjectDispatch.h
src/librbd/io/Types.h
src/librbd/journal/ObjectDispatch.h
src/test/librbd/mock/io/MockObjectDispatch.h
src/test/librbd/mock/io/MockObjectDispatcher.h

index ab0561cfdd35764759ea353d1c15c59282e01e1f..5762c6914397b60f39f033ee752d363a364f18db 100644 (file)
@@ -101,6 +101,11 @@ public:
       uint64_t journal_tid, uint64_t new_journal_tid) {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
   struct C_InvalidateCache;
 
index 6fbe44a447e78c16542fd8b80d03b979881ad18b..6d9c90828c0808b7b3d5e10f3b6a4453943203ad 100644 (file)
@@ -118,6 +118,11 @@ public:
       uint64_t journal_tid, uint64_t new_journal_tid) {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
   ImageCtxT* get_image_ctx() {
     return m_image_ctx;
   }
index 53bb902e74025dd0714a348a8472c7ef046219e1..b91ab979e1ea05636201699ab9d948cd9f11cbe8 100644 (file)
@@ -106,6 +106,11 @@ public:
       uint64_t journal_tid, uint64_t new_journal_tid) override {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
   struct QueuedIO {
     QueuedIO(uint64_t length, Context* on_finish, Context* on_dispatched)
index aad11af641a856d4e8f1c2e7c0921f22f94b0d85..661142b0716e89e7e6bd46f55424adbdf3e9240b 100644 (file)
@@ -97,6 +97,11 @@ public:
           uint64_t journal_tid, uint64_t new_journal_tid) override {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
 
   ImageCtxT* m_image_ctx;
index a45bb9a0ff320b39294978b431cbc7efc9782d36..e66fba134fdc04c2ad2f22720bd57b6aee48d621 100644 (file)
@@ -96,6 +96,11 @@ public:
       uint64_t journal_tid, uint64_t new_journal_tid) override {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
   ImageCtxT* m_image_ctx;
 
index c61dc533ad64b7b0b89eb18753b6c652765ccb97..1cd72dd1b9b149824d53572d2a1316da630ed41f 100644 (file)
@@ -90,6 +90,10 @@ struct ObjectDispatchInterface {
       uint64_t object_no, uint64_t object_off, uint64_t object_len,
       uint64_t journal_tid, uint64_t new_journal_tid) = 0;
 
+  virtual void prepare_copyup(
+      uint64_t object_no,
+      SnapshotSparseBufferlist* snapshot_sparse_bufferlist) = 0;
+
 };
 
 } // namespace io
index 52500275c08564884e457080872136d29b6d9237..16cc1722f0c37f7b26c163489c7775e40c835169 100644 (file)
@@ -233,6 +233,21 @@ void ObjectDispatcher<I>::extent_overwritten(
   }
 }
 
+template <typename I>
+void ObjectDispatcher<I>::prepare_copyup(
+    uint64_t object_no,
+    SnapshotSparseBufferlist* snapshot_sparse_bufferlist) {
+  auto cct = this->m_image_ctx->cct;
+  ldout(cct, 20) << "object_no=" << object_no << dendl;
+
+  std::shared_lock locker{this->m_lock};
+  for (auto it : this->m_dispatches) {
+    auto& object_dispatch_meta = it.second;
+    auto object_dispatch = object_dispatch_meta.dispatch;
+    object_dispatch->prepare_copyup(object_no, snapshot_sparse_bufferlist);
+  }
+}
+
 template <typename I>
 bool ObjectDispatcher<I>::send_dispatch(
     ObjectDispatchInterface* object_dispatch,
index 0f8317fb437bd423af68d61d3068d6faf4aad68f..2cb5904de8e1a2b402f3b4b785a00a3a9412c352 100644 (file)
@@ -34,6 +34,10 @@ public:
       uint64_t object_no, uint64_t object_off, uint64_t object_len,
       uint64_t journal_tid, uint64_t new_journal_tid) override;
 
+  void prepare_copyup(
+      uint64_t object_no,
+      SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override;
+
 protected:
   bool send_dispatch(ObjectDispatchInterface* object_dispatch,
                      ObjectDispatchSpec* object_dispatch_spec) override;
index 0b2befd3dd691c5a5f85c9e8d5dbbd508f0cb0ac..b9f9197c02a4b4d736b80f387f242192e138fb7f 100644 (file)
@@ -22,6 +22,11 @@ public:
   virtual void extent_overwritten(
       uint64_t object_no, uint64_t object_off, uint64_t object_len,
       uint64_t journal_tid, uint64_t new_journal_tid) = 0;
+
+  virtual void prepare_copyup(
+      uint64_t object_no,
+      SnapshotSparseBufferlist* snapshot_sparse_bufferlist) = 0;
+
 };
 
 } // namespace io
index d68cda3ef28000813520093df5ddff0c99818f64..ea125082d1d332fcb033adda901e8f35aef86a83 100644 (file)
@@ -112,6 +112,11 @@ public:
       uint64_t journal_tid, uint64_t new_journal_tid) override {
   }
 
+  void prepare_copyup(
+      uint64_t object_no,
+      SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
   struct MergedRequests {
     ceph::bufferlist data;
index b4e9f14d1e333f406c81195233d7c236700ff814..a41d1e9f23749c1cf54d4e97d7ba0cf8ae9536ff 100644 (file)
@@ -189,6 +189,63 @@ extern const WriteReadSnapIds INITIAL_WRITE_READ_SNAP_IDS;
 
 typedef std::map<WriteReadSnapIds, SparseExtents> SnapshotDelta;
 
+struct SparseBufferlistExtent : public SparseExtent {
+  ceph::bufferlist bl;
+
+  SparseBufferlistExtent(SparseExtentState state, size_t length)
+    : SparseExtent(state, length) {
+    ceph_assert(state != SPARSE_EXTENT_STATE_DATA);
+  }
+  SparseBufferlistExtent(SparseExtentState state, size_t length,
+                         ceph::bufferlist&& bl_)
+    : SparseExtent(state, length), bl(std::move(bl_)) {
+    ceph_assert(state != SPARSE_EXTENT_STATE_DATA || length == bl.length());
+  }
+
+  bool operator==(const SparseBufferlistExtent& rhs) const {
+    return (state == rhs.state &&
+            length == rhs.length &&
+            bl.contents_equal(rhs.bl));
+  }
+};
+
+struct SparseBufferlistExtentSplitMerge {
+  SparseBufferlistExtent split(uint64_t offset, uint64_t length,
+                               SparseBufferlistExtent& sbe) const {
+    ceph::bufferlist bl;
+    if (sbe.state == SPARSE_EXTENT_STATE_DATA) {
+      bl.substr_of(bl, offset, length);
+    }
+    return SparseBufferlistExtent(sbe.state, length, std::move(bl));
+  }
+
+  bool can_merge(const SparseBufferlistExtent& left,
+                 const SparseBufferlistExtent& right) const {
+    return left.state == right.state;
+  }
+
+  SparseBufferlistExtent merge(SparseBufferlistExtent&& left,
+                               SparseBufferlistExtent&& right) const {
+    if (left.state == SPARSE_EXTENT_STATE_DATA) {
+      ceph::bufferlist bl{std::move(left.bl)};
+      bl.claim_append(std::move(right.bl));
+      return SparseBufferlistExtent(SPARSE_EXTENT_STATE_DATA,
+                                    bl.length(), std::move(bl));
+    } else {
+      return SparseBufferlistExtent(left.state, left.length + right.length, {});
+    }
+  }
+
+  uint64_t length(const SparseBufferlistExtent& sbe) const {
+    return sbe.length;
+  }
+};
+
+typedef interval_map<uint64_t,
+                     SparseBufferlistExtent,
+                     SparseBufferlistExtentSplitMerge> SparseBufferlist;
+typedef std::map<uint64_t, SparseBufferlist> SnapshotSparseBufferlist;
+
 using striper::LightweightBufferExtents;
 using striper::LightweightObjectExtent;
 using striper::LightweightObjectExtents;
index 006f323d40b7282e17d27ea65e17a4f09521f80f..18967a33aa4984959523395b31eb19570f1e2ca5 100644 (file)
@@ -101,6 +101,11 @@ public:
       uint64_t object_no, uint64_t object_off, uint64_t object_len,
       uint64_t journal_tid, uint64_t new_journal_tid) override;
 
+  void prepare_copyup(
+      uint64_t object_no,
+      io::SnapshotSparseBufferlist* snapshot_sparse_bufferlist) override {
+  }
+
 private:
   ImageCtxT* m_image_ctx;
   Journal<ImageCtxT>* m_journal;
index fd0a5ac78c527ef2dec96648c7138659bf7390d0..262e76bde337b18dde54e1db16147d90ff1e1eb8 100644 (file)
@@ -128,6 +128,7 @@ public:
 
   MOCK_METHOD5(extent_overwritten, void(uint64_t, uint64_t, uint64_t, uint64_t,
                                         uint64_t));
+  MOCK_METHOD2(prepare_copyup, void(uint64_t, SnapshotSparseBufferlist*));
 };
 
 } // namespace io
index 908e2186816daccf93cb0d1a8936a9ea802d96d5..0c3fc2c2c4ad84aa70baf7461b896ec15d6d8ad1 100644 (file)
@@ -32,6 +32,8 @@ public:
   MOCK_METHOD5(extent_overwritten, void(uint64_t, uint64_t, uint64_t, uint64_t,
                                         uint64_t));
 
+  MOCK_METHOD2(prepare_copyup, void(uint64_t, SnapshotSparseBufferlist*));
+
   MOCK_METHOD1(send, void(ObjectDispatchSpec*));
 };