]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd: avoid bl manipulation on single object read/writes 28044/head
authorJason Dillaman <dillaman@redhat.com>
Thu, 9 May 2019 03:31:01 +0000 (23:31 -0400)
committerJason Dillaman <dillaman@redhat.com>
Mon, 13 May 2019 17:30:09 +0000 (13:30 -0400)
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 <dillaman@redhat.com>
src/librbd/io/ImageRequest.cc
src/librbd/io/ImageRequest.h
src/librbd/io/ReadResult.cc

index 5db5195fd1bf6fdef4aef5db86844019af286402..ce064f1f07a1747b86a4b22bbe57465efc1df7e3 100644 (file)
@@ -472,17 +472,15 @@ void AbstractImageWriteRequest<I>::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<I>::send_image_cache_request() {
 template <typename I>
 ObjectDispatchSpec *ImageWriteRequest<I>::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<I>::send_image_cache_request() {
 template <typename I>
 ObjectDispatchSpec *ImageDiscardRequest<I>::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<I>::send_image_cache_request() {
 template <typename I>
 ObjectDispatchSpec *ImageWriteSameRequest<I>::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<I>::send_image_cache_request() {
 
 template <typename I>
 ObjectDispatchSpec *ImageCompareAndWriteRequest<I>::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
index 2a684fb1e3537c8c6f89c14f5b0f5ccd663baeea..f62a6796209501fcd0076c73adc43f84ce5918ad 100644 (file)
@@ -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;
index 61bf78682bcbdf7cab6f7e1a447df302590901ca..d9a96293522793330c2fcc08e0c4ee3bb274acbc 100644 (file)
@@ -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;