From 5307f252d6d31d49aa2a62ca0b61cb92ea46e5a2 Mon Sep 17 00:00:00 2001 From: Myoungwon Oh Date: Sun, 10 Dec 2023 12:34:03 +0900 Subject: [PATCH] crimson/os/seastore: write only modified region when rewriting the extent in an inplace manner Signed-off-by: Myoungwon Oh --- src/crimson/os/seastore/cached_extent.h | 8 +++++++ .../os/seastore/extent_placement_manager.cc | 24 +++++++++++++++---- src/crimson/os/seastore/object_data_handler.h | 14 +++++++++++ src/test/crimson/seastore/test_block.h | 14 +++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/crimson/os/seastore/cached_extent.h b/src/crimson/os/seastore/cached_extent.h index 18c102ed3e1..a72011db275 100644 --- a/src/crimson/os/seastore/cached_extent.h +++ b/src/crimson/os/seastore/cached_extent.h @@ -1244,6 +1244,14 @@ public: virtual void clear_delta() {} + struct modified_region_t { + extent_len_t offset; + extent_len_t len; + }; + virtual std::optional get_modified_region() { + return std::nullopt; + } + virtual ~LogicalCachedExtent(); protected: diff --git a/src/crimson/os/seastore/extent_placement_manager.cc b/src/crimson/os/seastore/extent_placement_manager.cc index f53b9f5be91..45f51a401e0 100644 --- a/src/crimson/os/seastore/extent_placement_manager.cc +++ b/src/crimson/os/seastore/extent_placement_manager.cc @@ -790,19 +790,33 @@ RandomBlockOolWriter::do_write( stats.num_records += 1; ex->prepare_write(); - return rbm->write(paddr, - ex->get_bptr() + extent_len_t offset = 0; + 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(); + } + } else { + bp = ex->get_bptr(); + } + return rbm->write(paddr + offset, + bp ).handle_error( alloc_write_iertr::pass_further{}, crimson::ct_error::assert_all{ "Invalid error when writing record"} - ).safe_then([&t, &ex, paddr, FNAME]() { + ).safe_then([&t, &ex, paddr, this, FNAME]() { TRACET("ool extent written at {} -- {}", t, paddr, *ex); if (ex->is_initial_pending()) { t.mark_allocated_extent_ool(ex); - } else if (ex->is_dirty()) { - assert(t.get_src() == transaction_type_t::TRIM_DIRTY); + } else if (can_inplace_rewrite(t, ex)) { t.mark_inplace_rewrite_extent_ool(ex); } else { ceph_assert("impossible"); diff --git a/src/crimson/os/seastore/object_data_handler.h b/src/crimson/os/seastore/object_data_handler.h index 76d69eb73f9..2b01089214c 100644 --- a/src/crimson/os/seastore/object_data_handler.h +++ b/src/crimson/os/seastore/object_data_handler.h @@ -64,6 +64,20 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent { 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()) { + return std::nullopt; + } + return modified_region_t{range.range_start(), + range.range_end() - range.range_start()}; + } }; using ObjectDataBlockRef = TCachedExtentRef; diff --git a/src/test/crimson/seastore/test_block.h b/src/test/crimson/seastore/test_block.h index bfb50670420..8ddb3880b4f 100644 --- a/src/test/crimson/seastore/test_block.h +++ b/src/test/crimson/seastore/test_block.h @@ -83,6 +83,20 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent { 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()) { + return std::nullopt; + } + return modified_region_t{range.range_start(), + range.range_end() - range.range_start()}; + } }; using TestBlockRef = TCachedExtentRef; -- 2.47.3