io/ImageDispatchSpec.cc
io/ImageRequest.cc
io/ImageRequestWQ.cc
+ io/ObjectDispatchSpec.cc
+ io/ObjectDispatcher.cc
io/ObjectRequest.cc
io/ReadResult.cc
io/Utils.cc
#include "librbd/io/AioCompletion.h"
#include "librbd/io/AsyncOperation.h"
#include "librbd/io/ImageRequestWQ.h"
+#include "librbd/io/ObjectDispatcher.h"
#include "librbd/journal/StandardPolicy.h"
#include "osdc/Striper.h"
this, "librbd::io_work_queue",
cct->_conf->get_val<int64_t>("rbd_op_thread_timeout"),
thread_pool);
+ io_object_dispatcher = new io::ObjectDispatcher<>(this);
if (cct->_conf->get_val<bool>("rbd_auto_exclusive_lock_until_manual_request")) {
exclusive_lock_policy = new exclusive_lock::AutomaticPolicy(this);
data_ctx.aio_flush();
io_work_queue->drain();
+ delete io_object_dispatcher;
+
delete journal_policy;
delete exclusive_lock_policy;
delete io_work_queue;
class AsyncOperation;
template <typename> class CopyupRequest;
template <typename> class ImageRequestWQ;
+ template <typename> class ObjectDispatcher;
}
namespace journal { struct Policy; }
xlist<operation::ResizeRequest<ImageCtx>*> resize_reqs;
io::ImageRequestWQ<ImageCtx> *io_work_queue;
+ io::ObjectDispatcher<ImageCtx> *io_object_dispatcher = nullptr;
+
xlist<io::AioCompletion*> completed_reqs;
EventSocket event_socket;
#include "librbd/ExclusiveLock.h"
#include "librbd/ImageCtx.h"
#include "librbd/io/ImageRequestWQ.h"
-#include "librbd/io/ObjectRequest.h"
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/ObjectDispatcher.h"
#include "librbd/journal/CreateRequest.h"
#include "librbd/journal/DemoteRequest.h"
#include "librbd/journal/OpenRequest.h"
ldout(cct, 20) << this << " " << __func__ << ": "
<< "completing tid=" << tid << dendl;
- for (IOObjectRequests::iterator it = aio_object_requests.begin();
- it != aio_object_requests.end(); ++it) {
+ for (auto it = aio_object_requests.begin(); it != aio_object_requests.end();
+ ++it) {
if (r < 0) {
// don't send aio requests if the journal fails -- bubble error up
(*it)->fail(r);
} else {
// send any waiting aio requests now that journal entry is safe
- (*it)->send();
+ (*it)->send(tid);
}
}
class ImageCtx;
-namespace io { struct ObjectRequestHandle; }
+namespace io { struct ObjectDispatchSpec; }
namespace journal { template <typename> class Replay; }
template <typename ImageCtxT = ImageCtx>
static const std::string LOCAL_MIRROR_UUID;
static const std::string ORPHAN_MIRROR_UUID;
- typedef std::list<io::ObjectRequestHandle *> IOObjectRequests;
+ typedef std::list<io::ObjectDispatchSpec*> IOObjectRequests;
Journal(ImageCtxT &image_ctx);
~Journal();
#include "librbd/cache/ImageCache.h"
#include "librbd/io/AioCompletion.h"
#include "librbd/io/ObjectRequest.h"
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/ObjectDispatcher.h"
#include "librbd/io/Utils.h"
#include "librbd/journal/Types.h"
#include "include/rados/librados.hpp"
auto req_comp = new io::ReadResult::C_ObjectReadRequest(
aio_comp, extent.offset, extent.length,
std::move(extent.buffer_extents), true);
- ObjectReadRequest<I> *req = ObjectReadRequest<I>::create(
+ auto req = ObjectReadRequest<I>::create(
&image_ctx, extent.oid.name, extent.objectno, extent.offset,
extent.length, snap_id, m_op_flags, false, this->m_trace,
&req_comp->bl, &req_comp->extent_map, req_comp);
ldout(cct, 20) << "oid " << p->oid << " " << p->offset << "~" << p->length
<< " from " << p->buffer_extents << dendl;
C_AioRequest *req_comp = new C_AioRequest(aio_comp);
- ObjectRequestHandle *request = create_object_request(*p, snapc,
- req_comp);
+ auto request = create_object_request(*p, snapc, req_comp);
// if journaling, stash the request for later; otherwise send
if (request != NULL) {
if (object_requests != NULL) {
object_requests->push_back(request);
} else {
- request->send();
+ request->send(0);
}
}
}
}
template <typename I>
-ObjectRequestHandle *ImageWriteRequest<I>::create_object_request(
+ObjectDispatchSpec *ImageWriteRequest<I>::create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) {
I &image_ctx = this->m_image_ctx;
bufferlist bl;
assemble_extent(object_extent, &bl);
- ObjectRequest<I> *req = ObjectRequest<I>::create_write(
- &image_ctx, object_extent.oid.name, object_extent.objectno,
- object_extent.offset, std::move(bl), snapc, m_op_flags, this->m_trace,
- on_finish);
+ auto req = ObjectDispatchSpec::create_write(
+ &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.oid.name,
+ object_extent.objectno, object_extent.offset, std::move(bl), snapc,
+ m_op_flags, 0, this->m_trace, on_finish);
return req;
}
}
template <typename I>
-ObjectRequestHandle *ImageDiscardRequest<I>::create_object_request(
+ObjectDispatchSpec *ImageDiscardRequest<I>::create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) {
I &image_ctx = this->m_image_ctx;
-
- auto req = ObjectRequest<I>::create_discard(
- &image_ctx, object_extent.oid.name, object_extent.objectno,
- object_extent.offset, object_extent.length, snapc, true, true,
- this->m_trace, on_finish);
+ auto req = ObjectDispatchSpec::create_discard(
+ &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.oid.name,
+ object_extent.objectno, object_extent.offset, object_extent.length, snapc,
+ 0, 0, this->m_trace, on_finish);
return req;
}
}
template <typename I>
-ObjectRequestHandle *ImageWriteSameRequest<I>::create_object_request(
+ObjectDispatchSpec *ImageWriteSameRequest<I>::create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) {
I &image_ctx = this->m_image_ctx;
assert(image_ctx.object_cacher == NULL);
bufferlist bl;
- ObjectRequest<I> *req;
+ ObjectDispatchSpec *req;
if (util::assemble_write_same_extent(object_extent, m_data_bl, &bl, false)) {
- req = ObjectRequest<I>::create_writesame(
- &image_ctx, object_extent.oid.name, object_extent.objectno,
- object_extent.offset, object_extent.length,
- std::move(bl), snapc, m_op_flags, this->m_trace, on_finish);
+ Extents buffer_extents{object_extent.buffer_extents};
+
+ req = ObjectDispatchSpec::create_write_same(
+ &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.oid.name,
+ object_extent.objectno, object_extent.offset, object_extent.length,
+ std::move(buffer_extents), std::move(bl), snapc, m_op_flags, 0,
+ this->m_trace, on_finish);
return req;
}
- req = ObjectRequest<I>::create_write(
- &image_ctx, object_extent.oid.name, object_extent.objectno,
- object_extent.offset, std::move(bl), snapc, m_op_flags, this->m_trace,
- on_finish);
+ req = ObjectDispatchSpec::create_write(
+ &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.oid.name,
+ object_extent.objectno, object_extent.offset, std::move(bl), snapc,
+ m_op_flags, 0, this->m_trace, on_finish);
return req;
}
}
template <typename I>
-ObjectRequestHandle *ImageCompareAndWriteRequest<I>::create_object_request(
+ObjectDispatchSpec *ImageCompareAndWriteRequest<I>::create_object_request(
const ObjectExtent &object_extent,
const ::SnapContext &snapc,
Context *on_finish) {
// a single object
bufferlist bl;
assemble_extent(object_extent, &bl);
- ObjectRequest<I> *req = ObjectRequest<I>::create_compare_and_write(
- &image_ctx, object_extent.oid.name,
- object_extent.objectno, object_extent.offset,
- std::move(m_cmp_bl), std::move(bl), snapc,
- m_mismatch_offset, m_op_flags, this->m_trace,
- on_finish);
+ auto req = ObjectDispatchSpec::create_compare_and_write(
+ &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.oid.name,
+ object_extent.objectno, object_extent.offset, std::move(m_cmp_bl),
+ std::move(bl), snapc, m_mismatch_offset, m_op_flags, 0, this->m_trace,
+ on_finish);
return req;
}
namespace io {
class AioCompletion;
-class ObjectRequestHandle;
+class ObjectDispatchSpec;
class ReadResult;
template <typename ImageCtxT = ImageCtx>
}
protected:
- typedef std::list<ObjectRequestHandle *> ObjectRequests;
+ typedef std::list<ObjectDispatchSpec*> ObjectRequests;
ImageCtxT &m_image_ctx;
AioCompletion *m_aio_comp;
virtual void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
ObjectRequests *object_requests);
- virtual ObjectRequestHandle *create_object_request(
+ virtual ObjectDispatchSpec *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) = 0;
const ::SnapContext &snapc,
ObjectRequests *aio_object_requests) override;
- ObjectRequestHandle *create_object_request(
+ ObjectDispatchSpec *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) override;
void send_object_cache_requests(const ObjectExtents &object_extents,
uint64_t journal_tid) override;
- ObjectRequestHandle *create_object_request(
+ ObjectDispatchSpec *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) override;
void send_object_requests(const ObjectExtents &object_extents,
const ::SnapContext &snapc,
ObjectRequests *object_requests) override;
- ObjectRequestHandle *create_object_request(
+ ObjectDispatchSpec *create_object_request(
const ObjectExtent &object_extent, const ::SnapContext &snapc,
Context *on_finish) override;
void assemble_extent(const ObjectExtent &object_extent, bufferlist *bl);
- ObjectRequestHandle *create_object_request(const ObjectExtent &object_extent,
- const ::SnapContext &snapc,
- Context *on_finish) override;
+ ObjectDispatchSpec *create_object_request(
+ const ObjectExtent &object_extent, const ::SnapContext &snapc,
+ Context *on_finish) override;
uint64_t append_journal_event(const ObjectRequests &requests,
bool synchronous) override;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "include/Context.h"
+#include "librbd/io/ObjectDispatcher.h"
+#include <boost/variant.hpp>
+
+namespace librbd {
+namespace io {
+
+void ObjectDispatchSpec::C_Dispatcher::complete(int r) {
+ if (r < 0) {
+ finish(r);
+ return;
+ }
+
+ switch (object_dispatch_spec->dispatch_result) {
+ case DISPATCH_RESULT_CONTINUE:
+ object_dispatch_spec->send(0);
+ break;
+ case DISPATCH_RESULT_COMPLETE:
+ finish(r);
+ break;
+ case DISPATCH_RESULT_INVALID:
+ assert(false);
+ break;
+ }
+}
+
+void ObjectDispatchSpec::C_Dispatcher::finish(int r) {
+ on_finish->complete(r);
+ delete object_dispatch_spec;
+}
+
+struct ObjectDispatchSpec::SetJournalTid : public boost::static_visitor<void> {
+ uint64_t journal_tid;
+
+ SetJournalTid(uint64_t journal_tid) : journal_tid(journal_tid) {
+ }
+
+ template <typename T>
+ void operator()(T& t) const {
+ }
+
+ void operator()(WriteRequestBase& write_request_base) const {
+ write_request_base.journal_tid = journal_tid;
+ }
+};
+
+void ObjectDispatchSpec::send(uint64_t journal_tid) {
+ // TODO removed in future commit
+ if (journal_tid != 0) {
+ boost::apply_visitor(SetJournalTid{journal_tid}, request);
+ }
+
+ object_dispatcher->send(this);
+}
+
+void ObjectDispatchSpec::fail(int r) {
+ assert(r < 0);
+ dispatcher_ctx.complete(r);
+}
+
+} // namespace io
+} // namespace librbd
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H
+#define CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H
+
+#include "include/int_types.h"
+#include "include/buffer.h"
+#include "include/Context.h"
+#include "include/rados/librados.hpp"
+#include "common/snap_types.h"
+#include "common/zipkin_trace.h"
+#include "librbd/io/Types.h"
+#include <boost/variant/variant.hpp>
+
+namespace librbd {
+namespace io {
+
+struct ObjectDispatcherInterface;
+
+struct ObjectDispatchSpec {
+private:
+ // helper to avoid extra heap allocation per object IO
+ struct C_Dispatcher : public Context {
+ ObjectDispatchSpec* object_dispatch_spec;
+ Context* on_finish;
+
+ C_Dispatcher(ObjectDispatchSpec* object_dispatch_spec, Context* on_finish)
+ : object_dispatch_spec(object_dispatch_spec), on_finish(on_finish) {
+ }
+
+ void complete(int r) override;
+ void finish(int r) override;
+ };
+
+public:
+ struct RequestBase {
+ std::string oid;
+ uint64_t object_no;
+ uint64_t object_off;
+
+ RequestBase(const std::string& oid, uint64_t object_no, uint64_t object_off)
+ : oid(oid), object_no(object_no), object_off(object_off) {
+ }
+ };
+
+ struct ReadRequest : public RequestBase {
+ uint64_t object_len;
+ librados::snap_t snap_id;
+ ceph::bufferlist* read_data;
+ ExtentMap* extent_map;
+
+ ReadRequest(const std::string& oid, uint64_t object_no, uint64_t object_off,
+ uint64_t object_len, librados::snap_t snap_id,
+ ceph::bufferlist* read_data, ExtentMap* extent_map)
+ : RequestBase(oid, object_no, object_off),
+ object_len(object_len), snap_id(snap_id), read_data(read_data),
+ extent_map(extent_map) {
+ }
+ };
+
+ struct WriteRequestBase : public RequestBase {
+ ::SnapContext snapc;
+ uint64_t journal_tid;
+
+ WriteRequestBase(const std::string& oid, uint64_t object_no,
+ uint64_t object_off, const ::SnapContext& snapc,
+ uint64_t journal_tid)
+ : RequestBase(oid, object_no, object_off), snapc(snapc),
+ journal_tid(journal_tid) {
+ }
+ };
+
+ struct DiscardRequest : public WriteRequestBase {
+ uint64_t object_len;
+ int discard_flags;
+
+ DiscardRequest(const std::string& oid, uint64_t object_no,
+ uint64_t object_off, uint64_t object_len,
+ int discard_flags, const ::SnapContext& snapc,
+ uint64_t journal_tid)
+ : WriteRequestBase(oid, object_no, object_off, snapc, journal_tid),
+ object_len(object_len), discard_flags(discard_flags) {
+ }
+ };
+
+ struct WriteRequest : public WriteRequestBase {
+ ceph::bufferlist data;
+
+ WriteRequest(const std::string& oid, uint64_t object_no,
+ uint64_t object_off, ceph::bufferlist&& data,
+ const ::SnapContext& snapc, uint64_t journal_tid)
+ : WriteRequestBase(oid, object_no, object_off, snapc, journal_tid),
+ data(std::move(data)) {
+ }
+ };
+
+ struct WriteSameRequest : public WriteRequestBase {
+ uint64_t object_len;
+ Extents buffer_extents;
+ ceph::bufferlist data;
+
+ WriteSameRequest(const std::string& oid, uint64_t object_no,
+ uint64_t object_off, uint64_t object_len,
+ Extents&& buffer_extents, ceph::bufferlist&& data,
+ const ::SnapContext& snapc, uint64_t journal_tid)
+ : WriteRequestBase(oid, object_no, object_off, snapc, journal_tid),
+ object_len(object_len), buffer_extents(std::move(buffer_extents)),
+ data(std::move(data)) {
+ }
+ };
+
+ struct CompareAndWriteRequest : public WriteRequestBase {
+ ceph::bufferlist cmp_data;
+ ceph::bufferlist data;
+ uint64_t* mismatch_offset;
+
+ CompareAndWriteRequest(const std::string& oid, uint64_t object_no,
+ uint64_t object_off, ceph::bufferlist&& cmp_data,
+ ceph::bufferlist&& data, uint64_t* mismatch_offset,
+ const ::SnapContext& snapc, uint64_t journal_tid)
+ : WriteRequestBase(oid, object_no, object_off, snapc, journal_tid),
+ cmp_data(std::move(cmp_data)), data(std::move(data)),
+ mismatch_offset(mismatch_offset) {
+ }
+ };
+
+ struct FlushRequest {
+ FlushSource flush_source;
+
+ FlushRequest(FlushSource flush_source) : flush_source(flush_source) {
+ }
+ };
+
+ typedef boost::variant<ReadRequest,
+ DiscardRequest,
+ WriteRequest,
+ WriteSameRequest,
+ CompareAndWriteRequest,
+ FlushRequest> Request;
+
+ C_Dispatcher dispatcher_ctx;
+
+ ObjectDispatcherInterface* object_dispatcher;
+ ObjectDispatchLayer object_dispatch_layer;
+ int object_dispatch_flags = 0;
+ DispatchResult dispatch_result = DISPATCH_RESULT_INVALID;
+
+ Request request;
+ int op_flags;
+ ZTracer::Trace parent_trace;
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_read(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ const std::string &oid, uint64_t object_no, uint64_t object_off,
+ uint64_t object_len, librados::snap_t snap_id, int op_flags,
+ const ZTracer::Trace &parent_trace, ceph::bufferlist* read_data,
+ ExtentMap* extent_map, Context* on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ ReadRequest{oid, object_no, object_off,
+ object_len, snap_id, read_data,
+ extent_map},
+ op_flags, parent_trace, on_finish);
+ }
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_discard(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ const std::string &oid, uint64_t object_no, uint64_t object_off,
+ uint64_t object_len, const ::SnapContext &snapc, int discard_flags,
+ uint64_t journal_tid, const ZTracer::Trace &parent_trace,
+ Context *on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ DiscardRequest{oid, object_no, object_off,
+ object_len, discard_flags,
+ snapc, journal_tid},
+ 0, parent_trace, on_finish);
+ }
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_write(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ const std::string &oid, uint64_t object_no, uint64_t object_off,
+ ceph::bufferlist&& data, const ::SnapContext &snapc, int op_flags,
+ uint64_t journal_tid, const ZTracer::Trace &parent_trace,
+ Context *on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ WriteRequest{oid, object_no, object_off,
+ std::move(data), snapc,
+ journal_tid},
+ op_flags, parent_trace, on_finish);
+ }
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_write_same(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ const std::string &oid, uint64_t object_no, uint64_t object_off,
+ uint64_t object_len, Extents&& buffer_extents,
+ ceph::bufferlist&& data, const ::SnapContext &snapc, int op_flags,
+ uint64_t journal_tid, const ZTracer::Trace &parent_trace,
+ Context *on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ WriteSameRequest{oid, object_no, object_off,
+ object_len,
+ std::move(buffer_extents),
+ std::move(data), snapc,
+ journal_tid},
+ op_flags, parent_trace, on_finish);
+ }
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_compare_and_write(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ const std::string &oid, uint64_t object_no, uint64_t object_off,
+ ceph::bufferlist&& cmp_data, ceph::bufferlist&& write_data,
+ const ::SnapContext &snapc, uint64_t *mismatch_offset, int op_flags,
+ uint64_t journal_tid, const ZTracer::Trace &parent_trace,
+ Context *on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ CompareAndWriteRequest{oid, object_no,
+ object_off,
+ std::move(cmp_data),
+ std::move(write_data),
+ mismatch_offset,
+ snapc, journal_tid},
+ op_flags, parent_trace, on_finish);
+ }
+
+ template <typename ImageCtxT>
+ static ObjectDispatchSpec* create_flush(
+ ImageCtxT* image_ctx, ObjectDispatchLayer object_dispatch_layer,
+ FlushSource flush_source, const ZTracer::Trace &parent_trace,
+ Context *on_finish) {
+ return new ObjectDispatchSpec(image_ctx->io_object_dispatcher,
+ object_dispatch_layer,
+ FlushRequest{flush_source}, 0,
+ parent_trace, on_finish);
+ }
+
+ void send(uint64_t journal_tid /* removed in future commit */);
+ void fail(int r);
+
+private:
+ template <typename> friend class ObjectDispatcher;
+
+ // TODO removed in future commmit
+ struct SetJournalTid;
+
+ ObjectDispatchSpec(ObjectDispatcherInterface* object_dispatcher,
+ ObjectDispatchLayer object_dispatch_layer,
+ Request&& request, int op_flags,
+ const ZTracer::Trace& parent_trace, Context* on_finish)
+ : dispatcher_ctx(this, on_finish), object_dispatcher(object_dispatcher),
+ object_dispatch_layer(object_dispatch_layer), request(std::move(request)),
+ op_flags(op_flags), parent_trace(parent_trace) {
+ }
+
+};
+
+} // namespace io
+} // namespace librbd
+
+#endif // CEPH_LIBRBD_IO_OBJECT_DISPATCH_SPEC_H
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/ImageCtx.h"
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/ObjectRequest.h"
+#include <boost/variant.hpp>
+
+namespace librbd {
+namespace io {
+
+// TODO temporary implementation
+template <typename I>
+struct ObjectDispatcher<I>::SendVisitor
+ : public boost::static_visitor<void> {
+ ObjectDispatcher* object_dispatcher;
+ ObjectDispatchSpec* object_dispatch_spec;
+
+ SendVisitor(ObjectDispatcher* object_dispatcher,
+ ObjectDispatchSpec* object_dispatch_spec)
+ : object_dispatcher(object_dispatcher),
+ object_dispatch_spec(object_dispatch_spec) {
+ }
+
+ void operator()(ObjectDispatchSpec::ReadRequest& read) const {
+ auto req = ObjectReadRequest<I>::create(
+ object_dispatcher->m_image_ctx, read.oid, read.object_no, read.object_off,
+ read.object_len, read.snap_id, object_dispatch_spec->op_flags, false,
+ object_dispatch_spec->parent_trace, read.read_data, read.extent_map,
+ &object_dispatch_spec->dispatcher_ctx);
+ req->send();
+ }
+
+ void operator()(ObjectDispatchSpec::DiscardRequest& discard) const {
+ auto req = ObjectRequest<I>::create_discard(
+ object_dispatcher->m_image_ctx, discard.oid, discard.object_no,
+ discard.object_off, discard.object_len, discard.snapc, true, true,
+ object_dispatch_spec->parent_trace,
+ &object_dispatch_spec->dispatcher_ctx);
+ req->send();
+ }
+
+ void operator()(ObjectDispatchSpec::WriteRequest& write) const {
+ auto req = ObjectRequest<I>::create_write(
+ object_dispatcher->m_image_ctx, write.oid, write.object_no,
+ write.object_off, std::move(write.data), write.snapc,
+ object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
+ &object_dispatch_spec->dispatcher_ctx);
+ req->send();
+ }
+
+ void operator()(ObjectDispatchSpec::WriteSameRequest& write_same) const {
+ auto req = ObjectRequest<I>::create_write_same(
+ object_dispatcher->m_image_ctx, write_same.oid, write_same.object_no,
+ write_same.object_off, write_same.object_len, std::move(write_same.data),
+ write_same.snapc, object_dispatch_spec->op_flags,
+ object_dispatch_spec->parent_trace,
+ &object_dispatch_spec->dispatcher_ctx);
+ req->send();
+ }
+
+ void operator()(
+ ObjectDispatchSpec::CompareAndWriteRequest& compare_and_write) const {
+ auto req = ObjectRequest<I>::create_compare_and_write(
+ object_dispatcher->m_image_ctx, compare_and_write.oid,
+ compare_and_write.object_no, compare_and_write.object_off,
+ std::move(compare_and_write.cmp_data), std::move(compare_and_write.data),
+ compare_and_write.snapc, compare_and_write.mismatch_offset,
+ object_dispatch_spec->op_flags, object_dispatch_spec->parent_trace,
+ &object_dispatch_spec->dispatcher_ctx);
+ req->send();
+ }
+
+ void operator()(
+ ObjectDispatchSpec::FlushRequest& flush) const {
+ }
+};
+
+template <typename I>
+void ObjectDispatcher<I>::send(ObjectDispatchSpec* object_dispatch_spec) {
+ // TODO temporary implementation
+ object_dispatch_spec->dispatch_result = DISPATCH_RESULT_COMPLETE;
+ boost::apply_visitor(SendVisitor{this, object_dispatch_spec},
+ object_dispatch_spec->request);
+}
+
+} // namespace io
+} // namespace librbd
+
+template class librbd::io::ObjectDispatcher<librbd::ImageCtx>;
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_LIBRBD_IO_OBJECT_DISPATCHER_H
+#define CEPH_LIBRBD_IO_OBJECT_DISPATCHER_H
+
+#include "include/int_types.h"
+#include "librbd/io/Types.h"
+
+namespace librbd {
+
+struct ImageCtx;
+
+namespace io {
+
+struct ObjectDispatchSpec;
+
+struct ObjectDispatcherInterface {
+public:
+ virtual ~ObjectDispatcherInterface() {
+ }
+
+private:
+ friend class ObjectDispatchSpec;
+
+ virtual void send(ObjectDispatchSpec* object_dispatch_spec) = 0;
+};
+
+template <typename ImageCtxT = ImageCtx>
+class ObjectDispatcher : public ObjectDispatcherInterface {
+public:
+ ObjectDispatcher(ImageCtxT* image_ctx) : m_image_ctx(image_ctx) {
+ }
+
+private:
+ struct SendVisitor;
+
+ ImageCtxT* m_image_ctx;
+
+ void send(ObjectDispatchSpec* object_dispatch_spec);
+
+};
+
+} // namespace io
+} // namespace librbd
+
+extern template class librbd::io::ObjectDispatcher<librbd::ImageCtx>;
+
+#endif // CEPH_LIBRBD_IO_OBJECT_DISPATCHER_H
template <typename I>
ObjectRequest<I>*
-ObjectRequest<I>::create_writesame(I *ictx, const std::string &oid,
+ObjectRequest<I>::create_write_same(I *ictx, const std::string &oid,
uint64_t object_no, uint64_t object_off,
uint64_t object_len,
ceph::bufferlist&& data,
struct AioCompletion;
template <typename> class CopyupRequest;
-struct ObjectRequestHandle {
- virtual ~ObjectRequestHandle() {
- }
-
- virtual void fail(int r) = 0;
- virtual void send() = 0;
-};
-
/**
* This class represents an I/O operation to a single RBD data object.
* Its subclasses encapsulate logic for dealing with special cases
* for I/O due to layering.
*/
template <typename ImageCtxT = ImageCtx>
-class ObjectRequest : public ObjectRequestHandle {
+class ObjectRequest {
public:
- static ObjectRequest* create_write(ImageCtxT *ictx, const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- ceph::bufferlist&& data,
- const ::SnapContext &snapc, int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion);
- static ObjectRequest* create_discard(ImageCtxT *ictx, const std::string &oid,
- uint64_t object_no, uint64_t object_off,
- uint64_t object_len,
- const ::SnapContext &snapc,
- bool disable_clone_remove,
- bool update_object_map,
- const ZTracer::Trace &parent_trace,
- Context *completion);
- static ObjectRequest* create_writesame(ImageCtxT *ictx,
- const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- uint64_t object_len,
- ceph::bufferlist&& data,
- const ::SnapContext &snapc,
- int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion);
- static ObjectRequest* create_compare_and_write(ImageCtxT *ictx,
- const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- ceph::bufferlist&& cmp_data,
- ceph::bufferlist&& write_data,
- const ::SnapContext &snapc,
- uint64_t *mismatch_offset, int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion);
+ static ObjectRequest* create_write(
+ ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
+ uint64_t object_off, ceph::bufferlist&& data, const ::SnapContext &snapc,
+ int op_flags, const ZTracer::Trace &parent_trace, Context *completion);
+ static ObjectRequest* create_discard(
+ ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
+ uint64_t object_off, uint64_t object_len, const ::SnapContext &snapc,
+ bool disable_clone_remove, bool update_object_map,
+ const ZTracer::Trace &parent_trace, Context *completion);
+ static ObjectRequest* create_write_same(
+ ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
+ uint64_t object_off, uint64_t object_len, ceph::bufferlist&& data,
+ const ::SnapContext &snapc, int op_flags,
+ const ZTracer::Trace &parent_trace, Context *completion);
+ static ObjectRequest* create_compare_and_write(
+ ImageCtxT *ictx, const std::string &oid, uint64_t object_no,
+ uint64_t object_off, ceph::bufferlist&& cmp_data,
+ ceph::bufferlist&& write_data, const ::SnapContext &snapc,
+ uint64_t *mismatch_offset, int op_flags,
+ const ZTracer::Trace &parent_trace, Context *completion);
ObjectRequest(ImageCtxT *ictx, const std::string &oid,
uint64_t objectno, uint64_t off, uint64_t len,
librados::snap_t snap_id, const char *trace_name,
const ZTracer::Trace &parent_trace, Context *completion);
- ~ObjectRequest() override {
+ virtual ~ObjectRequest() {
m_trace.event("finish");
}
static void add_write_hint(ImageCtxT& image_ctx,
librados::ObjectWriteOperation *wr);
- void fail(int r) {
- finish(r);
- }
-
- void send() override = 0;
+ virtual void send() = 0;
bool has_parent() const {
return m_has_parent;
DIRECTION_BOTH
};
+enum DispatchResult {
+ DISPATCH_RESULT_INVALID,
+ DISPATCH_RESULT_CONTINUE,
+ DISPATCH_RESULT_COMPLETE
+};
+
+enum ObjectDispatchLayer {
+ OBJECT_DISPATCH_LAYER_NONE = 0,
+ OBJECT_DISPATCH_LAYER_CACHE,
+ OBJECT_DISPATCH_LAYER_JOURNAL,
+ OBJECT_DISPATCH_LAYER_CORE,
+ OBJECT_DISPATCH_LAYER_LAST
+};
+
+enum {
+ OBJECT_DISCARD_FLAG_DISABLE_CLONE_REMOVE = 1UL << 0,
+ OBJECT_DISCARD_FLAG_DISABLE_OBJECT_MAP_UPDATE = 1UL << 1
+};
+
typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
typedef std::map<uint64_t, uint64_t> ExtentMap;
#include "test/librbd/mock/cache/MockImageCache.h"
#include "librbd/io/ImageRequest.h"
#include "librbd/io/ObjectRequest.h"
+#include "librbd/io/ObjectDispatchSpec.h"
namespace librbd {
namespace {
+struct MockTestImageCtx;
+
+struct MockTestJournal : public MockJournal {
+ typedef std::list<io::ObjectDispatchSpec*> ObjectRequests;
+
+ MOCK_METHOD5(append_write_event, uint64_t(uint64_t, size_t,
+ const bufferlist &,
+ const ObjectRequests &, bool));
+ MOCK_METHOD6(append_io_event_mock, uint64_t(const journal::EventEntry&,
+ const ObjectRequests &,
+ uint64_t, size_t, bool, int));
+ uint64_t append_io_event(journal::EventEntry &&event_entry,
+ const ObjectRequests &requests,
+ uint64_t offset, size_t length,
+ bool flush_entry, int filter_ret_val) {
+ // googlemock doesn't support move semantics
+ return append_io_event_mock(event_entry, requests, offset, length,
+ flush_entry, filter_ret_val);
+ }
+};
+
struct MockTestImageCtx : public MockImageCtx {
MockTestImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
}
+
+ MockTestJournal* journal;
};
} // anonymous namespace
namespace io {
template <>
-struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
- static ObjectRequest* s_instance;
- Context *on_finish = nullptr;
-
- static ObjectRequest* create_write(librbd::MockTestImageCtx *ictx,
- const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- const ceph::bufferlist &data,
- const ::SnapContext &snapc, int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion) {
- assert(s_instance != nullptr);
- s_instance->on_finish = completion;
- return s_instance;
- }
-
- static ObjectRequest* create_discard(librbd::MockTestImageCtx *ictx,
- const std::string &oid,
- uint64_t object_no, uint64_t object_off,
- uint64_t object_len,
- const ::SnapContext &snapc,
- bool disable_remove_on_clone,
- bool update_object_map,
- const ZTracer::Trace &parent_trace,
- Context *completion) {
- assert(s_instance != nullptr);
- EXPECT_TRUE(disable_remove_on_clone);
- EXPECT_TRUE(update_object_map);
- s_instance->on_finish = completion;
- return s_instance;
- }
-
- static ObjectRequest* create_writesame(librbd::MockTestImageCtx *ictx,
- const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- uint64_t object_len,
- const ceph::bufferlist &data,
- const ::SnapContext &snapc,
- int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion) {
- assert(s_instance != nullptr);
- s_instance->on_finish = completion;
- return s_instance;
- }
-
- static ObjectRequest* create_compare_and_write(librbd::MockTestImageCtx *ictx,
- const std::string &oid,
- uint64_t object_no,
- uint64_t object_off,
- const ceph::bufferlist &cmp_data,
- const ceph::bufferlist &write_data,
- const ::SnapContext &snapc,
- uint64_t *mismatch_offset,
- int op_flags,
- const ZTracer::Trace &parent_trace,
- Context *completion) {
- assert(s_instance != nullptr);
- s_instance->on_finish = completion;
- return s_instance;
- }
-
- ObjectRequest() {
- assert(s_instance == nullptr);
- s_instance = this;
- }
- ~ObjectRequest() override {
- s_instance = nullptr;
- }
-
- MOCK_METHOD0(send, void());
- MOCK_METHOD1(fail, void(int));
-};
-
-template <>
-struct ObjectReadRequest<librbd::MockTestImageCtx> : public ObjectRequest<librbd::MockTestImageCtx> {
+struct ObjectReadRequest<librbd::MockTestImageCtx> {
typedef std::vector<std::pair<uint64_t, uint64_t> > Extents;
typedef std::map<uint64_t, uint64_t> ExtentMap;
static ObjectReadRequest* s_instance;
+ Context* on_finish = nullptr;
static ObjectReadRequest* create(librbd::MockTestImageCtx *ictx,
const std::string &oid,
assert(s_instance == nullptr);
s_instance = this;
}
- ~ObjectReadRequest() override {
+ ~ObjectReadRequest() {
s_instance = nullptr;
}
+ MOCK_METHOD0(send, void());
+
MOCK_CONST_METHOD0(get_offset, uint64_t());
MOCK_CONST_METHOD0(get_length, uint64_t());
MOCK_METHOD0(data, ceph::bufferlist &());
};
-ObjectRequest<librbd::MockTestImageCtx>* ObjectRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
ObjectReadRequest<librbd::MockTestImageCtx>* ObjectReadRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
} // namespace io
using ::testing::Invoke;
using ::testing::Return;
using ::testing::WithArg;
+using ::testing::WithoutArgs;
struct TestMockIoImageRequest : public TestMockFixture {
typedef ImageRequest<librbd::MockTestImageCtx> MockImageRequest;
typedef ImageFlushRequest<librbd::MockTestImageCtx> MockImageFlushRequest;
typedef ImageWriteSameRequest<librbd::MockTestImageCtx> MockImageWriteSameRequest;
typedef ImageCompareAndWriteRequest<librbd::MockTestImageCtx> MockImageCompareAndWriteRequest;
- typedef ObjectRequest<librbd::MockTestImageCtx> MockObjectRequest;
typedef ObjectReadRequest<librbd::MockTestImageCtx> MockObjectReadRequest;
- void expect_is_journal_appending(MockJournal &mock_journal, bool appending) {
+ void expect_is_journal_appending(MockTestJournal &mock_journal, bool appending) {
EXPECT_CALL(mock_journal, is_journal_appending())
.WillOnce(Return(appending));
}
.WillOnce(WithArg<4>(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue)));
}
- void expect_object_request_send(MockImageCtx &mock_image_ctx,
- MockObjectRequest &mock_object_request,
+ void expect_object_request_send(MockTestImageCtx &mock_image_ctx,
int r) {
- EXPECT_CALL(mock_object_request, send())
- .WillOnce(Invoke([&mock_image_ctx, &mock_object_request, r]() {
- mock_image_ctx.image_ctx->op_work_queue->queue(
- mock_object_request.on_finish, r);
+ EXPECT_CALL(*mock_image_ctx.io_object_dispatcher, send(_))
+ .WillOnce(Invoke([&mock_image_ctx, r](ObjectDispatchSpec* spec) {
+ spec->dispatch_result = io::DISPATCH_RESULT_COMPLETE;
+ mock_image_ctx.image_ctx->op_work_queue->queue(&spec->dispatcher_ctx, r);
}));
}
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- MockObjectRequest mock_aio_object_request;
MockTestImageCtx mock_image_ctx(*ictx);
- MockJournal mock_journal;
+ MockTestJournal mock_journal;
mock_image_ctx.journal = &mock_journal;
InSequence seq;
expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
0, 1, 0, 0);
} else {
- expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ expect_object_request_send(mock_image_ctx, 0);
}
C_SaferCond aio_comp_ctx;
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- MockObjectRequest mock_aio_object_request;
MockTestImageCtx mock_image_ctx(*ictx);
- MockJournal mock_journal;
+ MockTestJournal mock_journal;
mock_image_ctx.journal = &mock_journal;
InSequence seq;
expect_is_journal_appending(mock_journal, false);
if (!ictx->skip_partial_discard) {
- expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ expect_object_request_send(mock_image_ctx, 0);
}
C_SaferCond aio_comp_ctx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
MockTestImageCtx mock_image_ctx(*ictx);
- MockJournal mock_journal;
+ MockTestJournal mock_journal;
mock_image_ctx.journal = &mock_journal;
InSequence seq;
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- MockObjectRequest mock_aio_object_request;
MockTestImageCtx mock_image_ctx(*ictx);
- MockJournal mock_journal;
+ MockTestJournal mock_journal;
mock_image_ctx.journal = &mock_journal;
InSequence seq;
expect_write_to_cache(mock_image_ctx, ictx->get_object_name(0),
0, 1, 0, 0);
} else {
- expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ expect_object_request_send(mock_image_ctx, 0);
}
librbd::ImageCtx *ictx;
ASSERT_EQ(0, open_image(m_image_name, &ictx));
- MockObjectRequest mock_aio_object_request;
MockTestImageCtx mock_image_ctx(*ictx);
- MockJournal mock_journal;
+ MockTestJournal mock_journal;
mock_image_ctx.journal = &mock_journal;
InSequence seq;
expect_is_journal_appending(mock_journal, false);
- expect_object_request_send(mock_image_ctx, mock_aio_object_request, 0);
+ expect_object_request_send(mock_image_ctx, 0);
C_SaferCond aio_comp_ctx;
AioCompletion *aio_comp = AioCompletion::create_and_start(
expect_writesame(mock_image_ctx, 0, 4096, 0);
C_SaferCond ctx;
- auto req = MockObjectWriteSameRequest::create_writesame(
+ auto req = MockObjectWriteSameRequest::create_write_same(
&mock_image_ctx, ictx->get_object_name(0), 0, 0, 4096, std::move(bl),
mock_image_ctx.snapc, 0, {}, &ctx);
req->send();
#include "test/librbd/mock/MockOperations.h"
#include "test/librbd/mock/MockReadahead.h"
#include "test/librbd/mock/io/MockImageRequestWQ.h"
+#include "test/librbd/mock/io/MockObjectDispatcher.h"
#include "common/RWLock.h"
#include "common/WorkQueue.h"
#include "common/zipkin_trace.h"
group_spec(image_ctx.group_spec),
layout(image_ctx.layout),
io_work_queue(new io::MockImageRequestWQ()),
+ io_object_dispatcher(new io::MockObjectDispatcher()),
op_work_queue(new MockContextWQ()),
readahead_max_bytes(image_ctx.readahead_max_bytes),
event_socket(image_ctx.event_socket),
delete image_watcher;
delete op_work_queue;
delete io_work_queue;
+ delete io_object_dispatcher;
}
void wait_for_async_requests() {
std::map<uint64_t, io::CopyupRequest<MockImageCtx>*> copyup_list;
io::MockImageRequestWQ *io_work_queue;
+ io::MockObjectDispatcher *io_object_dispatcher;
MockContextWQ *op_work_queue;
cache::MockImageCache *image_cache = nullptr;
namespace librbd {
struct ImageCtx;
-namespace io { struct ObjectRequestHandle; }
struct MockJournal {
- typedef std::list<io::ObjectRequestHandle *> ObjectRequests;
-
static MockJournal *s_instance;
static MockJournal *get_instance() {
assert(s_instance != nullptr);
MOCK_METHOD0(allocate_op_tid, uint64_t());
- MOCK_METHOD5(append_write_event, uint64_t(uint64_t, size_t,
- const bufferlist &,
- const ObjectRequests &, bool));
- MOCK_METHOD6(append_io_event_mock, uint64_t(const journal::EventEntry&,
- const ObjectRequests &,
- uint64_t, size_t, bool, int));
- uint64_t append_io_event(journal::EventEntry &&event_entry,
- const ObjectRequests &requests,
- uint64_t offset, size_t length,
- bool flush_entry, int filter_ret_val) {
- // googlemock doesn't support move semantics
- return append_io_event_mock(event_entry, requests, offset, length,
- flush_entry, filter_ret_val);
- }
-
MOCK_METHOD3(append_op_event_mock, void(uint64_t, const journal::EventEntry&,
Context *));
void append_op_event(uint64_t op_tid, journal::EventEntry &&event_entry,
--- /dev/null
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H
+#define CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H
+
+#include "gmock/gmock.h"
+#include "include/Context.h"
+#include "librbd/io/ObjectDispatcher.h"
+#include "librbd/io/ObjectDispatchSpec.h"
+#include "librbd/io/Types.h"
+
+class Context;
+
+namespace librbd {
+namespace io {
+
+struct MockObjectDispatcher : public ObjectDispatcherInterface {
+public:
+ MOCK_METHOD1(send, void(ObjectDispatchSpec*));
+
+};
+
+} // namespace io
+} // namespace librbd
+
+#endif // CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H
namespace io {
template <>
-struct ObjectRequest<librbd::MockTestImageCtx> : public ObjectRequestHandle {
+struct ObjectRequest<librbd::MockTestImageCtx> {
static ObjectRequest* s_instance;
Context *on_finish = nullptr;
MOCK_METHOD3(construct, void(uint64_t, uint64_t, bool));
MOCK_METHOD0(send, void());
- MOCK_METHOD1(fail, void(int));
};
ObjectRequest<librbd::MockTestImageCtx>* ObjectRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
#include "librbd/Journal.h"
#include "librbd/Utils.h"
#include "librbd/io/AioCompletion.h"
-#include "librbd/io/ObjectRequest.h"
+#include "librbd/io/ObjectDispatchSpec.h"
#include "librbd/journal/Replay.h"
#include "librbd/journal/RemoveRequest.h"
#include "librbd/journal/CreateRequest.h"
uint64_t when_append_io_event(MockJournalImageCtx &mock_image_ctx,
MockJournal &mock_journal,
- io::ObjectRequest<> *object_request,
+ io::ObjectDispatchSpec *object_request,
int filter_ret_val) {
RWLock::RLocker owner_locker(mock_image_ctx.owner_lock);
MockJournal::IOObjectRequests object_requests;
};
C_SaferCond object_request_ctx;
- auto object_request = new io::ObjectDiscardRequest<>(
- ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
- &object_request_ctx);
+ auto object_request = io::ObjectDispatchSpec::create_discard(
+ &mock_image_ctx, io::OBJECT_DISPATCH_LAYER_NONE, "object0", 0, 0, 0, {}, 0,
+ 0, {}, &object_request_ctx);
::journal::MockFuture mock_future;
Context *on_journal_safe;
};
C_SaferCond object_request_ctx;
- auto object_request = new io::ObjectDiscardRequest<>(
- ictx, "oid", 0, 0, ictx->layout.object_size, {}, true, true, {},
- &object_request_ctx);
+ auto object_request = io::ObjectDispatchSpec::create_discard(
+ &mock_image_ctx, io::OBJECT_DISPATCH_LAYER_NONE, "object0", 0, 0, 0, {}, 0,
+ 0, {}, &object_request_ctx);
::journal::MockFuture mock_future;
Context *on_journal_safe;