mirror of
https://github.com/ceph/ceph
synced 2025-01-01 00:22:25 +00:00
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:
parent
78dc32bada
commit
5307f252d6
@ -1244,6 +1244,14 @@ public:
|
|||||||
|
|
||||||
virtual void clear_delta() {}
|
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();
|
virtual ~LogicalCachedExtent();
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -790,19 +790,33 @@ RandomBlockOolWriter::do_write(
|
|||||||
stats.num_records += 1;
|
stats.num_records += 1;
|
||||||
|
|
||||||
ex->prepare_write();
|
ex->prepare_write();
|
||||||
return rbm->write(paddr,
|
extent_len_t offset = 0;
|
||||||
ex->get_bptr()
|
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(
|
).handle_error(
|
||||||
alloc_write_iertr::pass_further{},
|
alloc_write_iertr::pass_further{},
|
||||||
crimson::ct_error::assert_all{
|
crimson::ct_error::assert_all{
|
||||||
"Invalid error when writing record"}
|
"Invalid error when writing record"}
|
||||||
).safe_then([&t, &ex, paddr, FNAME]() {
|
).safe_then([&t, &ex, paddr, this, FNAME]() {
|
||||||
TRACET("ool extent written at {} -- {}",
|
TRACET("ool extent written at {} -- {}",
|
||||||
t, paddr, *ex);
|
t, paddr, *ex);
|
||||||
if (ex->is_initial_pending()) {
|
if (ex->is_initial_pending()) {
|
||||||
t.mark_allocated_extent_ool(ex);
|
t.mark_allocated_extent_ool(ex);
|
||||||
} else if (ex->is_dirty()) {
|
} else if (can_inplace_rewrite(t, ex)) {
|
||||||
assert(t.get_src() == transaction_type_t::TRIM_DIRTY);
|
|
||||||
t.mark_inplace_rewrite_extent_ool(ex);
|
t.mark_inplace_rewrite_extent_ool(ex);
|
||||||
} else {
|
} else {
|
||||||
ceph_assert("impossible");
|
ceph_assert("impossible");
|
||||||
|
@ -64,6 +64,20 @@ struct ObjectDataBlock : crimson::os::seastore::LogicalCachedExtent {
|
|||||||
void clear_delta() final {
|
void clear_delta() final {
|
||||||
delta.clear();
|
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>;
|
using ObjectDataBlockRef = TCachedExtentRef<ObjectDataBlock>;
|
||||||
|
|
||||||
|
@ -83,6 +83,20 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
|
|||||||
void clear_delta() final {
|
void clear_delta() final {
|
||||||
delta.clear();
|
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>;
|
using TestBlockRef = TCachedExtentRef<TestBlock>;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user