From: Jianpeng Ma Date: Mon, 19 Jan 2015 03:51:40 +0000 (+0800) Subject: Striper: Add function 'assemble_result(CephContext *cct, char *buffer, size_t len... X-Git-Tag: v10.1.0~328^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9867804c20583f7ce55fc2daf6c2198f1849905f;p=ceph.git Striper: Add function 'assemble_result(CephContext *cct, char *buffer, size_t len)' in StripedReadResult. For sparse read, it can avoid copying zero around. Signed-off-by: Jianpeng Ma --- diff --git a/src/librbd/AioCompletion.cc b/src/librbd/AioCompletion.cc index 765c4cfe5f21..3501032e8089 100644 --- a/src/librbd/AioCompletion.cc +++ b/src/librbd/AioCompletion.cc @@ -44,21 +44,25 @@ namespace librbd { << "read_buf=" << reinterpret_cast(read_buf) << ", " << "real_bl=" << reinterpret_cast(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); + } } } } diff --git a/src/osdc/Striper.cc b/src/osdc/Striper.cc index 43280c82a073..f2bf8fbddcbb 100644 --- a/src/osdc/Striper.cc +++ b/src/osdc/Striper.cc @@ -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 >::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); +} + diff --git a/src/osdc/Striper.h b/src/osdc/Striper.h index bbd7eeac25e0..6b5a4e3b67c0 100644 --- a/src/osdc/Striper.h +++ b/src/osdc/Striper.h @@ -98,6 +98,12 @@ class CephContext; const vector >& 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); }; };