@@ -788,6 +788,106 @@ BtreeLBAManager::_decref_intermediate(
788788 });
789789}
790790
791+ BtreeLBAManager::remap_ret
792+ BtreeLBAManager::remap_mappings (
793+ Transaction &t,
794+ LBAMapping orig_mapping,
795+ std::vector<remap_entry_t > remaps,
796+ std::vector<LogicalChildNodeRef> extents)
797+ {
798+ LOG_PREFIX (BtreeLBAManager::remap_mappings);
799+ struct state_t {
800+ LBAMapping orig_mapping;
801+ std::vector<remap_entry_t > remaps;
802+ std::vector<LogicalChildNodeRef> extents;
803+ std::vector<alloc_mapping_info_t > alloc_infos;
804+ std::vector<LBAMapping> ret;
805+ };
806+ return seastar::do_with (
807+ state_t (std::move (orig_mapping), std::move (remaps), std::move (extents), {}, {}),
808+ [this , &t, FNAME](state_t &state)
809+ {
810+ return update_refcount (
811+ t, state.orig_mapping .get_key (), -1 , false
812+ ).si_then ([this , &t, &state, FNAME](auto ret) {
813+ // Remapping the shared direct mapping is prohibited,
814+ // the refcount of indirect mapping should always be 1.
815+ ceph_assert (ret.is_removed_mapping ());
816+
817+ auto orig_laddr = state.orig_mapping .get_key ();
818+ if (!state.orig_mapping .is_indirect ()) {
819+ auto &addr = ret.get_removed_mapping ().map_value .pladdr ;
820+ ceph_assert (addr.is_paddr () && !addr.get_paddr ().is_zero ());
821+ return alloc_extents (
822+ t,
823+ (state.remaps .front ().offset + orig_laddr).checked_to_laddr (),
824+ std::move (state.extents ),
825+ EXTENT_DEFAULT_REF_COUNT
826+ ).si_then ([&state](auto ret) {
827+ state.ret = std::move (ret);
828+ return remap_iertr::make_ready_future ();
829+ });
830+ }
831+
832+ extent_len_t orig_len = state.orig_mapping .get_length ();
833+ auto intermediate_key = state.orig_mapping .get_intermediate_key ();
834+ ceph_assert (intermediate_key != L_ADDR_NULL);
835+ DEBUGT (" remap indirect mapping {}" , t, state.orig_mapping );
836+ for (auto &remap : state.remaps ) {
837+ DEBUGT (" remap 0x{:x}~0x{:x}" , t, remap.offset , remap.len );
838+ ceph_assert (remap.len != 0 );
839+ ceph_assert (remap.offset + remap.len <= orig_len);
840+ auto remapped_laddr = (orig_laddr + remap.offset )
841+ .checked_to_laddr ();
842+ auto remapped_intermediate_key = (intermediate_key + remap.offset )
843+ .checked_to_laddr ();
844+ state.alloc_infos .emplace_back (
845+ alloc_mapping_info_t::create_indirect (
846+ remapped_laddr, remap.len , remapped_intermediate_key));
847+ }
848+
849+ return alloc_sparse_mappings (
850+ t, state.alloc_infos .front ().key , state.alloc_infos ,
851+ alloc_policy_t ::deterministic
852+ ).si_then ([&t, &state, this ](std::list<LBACursorRef> cursors) {
853+ return seastar::futurize_invoke ([&t, &state, this ] {
854+ if (state.remaps .size () > 1 ) {
855+ auto base = state.orig_mapping .get_intermediate_base ();
856+ return update_refcount (
857+ t, base, state.remaps .size () - 1 , false
858+ ).si_then ([](update_mapping_ret_bare_t ret) {
859+ return ret.take_cursor ();
860+ });
861+ } else {
862+ return remap_iertr::make_ready_future<
863+ LBACursorRef>(state.orig_mapping .direct_cursor ->duplicate ());
864+ }
865+ }).si_then ([&state, cursors=std::move (cursors)](auto direct) mutable {
866+ for (auto &cursor : cursors) {
867+ state.ret .emplace_back (LBAMapping::create_indirect (
868+ direct->duplicate (), std::move (cursor)));
869+ }
870+ return remap_iertr::make_ready_future ();
871+ });
872+ });
873+ }).si_then ([&state] {
874+ assert (state.ret .size () == state.remaps .size ());
875+ #ifndef NDEBUG
876+ auto mapping_it = state.ret .begin ();
877+ auto remap_it = state.remaps .begin ();
878+ for (;mapping_it != state.ret .end (); mapping_it++, remap_it++) {
879+ auto &mapping = *mapping_it;
880+ auto &remap = *remap_it;
881+ assert (mapping.get_key () == state.orig_mapping .get_key () + remap.offset );
882+ assert (mapping.get_length () == remap.len );
883+ }
884+ #endif
885+ return remap_iertr::make_ready_future<
886+ std::vector<LBAMapping>>(std::move (state.ret ));
887+ });
888+ });
889+ }
890+
791891BtreeLBAManager::update_refcount_ret
792892BtreeLBAManager::update_refcount (
793893 Transaction &t,
0 commit comments