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;
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;
}
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)
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;
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;
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
}
}
+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,
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;
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
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;
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;
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;
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
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*));
};