assert(mapping.is_viewable());
assert(mapping.is_indirect() == mapping.is_complete_indirect());
auto c = get_context(t);
- return with_btree<LBABtree>(
- cache,
- c,
- [mapping=std::move(mapping), c, this,
- remaps=std::move(remaps)](auto &btree) mutable {
- auto &cursor = mapping.get_effective_cursor();
- return seastar::do_with(
- std::move(remaps),
- std::move(mapping),
- btree.make_partial_iter(c, cursor),
- std::vector<LBAMapping>(),
- [c, &btree, this, &cursor](auto &remaps, auto &mapping, auto &iter, auto &ret) {
- auto val = iter.get_val();
- assert(val.refcount == EXTENT_DEFAULT_REF_COUNT);
- assert(mapping.is_indirect() ||
- (val.pladdr.is_paddr() &&
- val.pladdr.get_paddr().is_absolute()));
- auto old_key = mapping.get_key();
- auto old_length = mapping.get_length();
- auto old_indirect = mapping.is_indirect();
- return update_refcount(c.trans, &cursor, -1
- ).si_then([old_key, old_length, old_indirect,
- &btree, &iter, c, &ret, &remaps,
- pladdr=val.pladdr](auto r) {
- assert(r.refcount == 0);
- auto &cursor = r.mapping.get_effective_cursor();
- iter = btree.make_partial_iter(c, cursor);
- return trans_intr::do_for_each(
- remaps,
- [old_key, old_length, old_indirect, &btree,
- &iter, c, &ret, pladdr](auto &remap) {
- assert(remap.offset + remap.len <= old_length);
- assert((bool)remap.extent == !old_indirect);
- lba_map_val_t val;
- auto new_key = (old_key + remap.offset).checked_to_laddr();
- val.len = remap.len;
- if (pladdr.is_laddr()) {
- auto laddr = pladdr.get_laddr();
- val.pladdr = (laddr + remap.offset).checked_to_laddr();
- } else {
- auto paddr = pladdr.get_paddr();
- val.pladdr = paddr + remap.offset;
- }
- val.refcount = EXTENT_DEFAULT_REF_COUNT;
- // Checksum will be updated when the committing the transaction
- val.checksum = CRC_NULL;
- return btree.insert(
- c, iter, new_key, std::move(val),
- old_indirect
- ? get_reserved_ptr<LBALeafNode, laddr_t>()
- : remap.extent
- ).si_then([c, old_indirect, &ret, &iter](auto p) {
- auto &[it, inserted] = p;
- ceph_assert(inserted);
- if (old_indirect) {
- ret.push_back(
- LBAMapping::create_indirect(nullptr, it.get_cursor(c)));
- } else {
- ret.push_back(
- LBAMapping::create_direct(it.get_cursor(c)));
- }
- return it.next(c).si_then([&iter](auto it) {
- iter = std::move(it);
- });
- });
- });
- }).si_then([&mapping, &ret] {
- if (mapping.is_indirect()) {
- auto &cursor = mapping.direct_cursor;
- return cursor->refresh(
- ).si_then([&ret, &mapping] {
- for (auto &m : ret) {
- m.direct_cursor = mapping.direct_cursor;
- }
- });
- }
- return base_iertr::now();
- }).si_then([this, c, &mapping, &remaps] {
- if (remaps.size() > 1 && mapping.is_indirect()) {
- auto &cursor = mapping.direct_cursor;
- assert(cursor->is_viewable());
- return update_refcount(
- c.trans, cursor.get(), 1).discard_result();
- }
- return update_refcount_iertr::now();
- }).si_then([&ret] {
- return trans_intr::parallel_for_each(
- ret,
- [](auto &remapped_mapping) {
- return remapped_mapping.refresh(
- ).si_then([&remapped_mapping](auto mapping) {
- remapped_mapping = std::move(mapping);
- });
- });
- }).si_then([&ret] {
- return std::move(ret);
+ auto btree = co_await get_btree<LBABtree>(cache, c);
+ auto iter = btree.make_partial_iter(c, mapping.get_effective_cursor());
+ std::vector<LBAMapping> ret;
+ auto val = iter.get_val();
+ assert(val.refcount == EXTENT_DEFAULT_REF_COUNT);
+ assert(mapping.is_indirect() ||
+ (val.pladdr.is_paddr() &&
+ val.pladdr.get_paddr().is_absolute()));
+ auto old_key = mapping.get_key();
+ auto old_length = mapping.get_length();
+ auto old_indirect = mapping.is_indirect();
+ auto updated_cursor = co_await update_mapping_refcount(
+ c.trans, mapping.get_effective_cursor_ref(), -1);
+ iter = btree.make_partial_iter(c, *updated_cursor);
+ for (auto &remap : remaps) {
+ assert(remap.offset + remap.len <= old_length);
+ assert((bool)remap.extent == !old_indirect);
+ lba_map_val_t val;
+ auto new_key = (old_key + remap.offset).checked_to_laddr();
+ val.len = remap.len;
+ if (val.pladdr.is_laddr()) {
+ auto laddr = val.pladdr.get_laddr();
+ val.pladdr = (laddr + remap.offset).checked_to_laddr();
+ } else {
+ auto paddr = val.pladdr.get_paddr();
+ val.pladdr = paddr + remap.offset;
+ }
+ val.refcount = EXTENT_DEFAULT_REF_COUNT;
+ // Checksum will be updated when the committing the transaction
+ val.checksum = CRC_NULL;
+ // committing the transaction
+ auto p = co_await btree.insert(
+ c, iter, new_key, std::move(val),
+ old_indirect
+ ? get_reserved_ptr<LBALeafNode, laddr_t>()
+ : remap.extent);
+ auto &[it, inserted] = p;
+ ceph_assert(inserted);
+ if (old_indirect) {
+ ret.push_back(
+ LBAMapping::create_indirect(nullptr, it.get_cursor(c)));
+ } else {
+ ret.push_back(
+ LBAMapping::create_direct(it.get_cursor(c)));
+ }
+ it = co_await it.next(c);
+ iter = std::move(it);
+ }
+ if (mapping.is_indirect()) {
+ co_await mapping.direct_cursor->refresh();
+ for (auto &m : ret) {
+ m.direct_cursor = mapping.direct_cursor;
+ }
+ }
+ if (remaps.size() > 1 && mapping.is_indirect()) {
+ assert(mapping.direct_cursor->is_viewable());
+ co_await update_mapping_refcount(c.trans, mapping.direct_cursor, 1);
+ }
+ co_await trans_intr::parallel_for_each(
+ ret,
+ [](auto &remapped_mapping) {
+ return remapped_mapping.refresh(
+ ).si_then([&remapped_mapping](auto mapping) {
+ remapped_mapping = std::move(mapping);
});
});
- });
+ co_return ret;
}
}