return fut.si_then([this, c, &mapping](auto cursor) {
mapping.direct_cursor = cursor;
assert(mapping.direct_cursor->is_viewable());
- return update_refcount(c.trans, cursor.get(), 1, false
+ return update_refcount(c.trans, cursor.get(), 1
).si_then([&mapping](auto res) {
- assert(!res.result.mapping.is_indirect());
- mapping.direct_cursor = std::move(res.result.mapping.direct_cursor);
+ assert(!res.mapping.is_indirect());
+ mapping.direct_cursor = std::move(res.mapping.direct_cursor);
return std::move(mapping);
});
});
BtreeLBAManager::update_refcount(
Transaction &t,
std::variant<laddr_t, LBACursor*> addr_or_cursor,
- int delta,
- bool cascade_remove)
+ int delta)
{
auto addr = addr_or_cursor.index() == 0
? std::get<0>(addr_or_cursor)
auto &cursor = std::get<1>(addr_or_cursor);
fut = _update_mapping(t, *cursor, std::move(update_func), nullptr);
}
- return fut.si_then([delta, &t, addr, FNAME, this, cascade_remove](auto res) {
+ return fut.si_then([delta, &t, addr, FNAME, this](auto res) {
DEBUGT("laddr={}, delta={} done -- {}",
t, addr, delta,
res.is_alive_mapping()
? res.get_cursor().val
: res.get_removed_mapping().map_value);
-
- if (res.is_removed_mapping() && cascade_remove &&
- res.get_removed_mapping().map_value.pladdr.is_laddr()) {
- auto &val = res.get_removed_mapping().map_value;
- TRACET("decref intermediate {} -> {}",
- t, addr, val.pladdr.get_laddr());
- return _decref_intermediate(t, val.pladdr.get_laddr(), val.len
- ).si_then([indirect_res=std::move(res), this](auto res) mutable {
- return indirect_res.get_removed_mapping().next->refresh(
- ).si_then([this, res=std::move(res),
- ires=std::move(indirect_res)]() mutable {
- return update_mapping_iertr::make_ready_future<
- ref_update_result_t>(get_ref_update_result(ires, std::move(res)));
- });
- }).handle_error_interruptible(
- update_mapping_iertr::pass_further{},
- crimson::ct_error::assert_all{
- "unexpect ENOENT"
- }
- );
- }
return update_mapping_iertr::make_ready_future<
- ref_update_result_t>(get_ref_update_result(res, std::nullopt));
+ mapping_update_result_t>(get_mapping_update_result(res));
});
}
assert(mapping.is_indirect() ||
(val.pladdr.is_paddr() &&
val.pladdr.get_paddr().is_absolute()));
- return update_refcount(c.trans, &cursor, -1, false
+ return update_refcount(c.trans, &cursor, -1
).si_then([&mapping, &btree, &iter, c, &ret,
&remaps, pladdr=val.pladdr](auto r) {
- assert(r.result.refcount == 0);
- auto &cursor = r.result.mapping.get_effective_cursor();
+ 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,
auto &cursor = mapping.direct_cursor;
assert(cursor->is_viewable());
return update_refcount(
- c.trans, cursor.get(), 1, false).discard_result();
+ c.trans, cursor.get(), 1).discard_result();
}
return update_refcount_iertr::now();
}).si_then([&ret] {
ref_ret remove_mapping(
Transaction &t,
laddr_t addr) final {
- return update_refcount(t, addr, -1, true);
+ return update_refcount(t, addr, -1
+ ).si_then([this, &t](auto res) {
+ ceph_assert(res.refcount == 0);
+ if (res.addr.is_paddr()) {
+ return ref_iertr::make_ready_future<
+ ref_update_result_t>(ref_update_result_t{
+ std::move(res), std::nullopt});
+ }
+ return update_refcount(t, res.key, -1
+ ).si_then([indirect_result=std::move(res)](auto direct_result) mutable {
+ return indirect_result.mapping.refresh(
+ ).si_then([direct_result=std::move(direct_result),
+ indirect_result=std::move(indirect_result)](auto) {
+ return ref_iertr::make_ready_future<
+ ref_update_result_t>(ref_update_result_t{
+ std::move(indirect_result),
+ std::move(direct_result)});
+ });
+ });
+ });
}
ref_ret remove_mapping(
Transaction &t,
LBAMapping mapping) final {
assert(mapping.is_viewable());
+ assert(mapping.is_complete());
return seastar::do_with(
std::move(mapping),
[&t, this](auto &mapping) {
auto &cursor = mapping.get_effective_cursor();
- return update_refcount(t, &cursor, -1, true);
+ return update_refcount(t, &cursor, -1
+ ).si_then([this, &t, &mapping](auto res) {
+ ceph_assert(res.refcount == 0);
+ if (res.addr.is_paddr()) {
+ assert(!mapping.is_indirect());
+ return ref_iertr::make_ready_future<
+ ref_update_result_t>(ref_update_result_t{
+ std::move(res), std::nullopt});
+ }
+ assert(mapping.is_indirect());
+ auto &cursor = *mapping.direct_cursor;
+ return cursor.refresh().si_then([this, &t, &cursor] {
+ return update_refcount(t, &cursor, -1);
+ }).si_then([indirect_result=std::move(res)]
+ (auto direct_result) mutable {
+ return indirect_result.mapping.refresh(
+ ).si_then([direct_result=std::move(direct_result),
+ indirect_result=std::move(indirect_result)](auto) {
+ return ref_iertr::make_ready_future<
+ ref_update_result_t>(ref_update_result_t{
+ std::move(indirect_result),
+ std::move(direct_result)});
+ });
+ });
+ });
});
}
ref_ret incref_extent(
Transaction &t,
laddr_t addr) final {
- return update_refcount(t, addr, 1, false);
+ return update_refcount(t, addr, 1
+ ).si_then([](auto res) {
+ return ref_update_result_t(std::move(res), std::nullopt);
+ });
}
ref_ret incref_extent(
std::move(mapping),
[&t, this](auto &mapping) {
auto &cursor = mapping.get_effective_cursor();
- return update_refcount(t, &cursor, 1, false);
+ return update_refcount(t, &cursor, 1
+ ).si_then([](auto res) {
+ return ref_update_result_t(std::move(res), std::nullopt);
+ });
});
}
using update_refcount_iertr = ref_iertr;
using update_refcount_ret = update_refcount_iertr::future<
- ref_update_result_t>;
+ mapping_update_result_t>;
update_refcount_ret update_refcount(
Transaction &t,
std::variant<laddr_t, LBACursor*> addr_or_cursor,
- int delta,
- bool cascade_remove);
+ int delta);
/**
* _update_mapping
laddr_t addr,
int delta) {
ceph_assert(delta > 0);
- return update_refcount(t, addr, delta, false);
+ return update_refcount(t, addr, delta
+ ).si_then([](auto res) {
+ return ref_update_result_t(std::move(res), std::nullopt);
+ });
}
using _get_cursor_ret = get_mapping_iertr::future<LBACursorRef>;
LBAMapping mapping)
{
LOG_PREFIX(TransactionManager::remove);
- return mapping.refresh().si_then([&t, this, FNAME](auto mapping) {
+ return mapping.refresh().si_then([&t, this](auto mapping) {
+ if (mapping.is_indirect()) {
+ return lba_manager->complete_indirect_lba_mapping(t, std::move(mapping));
+ }
+ return LBAManager::complete_lba_mapping_iertr::make_ready_future<
+ LBAMapping>(std::move(mapping));
+ }).si_then([&t, this, FNAME](auto mapping) {
auto fut = base_iertr::make_ready_future<LogicalChildNodeRef>();
if (!mapping.is_indirect() && mapping.get_val().is_real_location()) {
auto ret = get_extent_if_linked<LogicalChildNode>(t, mapping);