From a786cfd0ab2ad7f9c2711217adef9e6ed908f86d Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Wed, 8 May 2019 23:31:01 -0400 Subject: [PATCH] librbd: avoid bl manipulation on single object read/writes If a read or write only spans a single object and buffer extent, there isn't any need to build a new bufferlist from a full sub-bl. Signed-off-by: Jason Dillaman --- src/librbd/io/ImageRequest.cc | 29 ++++++++++++++++------------- src/librbd/io/ImageRequest.h | 10 +++++----- src/librbd/io/ReadResult.cc | 15 ++++++++------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/src/librbd/io/ImageRequest.cc b/src/librbd/io/ImageRequest.cc index 5db5195fd1bf..ce064f1f07a1 100644 --- a/src/librbd/io/ImageRequest.cc +++ b/src/librbd/io/ImageRequest.cc @@ -472,17 +472,15 @@ void AbstractImageWriteRequest::send_object_requests( CephContext *cct = image_ctx.cct; AioCompletion *aio_comp = this->m_aio_comp; + bool single_extent = (object_extents.size() == 1); for (auto& oe : object_extents) { ldout(cct, 20) << data_object_name(&image_ctx, oe.object_no) << " " << oe.offset << "~" << oe.length << " from " << oe.buffer_extents << dendl; C_AioRequest *req_comp = new C_AioRequest(aio_comp); - auto request = create_object_request(oe, snapc, journal_tid, req_comp); - - // if journaling, stash the request for later; otherwise send - if (request != NULL) { - request->send(); - } + auto request = create_object_request(oe, snapc, journal_tid, single_extent, + req_comp); + request->send(); } } @@ -531,11 +529,17 @@ void ImageWriteRequest::send_image_cache_request() { template ObjectDispatchSpec *ImageWriteRequest::create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) { + uint64_t journal_tid, bool single_extent, Context *on_finish) { I &image_ctx = this->m_image_ctx; bufferlist bl; - assemble_extent(object_extent, &bl); + if (single_extent && object_extent.buffer_extents.size() == 1) { + // optimization for single object/buffer extent writes + bl = std::move(m_bl); + } else { + assemble_extent(object_extent, &bl); + } + auto req = ObjectDispatchSpec::create_write( &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.object_no, object_extent.offset, std::move(bl), snapc, m_op_flags, journal_tid, @@ -587,7 +591,7 @@ void ImageDiscardRequest::send_image_cache_request() { template ObjectDispatchSpec *ImageDiscardRequest::create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) { + uint64_t journal_tid, bool single_extent, Context *on_finish) { I &image_ctx = this->m_image_ctx; auto req = ObjectDispatchSpec::create_discard( &image_ctx, OBJECT_DISPATCH_LAYER_NONE, object_extent.object_no, @@ -747,7 +751,7 @@ void ImageWriteSameRequest::send_image_cache_request() { template ObjectDispatchSpec *ImageWriteSameRequest::create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) { + uint64_t journal_tid, bool single_extent, Context *on_finish) { I &image_ctx = this->m_image_ctx; bufferlist bl; @@ -821,9 +825,8 @@ void ImageCompareAndWriteRequest::send_image_cache_request() { template ObjectDispatchSpec *ImageCompareAndWriteRequest::create_object_request( - const LightweightObjectExtent &object_extent, - const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) { + const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, + uint64_t journal_tid, bool single_extent, Context *on_finish) { I &image_ctx = this->m_image_ctx; // NOTE: safe to move m_cmp_bl since we only support this op against diff --git a/src/librbd/io/ImageRequest.h b/src/librbd/io/ImageRequest.h index 2a684fb1e353..f62a67962095 100644 --- a/src/librbd/io/ImageRequest.h +++ b/src/librbd/io/ImageRequest.h @@ -148,7 +148,7 @@ protected: const ::SnapContext &snapc, uint64_t journal_tid); virtual ObjectDispatchSpec *create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) = 0; + uint64_t journal_tid, bool single_extent, Context *on_finish) = 0; virtual uint64_t append_journal_event(bool synchronous) = 0; virtual void update_stats(size_t length) = 0; @@ -188,7 +188,7 @@ protected: ObjectDispatchSpec *create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) override; + uint64_t journal_tid, bool single_extent, Context *on_finish) override; uint64_t append_journal_event(bool synchronous) override; void update_stats(size_t length) override; @@ -224,7 +224,7 @@ protected: ObjectDispatchSpec *create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) override; + uint64_t journal_tid, bool single_extent, Context *on_finish) override; uint64_t append_journal_event(bool synchronous) override; void update_stats(size_t length) override; @@ -295,7 +295,7 @@ protected: ObjectDispatchSpec *create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) override; + uint64_t journal_tid, bool single_extent, Context *on_finish) override; uint64_t append_journal_event(bool synchronous) override; void update_stats(size_t length) override; @@ -327,7 +327,7 @@ protected: ObjectDispatchSpec *create_object_request( const LightweightObjectExtent &object_extent, const ::SnapContext &snapc, - uint64_t journal_tid, Context *on_finish) override; + uint64_t journal_tid, bool single_extent, Context *on_finish) override; uint64_t append_journal_event(bool synchronous) override; void update_stats(size_t length) override; diff --git a/src/librbd/io/ReadResult.cc b/src/librbd/io/ReadResult.cc index 61bf78682bcb..d9a962935227 100644 --- a/src/librbd/io/ReadResult.cc +++ b/src/librbd/io/ReadResult.cc @@ -138,14 +138,15 @@ void ReadResult::C_ObjectReadRequest::finish(int r) { ldout(cct, 10) << " got " << extent_map << " for " << buffer_extents << " bl " << bl.length() << dendl; - // handle the case where a sparse-read wasn't issued - if (extent_map.empty()) { - extent_map[object_off] = bl.length(); - } - aio_completion->lock.lock(); - aio_completion->read_result.m_destriper.add_partial_sparse_result( - cct, bl, extent_map, object_off, buffer_extents); + if (!extent_map.empty()) { + aio_completion->read_result.m_destriper.add_partial_sparse_result( + cct, bl, extent_map, object_off, buffer_extents); + } else { + // handle the case where a sparse-read wasn't issued + aio_completion->read_result.m_destriper.add_partial_result( + cct, std::move(bl), buffer_extents); + } aio_completion->lock.unlock(); r = object_len; -- 2.47.3