]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fix _do_read cached vs read result assembly
authorSage Weil <sage@redhat.com>
Mon, 23 May 2016 19:00:37 +0000 (15:00 -0400)
committerSage Weil <sage@redhat.com>
Wed, 1 Jun 2016 15:40:47 +0000 (11:40 -0400)
We weren't handling the case of

 read block 0~300
 cache bloc 100~100

where the result is read(head) + cached + read(tail). Restructure the
loop to handle this.

Signed-off-by: Sage Weil <sage@redhat.com>
src/os/bluestore/BlueStore.cc

index 8d1d334a0efb524382172939597ad561409ca7b7..907e7010f35e7b4eb128a7ac6e3fbd0e9875155d 100644 (file)
@@ -2903,65 +2903,56 @@ int BlueStore::_do_read(
     ++b2r_it;
   }
 
-  //generate a resulting buffer
-  auto rr_it = ready_regions.begin();
-  auto rr_end = ready_regions.end();
-  auto rr0_it = ready_regions_in_cache.begin();
-  auto rr0_end = ready_regions_in_cache.end();
-
-  off = offset;
-  while ((rr_it != rr_end || rr0_it != rr0_end) && off < offset + length) {
-    ready_regions_t::iterator it;
-    if (rr_it != rr_end && (rr0_it == rr0_end || rr_it->first < rr0_it->first)) {
-      uint64_t r_off = 0;
-      uint64_t r_len = rr_it->second.length();
-      dout(30) << __func__ << " read region " << rr_it->first << "~" << rr_it->second.length() <<
-        " off " << off << " " << dendl;
-      if (off > rr_it->first + r_len) {
-       ++rr_it;
-       continue;
-      }
-      if (rr0_it!=rr0_end && (rr0_it->first < rr_it->first + r_len)) {
-       r_len = rr0_it->first - rr_it->first;
-      }
-
-      if (off > rr_it->first && r_len) {
-       r_off = off - rr_it->first;
-       assert(r_len >= r_off);
-       r_len -= r_off;
-      }
-      if (r_len == 0) {
-       ++rr_it;
-       continue;
-      }
-
-      if (off < rr_it->first + r_off)
-       bl.append_zero(rr_it->first + r_off - off);
-      if(r_off == 0 && r_len == rr_it->second.length()) {
-       bl.claim_append(rr_it->second);
-      } else {
-       bufferlist tmp;
-       tmp.substr_of(rr_it->second, r_off, r_len);
-       bl.claim_append(tmp);
-      }
-      off = rr_it->first + r_off + r_len;
-      dout(30) << __func__ << " used read region " << rr_it->first + r_off <<
-        "~" << r_len << " new off " << off << dendl;
-      ++rr_it;
-    } else if(rr0_it != rr0_end) {
-      if (off < rr0_it->first)
-       bl.append_zero(rr0_it->first + off);
-      dout(30) << __func__ << " used from cached buffer " <<
-        rr0_it->first << "~" << rr0_it->second.length() << dendl;
-      off = rr0_it->first + rr0_it->second.length();
-      bl.claim_append(rr0_it->second);
-      ++rr0_it;
-    }
-  }
-  assert(offset + length >= off);
-  bl.append_zero(offset + length - off);
+  // generate a resulting buffer
+  auto pc = ready_regions_in_cache.begin();
+  auto pc_end = ready_regions_in_cache.end();
+  auto pr = ready_regions.begin();
+  auto pr_end = ready_regions.end();
+  for (uint64_t pos = offset; pos < offset + length; ) {
+    // take any cache content at pos
+    if (pc != pc_end && pc->first <= pos) {
+      assert(pc->first == pos);
+      dout(30) << __func__ << " used cached region 0x" << std::hex
+              << pc->first << "~" << pc->second.length() << std::dec
+              << dendl;
+      pos = pc->first + pc->second.length();
+      bl.claim_append(pc->second);
+      ++pc;      // we can always move forward here.
+      continue;
+    }
+    // calc space till next cached data
+    uint64_t l = offset + length - pos;
+    if (pc != pc_end) {
+      l = pc->first - pos;
+    }
+    // take any read data at pos
+    while (pr != pr_end && pr->first + pr->second.length() <= pos) {
+      ++pr;
+    }
+    if (pr != pr_end && pr->first <= pos) {
+      uint64_t r_off = pos - pr->first;
+      uint64_t r_len = MIN(l, pr->second.length() - r_off);
+      dout(30) << __func__ << " used read region 0x" << std::hex
+              << r_off << "~" << r_len
+              << " from 0x" << pr->first << "~" << pr->second.length()
+              << std::dec << dendl;
+      bufferlist tmp;
+      tmp.substr_of(pr->second, r_off, r_len);
+      bl.claim_append(tmp);
+      pos += r_len;
+      continue;
+    }
+    // fill in any gap with zeros
+    if (pr != pr_end && pr->first < pos + l) {
+      l = pr->first - pos;
+    }
+    assert(l);
+    dout(30) << __func__ << " used zeros for 0x" << std::hex << pos
+            << "~" << l << std::dec << dendl;
+    bl.append_zero(l);
+    pos += l;
+  }
   assert(bl.length() == length);
-
   r = bl.length();
   return r;
 }