]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Striper: Add function 'assemble_result(CephContext *cct, char *buffer, size_t len...
authorJianpeng Ma <jianpeng.ma@intel.com>
Mon, 19 Jan 2015 03:51:40 +0000 (11:51 +0800)
committerHaomai Wang <haomai@xsky.com>
Sat, 20 Feb 2016 06:15:28 +0000 (14:15 +0800)
For sparse read, it can avoid copying zero around.

Signed-off-by: Jianpeng Ma <jianpeng.ma@intel.com>
src/librbd/AioCompletion.cc
src/osdc/Striper.cc
src/osdc/Striper.h

index 765c4cfe5f2108543827126f57b3f0313d716093..3501032e8089326e8a7148e013d2ba1abd2aeec8 100644 (file)
@@ -44,21 +44,25 @@ namespace librbd {
                    << "read_buf=" << reinterpret_cast<void*>(read_buf) << ", "
                    << "real_bl=" <<  reinterpret_cast<void*>(read_bl) << dendl;
     if (rval >= 0 && aio_type == AIO_TYPE_READ) {
-      // FIXME: make the destriper write directly into a buffer so
-      // that we avoid shuffling pointers and copying zeros around.
-      bufferlist bl;
-      destriper.assemble_result(cct, bl, true);
-
-      if (read_buf) {
-       assert(bl.length() == read_buf_len);
-       bl.copy(0, read_buf_len, read_buf);
-       ldout(cct, 20) << "copied resulting " << bl.length()
-                      << " bytes to " << (void*)read_buf << dendl;
-      }
-      if (read_bl) {
-       ldout(cct, 20) << "moving resulting " << bl.length()
-                      << " bytes to bl " << (void*)read_bl << dendl;
-       read_bl->claim(bl);
+      if (read_buf && !read_bl) {
+       destriper.assemble_result(cct, read_buf, read_buf_len);
+      } else {
+       // FIXME: make the destriper write directly into a buffer so
+       // that we avoid shuffling pointers and copying zeros around.
+       bufferlist bl;
+       destriper.assemble_result(cct, bl, true);
+
+       if (read_buf) {
+         assert(bl.length() == read_buf_len);
+         bl.copy(0, read_buf_len, read_buf);
+         ldout(cct, 20) << "copied resulting " << bl.length()
+           << " bytes to " << (void*)read_buf << dendl;
+       }
+       if (read_bl) {
+         ldout(cct, 20) << " moving resulting " << bl.length()
+           << " bytes to bl " << (void*)read_bl << dendl;
+         read_bl->claim(bl);
+       }
       }
     }
   }
index 43280c82a07316a00024a8ca132a361288fdcc6a..f2bf8fbddcbb7c31695941fc349b9fc762a03c4e 100644 (file)
@@ -388,3 +388,38 @@ void Striper::StripedReadResult::assemble_result(CephContext *cct,
   partial.clear();
 }
 
+void Striper::StripedReadResult::assemble_result(CephContext *cct, char *buffer, size_t length)
+{
+
+  assert(buffer && length == total_intended_len);
+
+  map<uint64_t,pair<bufferlist,uint64_t> >::reverse_iterator p = partial.rbegin();
+  if (p == partial.rend())
+    return;
+
+  uint64_t curr = length;
+  uint64_t end = p->first + p->second.second;
+  while (p != partial.rend()) {
+    // sanity check
+    ldout(cct, 0) << "assemble_result(" << this << ") " << p->first << "~" << p->second.second
+                  << " " << p->second.first.length() << " bytes"
+                  << dendl;
+    assert(p->first == end - p->second.second);
+    end = p->first;
+
+    size_t len = p->second.first.length();
+    assert(curr >= p->second.second);
+    curr -= p->second.second;
+    if (len < p->second.second) {
+      if (len)
+       p->second.first.copy(0, len, buffer + curr);
+      memset(buffer + curr + len, 0, p->second.second - len);
+    } else {
+      p->second.first.copy(0, len, buffer + curr);
+    }
+    ++p;
+  }
+  partial.clear();
+  assert(curr == 0);
+}
+
index bbd7eeac25e0a91626e0e6580120d6382f1c2575..6b5a4e3b67c029c60910a962bd61bb68de30fd08 100644 (file)
@@ -98,6 +98,12 @@ class CephContext;
        const vector<pair<uint64_t,uint64_t> >& buffer_extents);
 
       void assemble_result(CephContext *cct, bufferlist& bl, bool zero_tail);
+
+      /**
+       * @buffer copy read data into buffer
+       * @len the length of buffer
+       */
+      void assemble_result(CephContext *cct, char *buffer, size_t len);
     };
 
   };