]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
ExtentCache: fix bug in get_remaining_extents_for_rmw
authorSamuel Just <sjust@redhat.com>
Tue, 22 Nov 2016 20:26:02 +0000 (12:26 -0800)
committerSamuel Just <sjust@redhat.com>
Tue, 22 Nov 2016 20:26:02 +0000 (12:26 -0800)
Signed-off-by: Samuel Just <sjust@redhat.com>
src/osd/ExtentCache.cc
src/test/osd/test_extent_cache.cc

index 6860b376e087765bfea3fafa6a3166ab59dbea2c..5368298a450dec62023b9f31da1d81356892acee 100644 (file)
@@ -168,20 +168,23 @@ extent_map ExtentCache::get_remaining_extents_for_rmw(
   auto &eset = get_or_create(oid);
   for (auto &&res: to_get) {
     bufferlist bl;
+    uint64_t cur = res.first;
     eset.traverse_update(
       pin,
       res.first,
       res.second,
       [&](uint64_t off, uint64_t len,
          extent *ext, object_extent_set::update_action *action) {
+       assert(off == cur);
+       cur = off + len;
        action->action = object_extent_set::update_action::NONE;
        assert(ext && ext->bl && ext->pinned_by_write());
        bl.substr_of(
          *(ext->bl),
          off - ext->offset,
          len);
+       ret.insert(off, len, bl);
       });
-    ret.insert(res.first, res.second, bl);
   }
   return ret;
 }
index b47cb2e47a27f294515e82639ac3a5c0db182d59..04b638a9a90612b0657964fdb70eef2d971aecd1 100644 (file)
@@ -166,3 +166,115 @@ TEST(extentcache, write_write_overlap)
 
   c.release_write_pin(pin2);
 }
+
+TEST(extentcache, write_write_overlap2)
+{
+  hobject_t oid;
+
+  ExtentCache c;
+  ExtentCache::write_pin pin;
+  c.open_write_pin(pin);
+
+  // start write 1
+  auto to_read = extent_set();
+  auto to_write = iset_from_vector(
+    {{659456, 4096}});
+  auto must_read = c.reserve_extents_for_rmw(
+    oid, pin, to_write, to_read);
+  ASSERT_EQ(
+    must_read,
+    to_read);
+
+  c.print(std::cerr);
+
+  // start write 2
+  ExtentCache::write_pin pin2;
+  c.open_write_pin(pin2);
+  auto to_read2 = extent_set();
+  auto to_write2 = iset_from_vector(
+    {{663552, 4096}});
+  auto must_read2 = c.reserve_extents_for_rmw(
+    oid, pin2, to_write2, to_read2);
+  ASSERT_EQ(
+    must_read2,
+    to_read2);
+
+
+  // start write 3
+  ExtentCache::write_pin pin3;
+  c.open_write_pin(pin3);
+  auto to_read3 = iset_from_vector({{659456, 8192}});
+  auto to_write3 = iset_from_vector({{659456, 8192}});
+  auto must_read3 = c.reserve_extents_for_rmw(
+    oid, pin3, to_write3, to_read3);
+  ASSERT_EQ(
+    must_read3,
+    extent_set());
+
+  c.print(std::cerr);
+
+  // complete read for write 1 and start commit
+  auto got = imap_from_iset(must_read);
+  auto pending_read = to_read;
+  pending_read.subtract(must_read);
+  auto pending = c.get_remaining_extents_for_rmw(
+    oid,
+    pin,
+    pending_read);
+  ASSERT_TRUE(pending.empty());
+
+  auto write_map = imap_from_iset(to_write);
+  c.present_rmw_update(
+    oid,
+    pin,
+    write_map);
+
+  c.print(std::cerr);
+
+  // complete read for write 2 and start commit
+  auto pending_read2 = to_read2;
+  pending_read2.subtract(must_read2);
+  auto pending2 = c.get_remaining_extents_for_rmw(
+    oid,
+    pin2,
+    pending_read2);
+  ASSERT_EQ(
+    pending2,
+    imap_from_iset(pending_read2));
+
+  auto write_map2 = imap_from_iset(to_write2);
+  c.present_rmw_update(
+    oid,
+    pin2,
+    write_map2);
+
+  // complete read for write 2 and start commit
+  auto pending_read3 = to_read3;
+  pending_read3.subtract(must_read3);
+  auto pending3 = c.get_remaining_extents_for_rmw(
+    oid,
+    pin3,
+    pending_read3);
+  ASSERT_EQ(
+    pending3,
+    imap_from_iset(pending_read3));
+
+  auto write_map3 = imap_from_iset(to_write3);
+  c.present_rmw_update(
+    oid,
+    pin3,
+    write_map3);
+
+
+  c.print(std::cerr);
+
+  c.release_write_pin(pin);
+
+  c.print(std::cerr);
+
+  c.release_write_pin(pin2);
+
+  c.print(std::cerr);
+
+  c.release_write_pin(pin3);
+}