From: Myoungwon Oh Date: Sun, 17 Dec 2023 08:51:22 +0000 (+0900) Subject: crimson/os/seastore: introduce modified_region in DATA_BLOCK to keep track of modifie... X-Git-Tag: v19.3.0~272^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=3ca63d79b86cec82cb33ad4fc05866e61949967d;p=ceph.git crimson/os/seastore: introduce modified_region in DATA_BLOCK to keep track of modified region It has a limitation to keep track of the modified region using the existing deltas because we can not get the correct region in two cases: 1) a case where replay is done and 2) duplicate_for_write. This commit introduces modified region to solve the problem. Signed-off-by: Myoungwon Oh --- diff --git a/src/crimson/os/seastore/cache.cc b/src/crimson/os/seastore/cache.cc index fe42efa74ad7..24fa9788fe89 100644 --- a/src/crimson/os/seastore/cache.cc +++ b/src/crimson/os/seastore/cache.cc @@ -1288,7 +1288,7 @@ record_t Cache::prepare_record( i->dirty_from_or_retired_at = JOURNAL_SEQ_MIN; i->state = CachedExtent::extent_state_t::CLEAN; assert(i->is_logical()); - i->cast()->clear_delta(); + i->clear_modified_region(); touch_extent(*i); DEBUGT("inplace rewrite ool block is commmitted -- {}", t, *i); } diff --git a/src/crimson/os/seastore/cached_extent.h b/src/crimson/os/seastore/cached_extent.h index a72011db2752..487b0f3555e1 100644 --- a/src/crimson/os/seastore/cached_extent.h +++ b/src/crimson/os/seastore/cached_extent.h @@ -1242,8 +1242,6 @@ public: void on_replace_prior(Transaction &t) final; - virtual void clear_delta() {} - struct modified_region_t { extent_len_t offset; extent_len_t len; @@ -1252,6 +1250,8 @@ public: return std::nullopt; } + virtual void clear_modified_region() {} + virtual ~LogicalCachedExtent(); protected: diff --git a/src/crimson/os/seastore/extent_placement_manager.cc b/src/crimson/os/seastore/extent_placement_manager.cc index 45f51a401e08..0562d975337c 100644 --- a/src/crimson/os/seastore/extent_placement_manager.cc +++ b/src/crimson/os/seastore/extent_placement_manager.cc @@ -794,14 +794,11 @@ RandomBlockOolWriter::do_write( bufferptr bp; if (can_inplace_rewrite(t, ex)) { auto r = ex->get_modified_region(); - if (r.has_value() && r->len > rbm->get_block_size()) { - offset = p2align(r->offset, rbm->get_block_size()); - extent_len_t len = - p2roundup(r->offset + r->len, rbm->get_block_size()) - offset; - bp = ceph::bufferptr(ex->get_bptr(), offset, len); - } else { - bp = ex->get_bptr(); - } + ceph_assert(r.has_value()); + offset = p2align(r->offset, rbm->get_block_size()); + extent_len_t len = + p2roundup(r->offset + r->len, rbm->get_block_size()) - offset; + bp = ceph::bufferptr(ex->get_bptr(), offset, len); } else { bp = ex->get_bptr(); } diff --git a/src/crimson/os/seastore/object_data_handler.cc b/src/crimson/os/seastore/object_data_handler.cc index 3333fcfad9d4..5e49a48a1880 100644 --- a/src/crimson/os/seastore/object_data_handler.cc +++ b/src/crimson/os/seastore/object_data_handler.cc @@ -423,6 +423,7 @@ void ObjectDataBlock::apply_delta(const ceph::bufferlist &bl) { for (auto &&d : deltas) { auto iter = d.bl.cbegin(); iter.copy(d.len, get_bptr().c_str() + d.offset); + modified_region.union_insert(d.offset, d.len); } } diff --git a/src/crimson/os/seastore/object_data_handler.h b/src/crimson/os/seastore/object_data_handler.h index 2b01089214c2..783d0919ce5d 100644 --- a/src/crimson/os/seastore/object_data_handler.h +++ b/src/crimson/os/seastore/object_data_handler.h @@ -35,10 +35,12 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent { std::vector delta = {}; + interval_set modified_region; + explicit ObjectDataBlock(ceph::bufferptr &&ptr) : LogicalCachedExtent(std::move(ptr)) {} explicit ObjectDataBlock(const ObjectDataBlock &other) - : LogicalCachedExtent(other) {} + : LogicalCachedExtent(other), modified_region(other.modified_region) {} explicit ObjectDataBlock(extent_len_t length) : LogicalCachedExtent(length) {} @@ -55,28 +57,27 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent { auto iter = bl.cbegin(); iter.copy(bl.length(), get_bptr().c_str() + offset); delta.push_back({offset, bl.length(), bl}); + modified_region.union_insert(offset, bl.length()); } ceph::bufferlist get_delta() final; void apply_delta(const ceph::bufferlist &bl) final; - void clear_delta() final { - delta.clear(); - } - std::optional get_modified_region() final { - interval_set range; - for (auto &p : delta) { - if (p.len > 0) { - range.union_insert(p.offset, p.len); - } - } - if (range.empty()) { + if (modified_region.empty()) { return std::nullopt; } - return modified_region_t{range.range_start(), - range.range_end() - range.range_start()}; + return modified_region_t{modified_region.range_start(), + modified_region.range_end() - modified_region.range_start()}; + } + + void clear_modified_region() final { + modified_region.clear(); + } + + void logical_on_delta_write() final { + delta.clear(); } }; using ObjectDataBlockRef = TCachedExtentRef; diff --git a/src/test/crimson/seastore/test_block.cc b/src/test/crimson/seastore/test_block.cc index f7a39b0ef59c..7d673d8c2362 100644 --- a/src/test/crimson/seastore/test_block.cc +++ b/src/test/crimson/seastore/test_block.cc @@ -19,6 +19,7 @@ void TestBlock::apply_delta(const ceph::bufferlist &bl) { decode(deltas, biter); for (auto &&d : deltas) { set_contents(d.val, d.offset, d.len); + modified_region.union_insert(d.offset, d.len); } } diff --git a/src/test/crimson/seastore/test_block.h b/src/test/crimson/seastore/test_block.h index 8ddb3880b4f5..2c70b7dbb876 100644 --- a/src/test/crimson/seastore/test_block.h +++ b/src/test/crimson/seastore/test_block.h @@ -49,10 +49,12 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent { std::vector delta = {}; + interval_set modified_region; + TestBlock(ceph::bufferptr &&ptr) : LogicalCachedExtent(std::move(ptr)) {} TestBlock(const TestBlock &other) - : LogicalCachedExtent(other) {} + : LogicalCachedExtent(other), modified_region(other.modified_region) {} CachedExtentRef duplicate_for_write(Transaction&) final { return CachedExtentRef(new TestBlock(*this)); @@ -68,6 +70,7 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent { void set_contents(char c, uint16_t offset, uint16_t len) { ::memset(get_bptr().c_str() + offset, c, len); delta.push_back({c, offset, len}); + modified_region.union_insert(offset, len); } void set_contents(char c) { @@ -80,22 +83,20 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent { void apply_delta(const ceph::bufferlist &bl) final; - void clear_delta() final { - delta.clear(); - } - std::optional get_modified_region() final { - interval_set range; - for (auto &p : delta) { - if (p.len > 0) { - range.union_insert(p.offset, p.len); - } - } - if (range.empty()) { + if (modified_region.empty()) { return std::nullopt; } - return modified_region_t{range.range_start(), - range.range_end() - range.range_start()}; + return modified_region_t{modified_region.range_start(), + modified_region.range_end() - modified_region.range_start()}; + } + + void clear_modified_region() final { + modified_region.clear(); + } + + void logical_on_delta_write() final { + delta.clear(); } }; using TestBlockRef = TCachedExtentRef;