From 5d96356e42063260e22451583629b275e64d5130 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 4 May 2020 19:21:06 -0400 Subject: [PATCH] librbd: add image dispatch layer to image dispatch spec This will allow image extent-based IOs to skip layers. Also added helpful enums for the start of user-based API requests and internal requests. Signed-off-by: Jason Dillaman --- src/librbd/api/DiffIterate.cc | 3 +- src/librbd/image/CloseRequest.cc | 3 +- src/librbd/image/RefreshRequest.cc | 3 +- src/librbd/io/ImageDispatchSpec.h | 64 +++++++++++-------- src/librbd/io/ImageRequestWQ.cc | 22 ++++--- src/librbd/io/Types.h | 2 + src/librbd/operation/ResizeRequest.cc | 3 +- .../librbd/image/test_mock_RefreshRequest.cc | 5 +- .../librbd/io/test_mock_ImageRequestWQ.cc | 11 ++-- src/test/librbd/journal/test_Replay.cc | 3 +- .../operation/test_mock_ResizeRequest.cc | 5 +- src/test/rbd_mirror/test_ImageSync.cc | 3 +- 12 files changed, 78 insertions(+), 49 deletions(-) diff --git a/src/librbd/api/DiffIterate.cc b/src/librbd/api/DiffIterate.cc index 7e47c7ec3a8..4235679507d 100644 --- a/src/librbd/api/DiffIterate.cc +++ b/src/librbd/api/DiffIterate.cc @@ -251,7 +251,8 @@ int DiffIterate::diff_iterate(I *ictx, auto aio_comp = io::AioCompletion::create_and_start(&flush_ctx, ictx, io::AIO_TYPE_FLUSH); auto req = io::ImageDispatchSpec::create_flush_request( - *ictx, aio_comp, io::FLUSH_SOURCE_INTERNAL, {}); + *ictx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, + aio_comp, io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; } diff --git a/src/librbd/image/CloseRequest.cc b/src/librbd/image/CloseRequest.cc index b9cdbba6a25..998459c2cde 100644 --- a/src/librbd/image/CloseRequest.cc +++ b/src/librbd/image/CloseRequest.cc @@ -168,7 +168,8 @@ void CloseRequest::send_flush() { auto aio_comp = io::AioCompletion::create_and_start(ctx, m_image_ctx, io::AIO_TYPE_FLUSH); auto req = io::ImageDispatchSpec::create_flush_request( - *m_image_ctx, aio_comp, io::FLUSH_SOURCE_INTERNAL, {}); + *m_image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; } diff --git a/src/librbd/image/RefreshRequest.cc b/src/librbd/image/RefreshRequest.cc index 560b22ee610..eea4fd1dc43 100644 --- a/src/librbd/image/RefreshRequest.cc +++ b/src/librbd/image/RefreshRequest.cc @@ -1225,7 +1225,8 @@ Context *RefreshRequest::send_flush_aio() { auto aio_comp = io::AioCompletion::create_and_start( ctx, util::get_image_ctx(&m_image_ctx), io::AIO_TYPE_FLUSH); auto req = io::ImageDispatchSpec::create_flush_request( - m_image_ctx, aio_comp, io::FLUSH_SOURCE_INTERNAL, {}); + m_image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; return nullptr; diff --git a/src/librbd/io/ImageDispatchSpec.h b/src/librbd/io/ImageDispatchSpec.h index 8bb602bd2cb..a73b297eefc 100644 --- a/src/librbd/io/ImageDispatchSpec.h +++ b/src/librbd/io/ImageDispatchSpec.h @@ -84,47 +84,57 @@ public: }; C_Dispatcher dispatcher_ctx; - ImageDispatchLayer dispatch_layer = IMAGE_DISPATCH_LAYER_NONE; + ImageDispatchLayer dispatch_layer; DispatchResult dispatch_result = DISPATCH_RESULT_INVALID; static ImageDispatchSpec* create_read_request( - ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, + 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, aio_comp, + return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp, std::move(image_extents), Read{std::move(read_result)}, op_flags, parent_trace, 0); } static ImageDispatchSpec* create_discard_request( - ImageCtxT &image_ctx, 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, aio_comp, {{off, len}}, + 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}}, Discard{discard_granularity_bytes}, 0, parent_trace, tid); } static ImageDispatchSpec* create_write_request( - ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, - bufferlist &&bl, int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) { - return new ImageDispatchSpec(image_ctx, aio_comp, std::move(image_extents), - Write{std::move(bl)}, op_flags, parent_trace, tid); + 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, + std::move(image_extents), Write{std::move(bl)}, + op_flags, parent_trace, tid); } static ImageDispatchSpec* create_write_same_request( - ImageCtxT &image_ctx, 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, aio_comp, {{off, len}}, - WriteSame{std::move(bl)}, op_flags, - parent_trace, tid); + 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, + {{off, len}}, WriteSame{std::move(bl)}, + op_flags, parent_trace, tid); } static ImageDispatchSpec* create_compare_and_write_request( - ImageCtxT &image_ctx, AioCompletion *aio_comp, Extents &&image_extents, + 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, aio_comp, + return new ImageDispatchSpec(image_ctx, image_dispatch_layer, aio_comp, std::move(image_extents), CompareAndWrite{std::move(cmp_bl), std::move(bl), @@ -133,10 +143,11 @@ public: } static ImageDispatchSpec* create_flush_request( - ImageCtxT &image_ctx, AioCompletion *aio_comp, - FlushSource flush_source, const ZTracer::Trace &parent_trace) { - return new ImageDispatchSpec(image_ctx, aio_comp, {}, Flush{flush_source}, - 0, parent_trace, 0); + 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, {}, + Flush{flush_source}, 0, parent_trace, 0); } ~ImageDispatchSpec() { @@ -185,10 +196,13 @@ private: struct IsWriteOpVisitor; struct TokenRequestedVisitor; - ImageDispatchSpec(ImageCtxT& image_ctx, AioCompletion* aio_comp, - Extents&& image_extents, Request&& request, - int op_flags, const ZTracer::Trace& parent_trace, uint64_t tid) - : dispatcher_ctx(this), m_image_ctx(image_ctx), m_aio_comp(aio_comp), + ImageDispatchSpec(ImageCtxT& image_ctx, + 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), dispatch_layer(image_dispatch_layer), + m_image_ctx(image_ctx), m_aio_comp(aio_comp), m_image_extents(std::move(image_extents)), m_request(std::move(request)), m_op_flags(op_flags), m_parent_trace(parent_trace), m_tid(tid) { m_aio_comp->get(); diff --git a/src/librbd/io/ImageRequestWQ.cc b/src/librbd/io/ImageRequestWQ.cc index c8677d0a8c7..f74d20cfb47 100644 --- a/src/librbd/io/ImageRequestWQ.cc +++ b/src/librbd/io/ImageRequestWQ.cc @@ -35,7 +35,8 @@ void flush_image(I& image_ctx, Context* on_finish) { auto aio_comp = librbd::io::AioCompletion::create_and_start( on_finish, util::get_image_ctx(&image_ctx), librbd::io::AIO_TYPE_FLUSH); auto req = librbd::io::ImageDispatchSpec::create_flush_request( - image_ctx, aio_comp, librbd::io::FLUSH_SOURCE_INTERNAL, {}); + image_ctx, IMAGE_DISPATCH_LAYER_API_START, aio_comp, FLUSH_SOURCE_INTERNAL, + {}); req->send(); delete req; } @@ -291,8 +292,8 @@ void ImageRequestWQ::aio_read(AioCompletion *c, uint64_t off, uint64_t len, if (m_image_ctx.non_blocking_aio || writes_blocked() || !writes_empty() || require_lock_on_read()) { queue(ImageDispatchSpec::create_read_request( - m_image_ctx, c, {{off, len}}, std::move(read_result), op_flags, - trace)); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, {{off, len}}, + std::move(read_result), op_flags, trace)); } else { c->start_op(); ImageRequest::aio_read(&m_image_ctx, c, {{off, len}}, @@ -335,7 +336,8 @@ void ImageRequestWQ::aio_write(AioCompletion *c, uint64_t off, uint64_t len, } ImageDispatchSpec *req = ImageDispatchSpec::create_write_request( - m_image_ctx, c, {{off, len}}, std::move(bl), op_flags, trace, tid); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, {{off, len}}, std::move(bl), + op_flags, trace, tid); std::shared_lock owner_locker{m_image_ctx.owner_lock}; if (m_image_ctx.non_blocking_aio || writes_blocked()) { @@ -381,7 +383,8 @@ void ImageRequestWQ::aio_discard(AioCompletion *c, uint64_t off, } ImageDispatchSpec *req = ImageDispatchSpec::create_discard_request( - m_image_ctx, c, off, len, discard_granularity_bytes, trace, tid); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, off, len, + discard_granularity_bytes, trace, tid); std::shared_lock owner_locker{m_image_ctx.owner_lock}; if (m_image_ctx.non_blocking_aio || writes_blocked()) { @@ -418,7 +421,7 @@ void ImageRequestWQ::aio_flush(AioCompletion *c, bool native_async) { auto tid = ++m_last_tid; ImageDispatchSpec *req = ImageDispatchSpec::create_flush_request( - m_image_ctx, c, FLUSH_SOURCE_USER, trace); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, FLUSH_SOURCE_USER, trace); { std::lock_guard locker{m_lock}; @@ -474,7 +477,8 @@ void ImageRequestWQ::aio_writesame(AioCompletion *c, uint64_t off, } ImageDispatchSpec *req = ImageDispatchSpec::create_write_same_request( - m_image_ctx, c, off, len, std::move(bl), op_flags, trace, tid); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, off, len, std::move(bl), + op_flags, trace, tid); std::shared_lock owner_locker{m_image_ctx.owner_lock}; if (m_image_ctx.non_blocking_aio || writes_blocked()) { @@ -522,8 +526,8 @@ void ImageRequestWQ::aio_compare_and_write(AioCompletion *c, } ImageDispatchSpec *req = ImageDispatchSpec::create_compare_and_write_request( - m_image_ctx, c, {{off, len}}, std::move(cmp_bl), std::move(bl), - mismatch_off, op_flags, trace, tid); + m_image_ctx, IMAGE_DISPATCH_LAYER_API_START, c, {{off, len}}, + std::move(cmp_bl), std::move(bl), mismatch_off, op_flags, trace, tid); std::shared_lock owner_locker{m_image_ctx.owner_lock}; if (m_image_ctx.non_blocking_aio || writes_blocked()) { diff --git a/src/librbd/io/Types.h b/src/librbd/io/Types.h index 9d5ef6d037c..fc10337255c 100644 --- a/src/librbd/io/Types.h +++ b/src/librbd/io/Types.h @@ -63,10 +63,12 @@ enum DispatchResult { enum ImageDispatchLayer { IMAGE_DISPATCH_LAYER_NONE = 0, + IMAGE_DISPATCH_LAYER_API_START = IMAGE_DISPATCH_LAYER_NONE, IMAGE_DISPATCH_LAYER_QUEUE, IMAGE_DISPATCH_LAYER_QOS, IMAGE_DISPATCH_LAYER_EXCLUSIVE_LOCK, IMAGE_DISPATCH_LAYER_REFRESH, + IMAGE_DISPATCH_LAYER_INTERNAL_START = IMAGE_DISPATCH_LAYER_REFRESH, IMAGE_DISPATCH_LAYER_JOURNAL, IMAGE_DISPATCH_LAYER_WRITEBACK_CACHE, IMAGE_DISPATCH_LAYER_CORE, diff --git a/src/librbd/operation/ResizeRequest.cc b/src/librbd/operation/ResizeRequest.cc index a14b6de24f4..53673980e96 100644 --- a/src/librbd/operation/ResizeRequest.cc +++ b/src/librbd/operation/ResizeRequest.cc @@ -197,7 +197,8 @@ void ResizeRequest::send_flush_cache() { auto aio_comp = io::AioCompletion::create_and_start( ctx, util::get_image_ctx(&image_ctx), io::AIO_TYPE_FLUSH); auto req = io::ImageDispatchSpec::create_flush_request( - image_ctx, aio_comp, io::FLUSH_SOURCE_INTERNAL, {}); + image_ctx, io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; } diff --git a/src/test/librbd/image/test_mock_RefreshRequest.cc b/src/test/librbd/image/test_mock_RefreshRequest.cc index f9a076e3229..ecec4586cf5 100644 --- a/src/test/librbd/image/test_mock_RefreshRequest.cc +++ b/src/test/librbd/image/test_mock_RefreshRequest.cc @@ -111,8 +111,9 @@ struct ImageDispatchSpec { AioCompletion *aio_comp = nullptr; static ImageDispatchSpec* create_flush_request( - librbd::MockRefreshImageCtx &image_ctx, AioCompletion *aio_comp, - FlushSource flush_source, const ZTracer::Trace &parent_trace) { + 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; diff --git a/src/test/librbd/io/test_mock_ImageRequestWQ.cc b/src/test/librbd/io/test_mock_ImageRequestWQ.cc index 8ebea73cf85..99c8362d887 100644 --- a/src/test/librbd/io/test_mock_ImageRequestWQ.cc +++ b/src/test/librbd/io/test_mock_ImageRequestWQ.cc @@ -43,17 +43,18 @@ struct ImageDispatchSpec { bool blocked = false; static ImageDispatchSpec* create_write_request( - librbd::MockTestImageCtx &image_ctx, AioCompletion *aio_comp, - Extents &&image_extents, bufferlist &&bl, int op_flags, - const ZTracer::Trace &parent_trace, uint64_t tid) { + librbd::MockTestImageCtx &image_ctx, ImageDispatchLayer dispatch_layer, + AioCompletion *aio_comp, Extents &&image_extents, bufferlist &&bl, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid) { ceph_assert(s_instance != nullptr); s_instance->aio_comp = aio_comp; return s_instance; } static ImageDispatchSpec* create_flush_request( - librbd::MockTestImageCtx &image_ctx, AioCompletion *aio_comp, - FlushSource flush_source, const ZTracer::Trace &parent_trace) { + librbd::MockTestImageCtx &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; diff --git a/src/test/librbd/journal/test_Replay.cc b/src/test/librbd/journal/test_Replay.cc index f79d752a15a..535198e3a7c 100644 --- a/src/test/librbd/journal/test_Replay.cc +++ b/src/test/librbd/journal/test_Replay.cc @@ -862,7 +862,8 @@ TEST_F(TestJournalReplay, ObjectPosition) { aio_comp = librbd::io::AioCompletion::create_and_start( &flush_ctx, ictx, librbd::io::AIO_TYPE_FLUSH); auto req = librbd::io::ImageDispatchSpec<>::create_flush_request( - *ictx, aio_comp, librbd::io::FLUSH_SOURCE_INTERNAL, {}); + *ictx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + librbd::io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; ASSERT_EQ(0, flush_ctx.wait()); diff --git a/src/test/librbd/operation/test_mock_ResizeRequest.cc b/src/test/librbd/operation/test_mock_ResizeRequest.cc index 4cbf914313d..764f2721327 100644 --- a/src/test/librbd/operation/test_mock_ResizeRequest.cc +++ b/src/test/librbd/operation/test_mock_ResizeRequest.cc @@ -33,8 +33,9 @@ struct ImageDispatchSpec { AioCompletion *aio_comp = nullptr; static ImageDispatchSpec* create_flush_request( - MockImageCtx &image_ctx, AioCompletion *aio_comp, - FlushSource flush_source, const ZTracer::Trace &parent_trace) { + 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; diff --git a/src/test/rbd_mirror/test_ImageSync.cc b/src/test/rbd_mirror/test_ImageSync.cc index c8aab54b0b5..2a830609fc7 100644 --- a/src/test/rbd_mirror/test_ImageSync.cc +++ b/src/test/rbd_mirror/test_ImageSync.cc @@ -36,7 +36,8 @@ int flush(librbd::ImageCtx *image_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_request( - *image_ctx, aio_comp, librbd::io::FLUSH_SOURCE_INTERNAL, {}); + *image_ctx, librbd::io::IMAGE_DISPATCH_LAYER_INTERNAL_START, aio_comp, + librbd::io::FLUSH_SOURCE_INTERNAL, {}); req->send(); delete req; return ctx.wait(); -- 2.39.5