From 64e00a53df287c7d1512bedb018fb39083dc8ae0 Mon Sep 17 00:00:00 2001 From: Samuel Just Date: Tue, 22 Nov 2016 12:26:02 -0800 Subject: [PATCH] ExtentCache: fix bug in get_remaining_extents_for_rmw Signed-off-by: Samuel Just --- src/osd/ExtentCache.cc | 5 +- src/test/osd/test_extent_cache.cc | 112 ++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/src/osd/ExtentCache.cc b/src/osd/ExtentCache.cc index 6860b376e087..5368298a450d 100644 --- a/src/osd/ExtentCache.cc +++ b/src/osd/ExtentCache.cc @@ -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; } diff --git a/src/test/osd/test_extent_cache.cc b/src/test/osd/test_extent_cache.cc index b47cb2e47a27..04b638a9a906 100644 --- a/src/test/osd/test_extent_cache.cc +++ b/src/test/osd/test_extent_cache.cc @@ -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); +} -- 2.47.3