crimson/os/seastore: write only modified region when rewriting the extent in an inplace manner

Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
This commit is contained in:
Myoungwon Oh 2023-12-10 12:34:03 +09:00
parent 78dc32bada
commit 5307f252d6
4 changed files with 55 additions and 5 deletions

View File

@ -1244,6 +1244,14 @@ public:
virtual void clear_delta() {}
struct modified_region_t {
extent_len_t offset;
extent_len_t len;
};
virtual std::optional<modified_region_t> get_modified_region() {
return std::nullopt;
}
virtual ~LogicalCachedExtent();
protected:

View File

@ -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");

View File

@ -64,6 +64,20 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent {
void clear_delta() final {
delta.clear();
}
std::optional<modified_region_t> get_modified_region() final {
interval_set<extent_len_t> 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<ObjectDataBlock>;

View File

@ -83,6 +83,20 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
void clear_delta() final {
delta.clear();
}
std::optional<modified_region_t> get_modified_region() final {
interval_set<extent_len_t> 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<TestBlock>;