<< "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);
+ }
}
}
}
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);
+}
+
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);
};
};