ceph_assert(extents.empty());
}
+Cache::retire_extent_ret Cache::retire_extent_if_cached(
+ Transaction &t, paddr_t addr)
+{
+ if (auto ext = t.write_set.find_offset(addr); ext != t.write_set.end()) {
+ t.add_to_retired_set(CachedExtentRef(&*ext));
+ return retire_extent_ertr::now();
+ } else if (auto iter = extents.find_offset(addr);
+ iter != extents.end()) {
+ auto ret = CachedExtentRef(&*iter);
+ return ret->wait_io().then([&t, ret=std::move(ret)]() mutable {
+ t.add_to_retired_set(ret);
+ return retire_extent_ertr::now();
+ });
+ } else {
+ return retire_extent_ertr::now();
+ }
+}
+
void Cache::add_extent(CachedExtentRef ref)
{
assert(ref->is_valid());
t.add_to_retired_set(ref);
}
+ /// Declare paddr retired in t, noop if not cached
+ using retire_extent_ertr = crimson::errorator<
+ crimson::ct_error::input_output_error>;
+ using retire_extent_ret = retire_extent_ertr::future<>;
+ retire_extent_ret retire_extent_if_cached(
+ Transaction &t, paddr_t addr);
+
/**
* get_root
*
Transaction &t,
LogicalCachedExtentRef &ref)
{
- return dec_ref(t, ref->get_laddr()
- ).handle_error(
- ref_ertr::pass_further{},
- ct_error::all_same_way([](auto e) {
- ceph_assert(0 == "unhandled error, TODO");
- }));
+ return lba_manager.decref_extent(t, ref->get_laddr()
+ ).safe_then([this, &t, ref](auto ret) {
+ if (ret.refcount == 0) {
+ cache.retire_extent(t, ref);
+ }
+ return ret.refcount;
+ });
}
TransactionManager::ref_ret TransactionManager::dec_ref(
Transaction &t,
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).safe_then([](auto ret) {
- return ret.refcount;
+ return lba_manager.decref_extent(t, offset
+ ).safe_then([this, &t](auto result) -> ref_ret {
+ if (result.refcount == 0) {
+ return cache.retire_extent_if_cached(t, result.addr).safe_then([] {
+ return ref_ret(
+ ref_ertr::ready_future_marker{},
+ 0);
+ });
+ } else {
+ return ref_ret(
+ ref_ertr::ready_future_marker{},
+ result.refcount);
+ }
});
}
});
}
+TEST_F(transaction_manager_test_t, create_remove_same_transaction)
+{
+ constexpr laddr_t SIZE = 4096;
+ run_async([this] {
+ constexpr laddr_t ADDR = 0xFF * SIZE;
+ {
+ auto t = create_transaction();
+ auto extent = alloc_extent(
+ t,
+ ADDR,
+ SIZE,
+ 'a');
+ ASSERT_EQ(ADDR, extent->get_laddr());
+ check_mappings(t);
+ dec_ref(t, ADDR);
+ check_mappings(t);
+
+ extent = alloc_extent(
+ t,
+ ADDR,
+ SIZE,
+ 'a');
+
+ submit_transaction(std::move(t));
+ check_mappings();
+ }
+ replay();
+ check_mappings();
+ });
+}
+
+
TEST_F(transaction_manager_test_t, inc_dec_ref)
{
constexpr laddr_t SIZE = 4096;