std::shared_lock owner_locker{ictx->owner_lock};
auto aio_comp = io::AioCompletion::create_and_start(&flush_ctx, ictx,
io::AIO_TYPE_FLUSH);
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
*ictx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START,
aio_comp, io::FLUSH_SOURCE_INTERNAL, {});
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_read(
+ auto req = io::ImageDispatchSpec::create_read(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, {{off, len}},
std::move(read_result), op_flags, trace);
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_write(
+ auto req = io::ImageDispatchSpec::create_write(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, {{off, len}},
std::move(bl), op_flags, trace, 0);
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_discard(
+ auto req = io::ImageDispatchSpec::create_discard(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, off, len,
discard_granularity_bytes, trace, 0);
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_write_same(
+ auto req = io::ImageDispatchSpec::create_write_same(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, off, len,
std::move(bl), op_flags, trace, 0);
req->send();
bl.append_zero(len);
aio_comp->aio_type = io::AIO_TYPE_WRITE;
- auto req = io::ImageDispatchSpec<I>::create_write(
+ auto req = io::ImageDispatchSpec::create_write(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, {{off, len}},
std::move(bl), op_flags, trace, 0);
req->send();
bufferlist bl;
bl.append_zero(data_length);
- auto req = io::ImageDispatchSpec<I>::create_write_same(
+ auto req = io::ImageDispatchSpec::create_write_same(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, off, len,
std::move(bl), op_flags, trace, 0);
req->send();
Context* prepend_ctx = new io::C_AioRequest(aio_comp);
auto prepend_aio_comp = io::AioCompletion::create_and_start(
prepend_ctx, &image_ctx, io::AIO_TYPE_WRITE);
- auto prepend_req = io::ImageDispatchSpec<I>::create_write(
+ auto prepend_req = io::ImageDispatchSpec::create_write(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, prepend_aio_comp,
{{prepend_offset, prepend_length}}, std::move(bl), op_flags, trace,
0);
Context* append_ctx = new io::C_AioRequest(aio_comp);
auto append_aio_comp = io::AioCompletion::create_and_start(
append_ctx, &image_ctx, io::AIO_TYPE_WRITE);
- auto append_req = io::ImageDispatchSpec<I>::create_write(
+ auto append_req = io::ImageDispatchSpec::create_write(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, append_aio_comp,
{{append_offset, append_length}}, std::move(bl), op_flags, trace, 0);
append_req->send();
Context* write_same_ctx = new io::C_AioRequest(aio_comp);
auto write_same_aio_comp = io::AioCompletion::create_and_start(
write_same_ctx, &image_ctx, io::AIO_TYPE_WRITESAME);
- auto req = io::ImageDispatchSpec<I>::create_write_same(
+ auto req = io::ImageDispatchSpec::create_write_same(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, write_same_aio_comp,
write_same_offset, write_same_length, std::move(bl), op_flags, trace,
0);
// enable partial discard (zeroing) of objects
uint32_t discard_granularity_bytes = 0;
- auto req = io::ImageDispatchSpec<I>::create_discard(
+ auto req = io::ImageDispatchSpec::create_discard(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, off, len,
discard_granularity_bytes, trace, 0);
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_compare_and_write(
+ auto req = io::ImageDispatchSpec::create_compare_and_write(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp, {{off, len}},
std::move(cmp_bl), std::move(bl), mismatch_off, op_flags, trace, 0);
req->send();
return;
}
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp,
io::FLUSH_SOURCE_USER, trace);
req->send();
// push through a flush for any in-flight writes at lower levels
auto aio_comp = io::AioCompletion::create_and_start(
on_finish, util::get_image_ctx(m_image_ctx), io::AIO_TYPE_FLUSH);
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
*m_image_ctx, io::IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK, aio_comp,
io::FLUSH_SOURCE_INTERNAL, {});
req->send();
CloseRequest<I>, &CloseRequest<I>::handle_flush>(this);
auto aio_comp = io::AioCompletion::create_and_start(ctx, m_image_ctx,
io::AIO_TYPE_FLUSH);
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
*m_image_ctx, io::IMAGE_DISPATCH_LAYER_API_START, aio_comp,
io::FLUSH_SOURCE_INTERNAL, {});
req->send();
RefreshRequest<I>, &RefreshRequest<I>::handle_flush_aio>(this);
auto aio_comp = io::AioCompletion::create_and_start(
ctx, util::get_image_ctx(&m_image_ctx), io::AIO_TYPE_FLUSH);
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
m_image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
io::FLUSH_SOURCE_INTERNAL, {});
req->send();
namespace io {
struct AioCompletion;
-template <typename> struct ImageDispatchSpec;
+struct ImageDispatchSpec;
struct ImageDispatchInterface {
typedef ImageDispatchLayer DispatchLayer;
- typedef ImageDispatchSpec<librbd::ImageCtx> DispatchSpec;
+ typedef ImageDispatchSpec DispatchSpec;
virtual ~ImageDispatchInterface() {
}
namespace librbd {
namespace io {
-template <typename I>
-void ImageDispatchSpec<I>::C_Dispatcher::complete(int r) {
+void ImageDispatchSpec::C_Dispatcher::complete(int r) {
switch (image_dispatch_spec->dispatch_result) {
case DISPATCH_RESULT_RESTART:
ceph_assert(image_dispatch_spec->dispatch_layer != 0);
}
}
-template <typename I>
-void ImageDispatchSpec<I>::C_Dispatcher::finish(int r) {
+void ImageDispatchSpec::C_Dispatcher::finish(int r) {
image_dispatch_spec->finish(r);
}
-template <typename I>
-struct ImageDispatchSpec<I>::IsWriteOpVisitor
- : public boost::static_visitor<bool> {
- bool operator()(const Read&) const {
- return false;
- }
-
- template <typename T>
- bool operator()(const T&) const {
- return true;
- }
-};
-
-template <typename I>
-void ImageDispatchSpec<I>::send() {
+void ImageDispatchSpec::send() {
image_dispatcher->send(this);
}
-template <typename I>
-void ImageDispatchSpec<I>::finish(int r) {
+void ImageDispatchSpec::finish(int r) {
image_dispatcher->finish(r, dispatch_layer, tid);
delete this;
}
-template <typename I>
-void ImageDispatchSpec<I>::fail(int r) {
+void ImageDispatchSpec::fail(int r) {
dispatch_result = DISPATCH_RESULT_COMPLETE;
aio_comp->fail(r);
}
-template <typename I>
-uint64_t ImageDispatchSpec<I>::extents_length() {
- uint64_t length = 0;
- auto &extents = this->image_extents;
-
- for (auto &extent : extents) {
- length += extent.second;
- }
- return length;
-}
-
-template <typename I>
-const Extents& ImageDispatchSpec<I>::get_image_extents() const {
- return this->image_extents;
-}
-
-template <typename I>
-uint64_t ImageDispatchSpec<I>::get_tid() {
- return this->tid;
-}
-
-template <typename I>
-bool ImageDispatchSpec<I>::is_write_op() const {
- return boost::apply_visitor(IsWriteOpVisitor(), request);
-}
-
-template <typename I>
-void ImageDispatchSpec<I>::start_op() {
- tid = 0;
- aio_comp->start_op();
-}
-
} // namespace io
} // namespace librbd
-
-template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
struct ImageDispatcherInterface;
-template <typename ImageCtxT = ImageCtx>
class ImageDispatchSpec {
private:
// helper to avoid extra heap allocation per object IO
ZTracer::Trace parent_trace;
uint64_t tid;
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_read(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, Extents &&image_extents,
ReadResult &&read_result, int op_flags,
const ZTracer::Trace &parent_trace) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp,
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp,
std::move(image_extents),
Read{std::move(read_result)},
op_flags, parent_trace, 0);
}
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_discard(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, uint64_t off, uint64_t len,
uint32_t discard_granularity_bytes, const ZTracer::Trace &parent_trace,
uint64_t tid) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp,
- {{off, len}},
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp, {{off, len}},
Discard{discard_granularity_bytes},
0, parent_trace, tid);
}
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_write(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, Extents &&image_extents,
bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace,
uint64_t tid) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp,
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp,
std::move(image_extents), Write{std::move(bl)},
op_flags, parent_trace, tid);
}
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_write_same(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, uint64_t off, uint64_t len,
bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace,
uint64_t tid) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp,
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp,
{{off, len}}, WriteSame{std::move(bl)},
op_flags, parent_trace, tid);
}
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_compare_and_write(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, Extents &&image_extents,
bufferlist &&cmp_bl, bufferlist &&bl, uint64_t *mismatch_offset,
int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp,
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp,
std::move(image_extents),
CompareAndWrite{std::move(cmp_bl),
std::move(bl),
op_flags, parent_trace, tid);
}
+ template <typename ImageCtxT = ImageCtx>
static ImageDispatchSpec* create_flush(
ImageCtxT &image_ctx, ImageDispatchLayer image_dispatch_layer,
AioCompletion *aio_comp, FlushSource flush_source,
const ZTracer::Trace &parent_trace) {
- return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp, {},
+ return new ImageDispatchSpec(image_ctx.io_image_dispatcher,
+ image_dispatch_layer, aio_comp, {},
Flush{flush_source}, 0, parent_trace, 0);
}
void send();
void fail(int r);
- bool is_write_op() const;
-
- void start_op();
-
- const Extents& get_image_extents() const;
-
- AioCompletion* get_aio_completion() const {
- return aio_comp;
- }
-
- uint64_t get_tid();
- bool blocked = false;
-
private:
struct SendVisitor;
struct IsWriteOpVisitor;
struct TokenRequestedVisitor;
- ImageDispatchSpec(ImageCtxT& image_ctx,
+ ImageDispatchSpec(ImageDispatcherInterface* image_dispatcher,
ImageDispatchLayer image_dispatch_layer,
AioCompletion* aio_comp, Extents&& image_extents,
Request&& request, int op_flags,
const ZTracer::Trace& parent_trace, uint64_t tid)
- : dispatcher_ctx(this), image_dispatcher(image_ctx.io_image_dispatcher),
+ : dispatcher_ctx(this), image_dispatcher(image_dispatcher),
dispatch_layer(image_dispatch_layer), aio_comp(aio_comp),
image_extents(std::move(image_extents)), request(std::move(request)),
op_flags(op_flags), parent_trace(parent_trace), tid(tid) {
}
void finish(int r);
-
- uint64_t extents_length();
};
} // namespace io
} // namespace librbd
-extern template class librbd::io::ImageDispatchSpec<librbd::ImageCtx>;
-
#endif // CEPH_LIBRBD_IO_IMAGE_DISPATCH_SPEC_H
template <typename I>
struct ImageDispatcher<I>::SendVisitor : public boost::static_visitor<bool> {
ImageDispatchInterface* image_dispatch;
- ImageDispatchSpec<I>* image_dispatch_spec;
+ ImageDispatchSpec* image_dispatch_spec;
SendVisitor(ImageDispatchInterface* image_dispatch,
- ImageDispatchSpec<I>* image_dispatch_spec)
+ ImageDispatchSpec* image_dispatch_spec)
: image_dispatch(image_dispatch),
image_dispatch_spec(image_dispatch_spec) {
}
- bool operator()(typename ImageDispatchSpec<I>::Read& read) const {
+ bool operator()(ImageDispatchSpec::Read& read) const {
return image_dispatch->read(
image_dispatch_spec->aio_comp,
std::move(image_dispatch_spec->image_extents),
&image_dispatch_spec->dispatcher_ctx);
}
- bool operator()(typename ImageDispatchSpec<I>::Discard& discard) const {
+ bool operator()(ImageDispatchSpec::Discard& discard) const {
return image_dispatch->discard(
image_dispatch_spec->aio_comp,
std::move(image_dispatch_spec->image_extents),
&image_dispatch_spec->dispatcher_ctx);
}
- bool operator()(typename ImageDispatchSpec<I>::Write& write) const {
+ bool operator()(ImageDispatchSpec::Write& write) const {
return image_dispatch->write(
image_dispatch_spec->aio_comp,
std::move(image_dispatch_spec->image_extents), std::move(write.bl),
&image_dispatch_spec->dispatcher_ctx);
}
- bool operator()(typename ImageDispatchSpec<I>::WriteSame& write_same) const {
+ bool operator()(ImageDispatchSpec::WriteSame& write_same) const {
return image_dispatch->write_same(
image_dispatch_spec->aio_comp,
std::move(image_dispatch_spec->image_extents), std::move(write_same.bl),
}
bool operator()(
- typename ImageDispatchSpec<I>::CompareAndWrite& compare_and_write) const {
+ ImageDispatchSpec::CompareAndWrite& compare_and_write) const {
return image_dispatch->compare_and_write(
image_dispatch_spec->aio_comp,
std::move(image_dispatch_spec->image_extents),
&image_dispatch_spec->dispatcher_ctx);
}
- bool operator()(typename ImageDispatchSpec<I>::Flush& flush) const {
+ bool operator()(ImageDispatchSpec::Flush& flush) const {
return image_dispatch->flush(
image_dispatch_spec->aio_comp, flush.flush_source,
image_dispatch_spec->parent_trace, image_dispatch_spec->tid,
template <typename I>
bool ImageDispatcher<I>::send_dispatch(
ImageDispatchInterface* image_dispatch,
- ImageDispatchSpec<I>* image_dispatch_spec) {
+ ImageDispatchSpec* image_dispatch_spec) {
if (image_dispatch_spec->tid == 0) {
image_dispatch_spec->tid = ++m_next_tid;
}
protected:
bool send_dispatch(
ImageDispatchInterface* image_dispatch,
- ImageDispatchSpec<ImageCtxT>* image_dispatch_spec) override;
+ ImageDispatchSpec* image_dispatch_spec) override;
private:
struct SendVisitor;
// ensure that all in-flight IO is flushed
auto aio_comp = AioCompletion::create_and_start(
on_finish, util::get_image_ctx(m_image_ctx), librbd::io::AIO_TYPE_FLUSH);
- auto req = ImageDispatchSpec<I>::create_flush(
+ auto req = ImageDispatchSpec::create_flush(
*m_image_ctx, IMAGE_DISPATCH_LAYER_WRITE_BLOCK, aio_comp,
FLUSH_SOURCE_INTERNAL, {});
req->send();
ResizeRequest<I>, &ResizeRequest<I>::handle_flush_cache>(this);
auto aio_comp = io::AioCompletion::create_and_start(
ctx, util::get_image_ctx(&image_ctx), io::AIO_TYPE_FLUSH);
- auto req = io::ImageDispatchSpec<I>::create_flush(
+ auto req = io::ImageDispatchSpec::create_flush(
image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
io::FLUSH_SOURCE_INTERNAL, {});
req->send();
#include "librbd/image/GetMetadataRequest.h"
#include "librbd/image/RefreshRequest.h"
#include "librbd/image/RefreshParentRequest.h"
-#include "librbd/io/ImageDispatchSpec.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <arpa/inet.h>
} // namespace image
-namespace io {
-
-template <>
-struct ImageDispatchSpec<librbd::MockRefreshImageCtx> {
- static ImageDispatchSpec* s_instance;
- AioCompletion *aio_comp = nullptr;
-
- static ImageDispatchSpec* create_flush(
- librbd::MockRefreshImageCtx &image_ctx, ImageDispatchLayer dispatch_layer,
- AioCompletion *aio_comp, FlushSource flush_source,
- const ZTracer::Trace &parent_trace) {
- ceph_assert(s_instance != nullptr);
- s_instance->aio_comp = aio_comp;
- return s_instance;
- }
-
- MOCK_CONST_METHOD0(send, void());
-
- ImageDispatchSpec() {
- s_instance = this;
- }
-};
-
-ImageDispatchSpec<librbd::MockRefreshImageCtx>* ImageDispatchSpec<librbd::MockRefreshImageCtx>::s_instance = nullptr;
-
-} // namespace io
namespace util {
inline ImageCtx *get_image_ctx(librbd::MockRefreshImageCtx *image_ctx) {
typedef GetMetadataRequest<MockRefreshImageCtx> MockGetMetadataRequest;
typedef RefreshRequest<MockRefreshImageCtx> MockRefreshRequest;
typedef RefreshParentRequest<MockRefreshImageCtx> MockRefreshParentRequest;
- typedef io::ImageDispatchSpec<librbd::MockRefreshImageCtx> MockIoImageDispatchSpec;
typedef std::map<std::string, bufferlist> Metadata;
void set_v1_migration_header(ImageCtx *ictx) {
.Times(1);
}
- void expect_image_flush(MockIoImageDispatchSpec &mock_image_request, int r) {
- EXPECT_CALL(mock_image_request, send())
- .WillOnce(Invoke([&mock_image_request, r]() {
- mock_image_request.aio_comp->set_request_count(1);
- mock_image_request.aio_comp->add_request();
- mock_image_request.aio_comp->complete_request(r);
+ void expect_image_flush(MockImageCtx &mock_image_ctx, int r) {
+ EXPECT_CALL(*mock_image_ctx.io_image_dispatcher, send(_))
+ .WillOnce(Invoke([r](io::ImageDispatchSpec* spec) {
+ ASSERT_TRUE(boost::get<io::ImageDispatchSpec::Flush>(
+ &spec->request) != nullptr);
+ spec->dispatch_result = io::DISPATCH_RESULT_COMPLETE;
+ spec->aio_comp->set_request_count(1);
+ spec->aio_comp->add_request();
+ spec->aio_comp->complete_request(r);
}));
}
C_SaferCond flush_ctx;
aio_comp = librbd::io::AioCompletion::create_and_start(
&flush_ctx, ictx, librbd::io::AIO_TYPE_FLUSH);
- auto req = librbd::io::ImageDispatchSpec<>::create_flush(
+ auto req = librbd::io::ImageDispatchSpec::create_flush(
*ictx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
librbd::io::FLUSH_SOURCE_INTERNAL, {});
req->send();
MOCK_METHOD1(register_dispatch, void(ImageDispatchInterface*));
MOCK_METHOD2(shut_down_dispatch, void(ImageDispatchLayer, Context*));
- MOCK_METHOD1(send, void(ImageDispatchSpec<>*));
+ MOCK_METHOD1(send, void(ImageDispatchSpec*));
MOCK_METHOD3(finish, void(int r, ImageDispatchLayer, uint64_t));
MOCK_METHOD1(apply_qos_schedule_tick_min, void(uint64_t));
#include "common/bit_vector.hpp"
#include "librbd/internal.h"
#include "librbd/ObjectMap.h"
-#include "librbd/io/ImageDispatchSpec.h"
#include "librbd/operation/ResizeRequest.h"
#include "librbd/operation/TrimRequest.h"
#include "gmock/gmock.h"
} // namespace util
-namespace io {
-
-template <>
-struct ImageDispatchSpec<MockImageCtx> {
- static ImageDispatchSpec* s_instance;
- AioCompletion *aio_comp = nullptr;
-
- static ImageDispatchSpec* create_flush(
- MockImageCtx &image_ctx, ImageDispatchLayer dispatch_layer,
- AioCompletion *aio_comp, FlushSource flush_source,
- const ZTracer::Trace &parent_trace) {
- ceph_assert(s_instance != nullptr);
- s_instance->aio_comp = aio_comp;
- return s_instance;
- }
-
- MOCK_CONST_METHOD0(send, void());
-
- ImageDispatchSpec() {
- s_instance = this;
- }
-};
-
-ImageDispatchSpec<MockImageCtx>* ImageDispatchSpec<MockImageCtx>::s_instance = nullptr;
-
-} // namespace io
-
namespace operation {
template <>
public:
typedef ResizeRequest<MockImageCtx> MockResizeRequest;
typedef TrimRequest<MockImageCtx> MockTrimRequest;
- typedef io::ImageDispatchSpec<MockImageCtx> MockIoImageDispatchSpec;
void expect_block_writes(MockImageCtx &mock_image_ctx, int r) {
EXPECT_CALL(*mock_image_ctx.io_image_dispatcher, block_writes(_))
.WillOnce(FinishRequest(&mock_trim_request, r, &mock_image_ctx));
}
- void expect_flush_cache(MockImageCtx &mock_image_ctx,
- MockIoImageDispatchSpec& mock_io_image_dispatch_spec,
- int r) {
- EXPECT_CALL(mock_io_image_dispatch_spec, send())
- .WillOnce(Invoke([&mock_image_ctx, &mock_io_image_dispatch_spec, r]() {
- auto aio_comp = mock_io_image_dispatch_spec.s_instance->aio_comp;
+ void expect_flush_cache(MockImageCtx &mock_image_ctx, int r) {
+ EXPECT_CALL(*mock_image_ctx.io_image_dispatcher, send(_))
+ .WillOnce(Invoke([&mock_image_ctx, r](io::ImageDispatchSpec* spec) {
+ ASSERT_TRUE(boost::get<io::ImageDispatchSpec::Flush>(
+ &spec->request) != nullptr);
+ spec->dispatch_result = io::DISPATCH_RESULT_COMPLETE;
+ auto aio_comp = spec->aio_comp;
auto ctx = new LambdaContext([aio_comp](int r) {
if (r < 0) {
aio_comp->fail(r);
expect_unblock_writes(mock_image_ctx);
MockTrimRequest mock_trim_request;
- MockIoImageDispatchSpec mock_io_image_dispatch_spec;
- expect_flush_cache(mock_image_ctx, mock_io_image_dispatch_spec, 0);
+ expect_flush_cache(mock_image_ctx, 0);
expect_invalidate_cache(mock_image_ctx, 0);
expect_trim(mock_image_ctx, mock_trim_request, 0);
expect_block_writes(mock_image_ctx, 0);
expect_unblock_writes(mock_image_ctx);
MockTrimRequest mock_trim_request;
- MockIoImageDispatchSpec mock_io_image_dispatch_spec;
- expect_flush_cache(mock_image_ctx, mock_io_image_dispatch_spec, 0);
+ expect_flush_cache(mock_image_ctx, 0);
expect_invalidate_cache(mock_image_ctx, -EBUSY);
expect_trim(mock_image_ctx, mock_trim_request, -EINVAL);
expect_commit_op_event(mock_image_ctx, -EINVAL);
expect_unblock_writes(mock_image_ctx);
MockTrimRequest mock_trim_request;
- MockIoImageDispatchSpec mock_io_image_dispatch_spec;
- expect_flush_cache(mock_image_ctx, mock_io_image_dispatch_spec, -EINVAL);
+ expect_flush_cache(mock_image_ctx, -EINVAL);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
}
expect_unblock_writes(mock_image_ctx);
MockTrimRequest mock_trim_request;
- MockIoImageDispatchSpec mock_io_image_dispatch_spec;
- expect_flush_cache(mock_image_ctx, mock_io_image_dispatch_spec, 0);
+ expect_flush_cache(mock_image_ctx, 0);
expect_invalidate_cache(mock_image_ctx, -EINVAL);
expect_commit_op_event(mock_image_ctx, -EINVAL);
ASSERT_EQ(-EINVAL, when_resize(mock_image_ctx, ictx->size / 2, true, 0, false));
expect_unblock_writes(mock_image_ctx);
MockTrimRequest mock_trim_request;
- MockIoImageDispatchSpec mock_io_image_dispatch_spec;
- expect_flush_cache(mock_image_ctx, mock_io_image_dispatch_spec, 0);
+ expect_flush_cache(mock_image_ctx, 0);
expect_invalidate_cache(mock_image_ctx, 0);
expect_trim(mock_image_ctx, mock_trim_request, 0);
expect_block_writes(mock_image_ctx, -EINVAL);
C_SaferCond ctx;
auto aio_comp = librbd::io::AioCompletion::create_and_start(
&ctx, image_ctx, librbd::io::AIO_TYPE_FLUSH);
- auto req = librbd::io::ImageDispatchSpec<>::create_flush(
+ auto req = librbd::io::ImageDispatchSpec::create_flush(
*image_ctx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
librbd::io::FLUSH_SOURCE_INTERNAL, {});
req->send();
C_SaferCond ctx;
auto aio_comp = librbd::io::AioCompletion::create_and_start(
&ctx, image_ctx, librbd::io::AIO_TYPE_FLUSH);
- auto req = librbd::io::ImageDispatchSpec<>::create_flush(
+ auto req = librbd::io::ImageDispatchSpec::create_flush(
*image_ctx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp,
librbd::io::FLUSH_SOURCE_INTERNAL, {});
req->send();