Transaction &t,
laddr_t off, extent_len_t len, paddr_t addr) = 0;
+
+ struct ref_update_result_t {
+ unsigned refcount = 0;
+ paddr_t addr;
+ };
using ref_ertr = crimson::errorator<
crimson::ct_error::enoent,
crimson::ct_error::input_output_error>;
- using ref_ret = ref_ertr::future<unsigned>;
+ using ref_ret = ref_ertr::future<ref_update_result_t>;
/**
* Decrements ref count on extent
lba_map_val_t out = in;
ceph_assert((int)out.refcount + delta >= 0);
out.refcount += delta;
- if (out.refcount == 0) {
- return std::optional<lba_map_val_t>();
- } else {
- return std::optional<lba_map_val_t>(out);
- }
+ return out;
}).safe_then([](auto result) {
- if (!result)
- return 0u;
- else
- return result->refcount;
+ return ref_update_result_t{result.refcount, result.paddr};
});
}
* Updates mapping, removes if f returns nullopt
*/
using update_mapping_ertr = ref_ertr;
- using update_mapping_ret = ref_ertr::future<std::optional<lba_map_val_t>>;
+ using update_mapping_ret = ref_ertr::future<lba_map_val_t>;
using update_func_t = LBANode::mutate_func_t;
update_mapping_ret update_mapping(
Transaction &t,
crimson::ct_error::input_output_error
>;
using mutate_mapping_ret = mutate_mapping_ertr::future<
- std::optional<lba_map_val_t>>;
+ lba_map_val_t>;
using mutate_func_t = std::function<
- std::optional<lba_map_val_t>(const lba_map_val_t &v)
+ lba_map_val_t(const lba_map_val_t &v)
>;
virtual mutate_mapping_ret mutate_mapping(
op_context_t c,
ceph_assert(!at_min_capacity());
auto mutation_pt = find(laddr);
if (mutation_pt == end()) {
- ceph_assert(0 == "should be impossible");
- return mutate_mapping_ret(
- mutate_mapping_ertr::ready_future_marker{},
- std::nullopt);
+ return crimson::ct_error::enoent::make();
}
auto mutated = f(mutation_pt.get_val());
- if (mutated) {
- journal_update(mutation_pt, *mutated, maybe_get_delta_buffer());
+ if (mutated.refcount > 0) {
+ journal_update(mutation_pt, mutated, maybe_get_delta_buffer());
return mutate_mapping_ret(
mutate_mapping_ertr::ready_future_marker{},
mutated);
Transaction &t,
LogicalCachedExtentRef &ref)
{
- return lba_manager.incref_extent(t, ref->get_laddr()
- ).handle_error(
+ return lba_manager.incref_extent(t, ref->get_laddr()).safe_then([](auto r) {
+ return r.refcount;
+ }).handle_error(
ref_ertr::pass_further{},
ct_error::all_same_way([](auto e) {
ceph_assert(0 == "unhandled error, TODO");
Transaction &t,
laddr_t offset)
{
- return lba_manager.incref_extent(t, offset);
+ return lba_manager.incref_extent(t, offset).safe_then([](auto result) {
+ return result.refcount;
+ });
}
TransactionManager::ref_ret TransactionManager::dec_ref(
laddr_t offset)
{
// TODO: need to retire the extent (only) if it's live, will need cache call
- return lba_manager.decref_extent(t, offset);
+ return lba_manager.decref_extent(t, offset).safe_then([](auto ret) {
+ return ret.refcount;
+ });
}
TransactionManager::submit_transaction_ertr::future<>
return ret;
}
+
using ref_ertr = LBAManager::ref_ertr;
- using ref_ret = LBAManager::ref_ret;
+ using ref_ret = ref_ertr::future<unsigned>;
/// Add refcount for ref
ref_ret inc_ref(
auto refcnt = lba_manager->decref_extent(
*t.t,
- target->first).unsafe_get0();
+ target->first).unsafe_get0().refcount;
EXPECT_EQ(refcnt, target->second.refcount);
if (target->second.refcount == 0) {
t.mappings.erase(target);
target->second.refcount++;
auto refcnt = lba_manager->incref_extent(
*t.t,
- target->first).unsafe_get0();
+ target->first).unsafe_get0().refcount;
EXPECT_EQ(refcnt, target->second.refcount);
}