mirror of
https://github.com/ceph/ceph
synced 2025-02-24 19:47:44 +00:00
crimson/os/seastore/transaction_manager: implement remap_pin
Signed-off-by: Xinyu Huang <xinyu.huang@intel.com>
This commit is contained in:
parent
cf6e46e57a
commit
55d33b69b0
@ -291,6 +291,125 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* remap_pin
|
||||
*
|
||||
* Remap original extent to new extents.
|
||||
* Return the pins of new extent.
|
||||
*/
|
||||
struct remap_entry {
|
||||
extent_len_t offset;
|
||||
extent_len_t len;
|
||||
remap_entry(extent_len_t _offset, extent_len_t _len) {
|
||||
offset = _offset;
|
||||
len = _len;
|
||||
}
|
||||
};
|
||||
using remap_pin_iertr = base_iertr;
|
||||
template <std::size_t N>
|
||||
using remap_pin_ret = remap_pin_iertr::future<std::array<LBAMappingRef, N>>;
|
||||
template <typename T, std::size_t N>
|
||||
remap_pin_ret<N> remap_pin(
|
||||
Transaction &t,
|
||||
LBAMappingRef &&pin,
|
||||
std::array<remap_entry, N> remaps) {
|
||||
|
||||
#ifndef NDEBUG
|
||||
std::sort(remaps.begin(), remaps.end(),
|
||||
[](remap_entry x, remap_entry y) {
|
||||
return x.offset < y.offset;
|
||||
});
|
||||
auto original_len = pin->get_length();
|
||||
extent_len_t total_remap_len = 0;
|
||||
extent_len_t last_offset = 0;
|
||||
extent_len_t last_len = 0;
|
||||
|
||||
for (auto &remap : remaps) {
|
||||
auto remap_offset = remap.offset;
|
||||
auto remap_len = remap.len;
|
||||
total_remap_len += remap.len;
|
||||
ceph_assert(remap_offset >= (last_offset + last_len));
|
||||
last_offset = remap_offset;
|
||||
last_len = remap_len;
|
||||
}
|
||||
ceph_assert(total_remap_len < original_len);
|
||||
#endif
|
||||
|
||||
// FIXME: paddr can be absolute and pending
|
||||
ceph_assert(pin->get_val().is_absolute());
|
||||
return cache->get_extent_if_cached(
|
||||
t, pin->get_val(), T::TYPE
|
||||
).si_then([this, &t, remaps,
|
||||
original_laddr = pin->get_key(),
|
||||
original_paddr = pin->get_val(),
|
||||
original_len = pin->get_length()](auto ext) {
|
||||
std::optional<ceph::bufferptr> original_bptr;
|
||||
LOG_PREFIX(TransactionManager::remap_pin);
|
||||
SUBDEBUGT(seastore_tm,
|
||||
"original laddr: {}, original paddr: {}, original length: {},"
|
||||
" remap to {} extents",
|
||||
t, original_laddr, original_paddr, original_len, remaps.size());
|
||||
if (ext) {
|
||||
// FIXME: cannot and will not remap a dirty extent for now.
|
||||
ceph_assert(!ext->is_dirty());
|
||||
ceph_assert(!ext->is_mutable());
|
||||
ceph_assert(ext->get_length() == original_len);
|
||||
original_bptr = ext->get_bptr();
|
||||
}
|
||||
return seastar::do_with(
|
||||
std::array<LBAMappingRef, N>(),
|
||||
0,
|
||||
std::move(original_bptr),
|
||||
std::vector<remap_entry>(remaps.begin(), remaps.end()),
|
||||
[this, &t, original_laddr, original_paddr, original_len]
|
||||
(auto &ret, auto &count, auto &original_bptr, auto &remaps) {
|
||||
return dec_ref(t, original_laddr
|
||||
).si_then([this, &t, &original_bptr, &ret, &count, &remaps,
|
||||
original_laddr, original_paddr, original_len](auto) {
|
||||
return trans_intr::do_for_each(
|
||||
remaps.begin(),
|
||||
remaps.end(),
|
||||
[this, &t, &original_bptr, &ret, &count,
|
||||
original_laddr, original_paddr, original_len](auto &remap) {
|
||||
LOG_PREFIX(TransactionManager::remap_pin);
|
||||
auto remap_offset = remap.offset;
|
||||
auto remap_len = remap.len;
|
||||
auto remap_laddr = original_laddr + remap_offset;
|
||||
auto remap_paddr = original_paddr.add_offset(remap_offset);
|
||||
ceph_assert(remap_len < original_len);
|
||||
ceph_assert(remap_offset + remap_len <= original_len);
|
||||
ceph_assert(remap_len != 0);
|
||||
ceph_assert(remap_offset % cache->get_block_size() == 0);
|
||||
ceph_assert(remap_len % cache->get_block_size() == 0);
|
||||
SUBDEBUGT(seastore_tm,
|
||||
"remap laddr: {}, remap paddr: {}, remap length: {}", t,
|
||||
remap_laddr, remap_paddr, remap_len);
|
||||
return alloc_remapped_extent<T>(
|
||||
t,
|
||||
remap_laddr,
|
||||
remap_paddr,
|
||||
remap_len,
|
||||
original_laddr,
|
||||
std::move(original_bptr)
|
||||
).si_then([&ret, &count, remap_laddr](auto &&npin) {
|
||||
ceph_assert(npin->get_key() == remap_laddr);
|
||||
ret[count++] = std::move(npin);
|
||||
});
|
||||
});
|
||||
}).handle_error_interruptible(
|
||||
remap_pin_iertr::pass_further{},
|
||||
crimson::ct_error::assert_all{
|
||||
"TransactionManager::remap_pin hit invalid error"
|
||||
}
|
||||
).si_then([&ret, &count] {
|
||||
ceph_assert(count == N);
|
||||
return remap_pin_iertr::make_ready_future<
|
||||
std::array<LBAMappingRef, N>>(std::move(ret));
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* map_existing_extent
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user