Skip to content

Commit 8a213d2

Browse files
committed
crimson/os/seastore/transaction_manager: linking retired placeholders to
lba leaf nodes must be synchronous with getting child pos Signed-off-by: Xuehan Xu <[email protected]>
1 parent 8d30cff commit 8a213d2

File tree

2 files changed

+38
-29
lines changed

2 files changed

+38
-29
lines changed

src/crimson/os/seastore/lba_mapping.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ class LBAMapping {
4646
LBAMapping &operator=(LBAMapping &&) = default;
4747
~LBAMapping() = default;
4848

49+
// whether the removal of this mapping would cause
50+
// other mappings to be removed.
51+
//
52+
// Note that this should only be called on complete
53+
// indirect mappings
54+
bool would_cascade_remove() const {
55+
assert(is_indirect());
56+
assert(is_complete_indirect());
57+
return direct_cursor->get_refcount() == 1;
58+
}
59+
4960
// whether the mapping corresponds to a pending extent
5061
bool is_pending() const {
5162
return !is_indirect() && !is_data_stable();

src/crimson/os/seastore/transaction_manager.cc

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -292,34 +292,35 @@ TransactionManager::_remove_indirect_mapping(
292292
});
293293
});
294294
} else {
295-
auto unlinked_child = std::move(std::get<0>(ret));
295+
auto remove_direct = mapping.would_cascade_remove();
296+
if (remove_direct) {
297+
auto unlinked_child = std::move(std::get<0>(ret));
298+
auto retired_placeholder = cache->retire_absent_extent_addr(
299+
t, mapping.get_intermediate_base(),
300+
mapping.get_val(),
301+
mapping.get_intermediate_length()
302+
)->template cast<RetiredExtentPlaceholder>();
303+
unlinked_child.child_pos.link_child(retired_placeholder.get());
304+
}
296305
return lba_manager->remove_mapping(t, std::move(mapping)
297-
).si_then([child_pos=unlinked_child.child_pos, &t,
298-
FNAME, this](auto result) mutable {
306+
).si_then([&t, FNAME, remove_direct](auto result) mutable {
299307
ceph_assert(result.direct_result);
300308
auto &primary_result = result.result;
301309
ceph_assert(primary_result.refcount == 0);
302310
auto &direct_result = *result.direct_result;
303311
ceph_assert(direct_result.addr.is_paddr());
304312
ceph_assert(!direct_result.addr.get_paddr().is_zero());
305-
if (direct_result.refcount == 0) {
306-
auto retired_placeholder = cache->retire_absent_extent_addr(
307-
t, direct_result.key,
308-
direct_result.addr.get_paddr(),
309-
direct_result.length
310-
)->template cast<RetiredExtentPlaceholder>();
311-
child_pos.link_child(retired_placeholder.get());
312-
}
313-
DEBUGT("removed indirect mapping {}~0x{:x} refcount={} offset={} "
314-
"with direct mapping {}~0x{:x} refcount={} offset={}",
315-
t, primary_result.addr,
316-
primary_result.length,
317-
primary_result.refcount,
318-
primary_result.key,
319-
direct_result.addr,
320-
direct_result.length,
321-
direct_result.refcount,
322-
direct_result.key);
313+
ceph_assert(remove_direct == (direct_result.refcount == 0));
314+
DEBUGT("removed indirect mapping {}~0x{:x} refcount={} offset={} "
315+
"with direct mapping {}~0x{:x} refcount={} offset={}",
316+
t, primary_result.addr,
317+
primary_result.length,
318+
primary_result.refcount,
319+
primary_result.key,
320+
direct_result.addr,
321+
direct_result.length,
322+
direct_result.refcount,
323+
direct_result.key);
323324
return ref_iertr::make_ready_future<
324325
_remove_mapping_result_t>(std::move(result));
325326
});
@@ -356,19 +357,16 @@ TransactionManager::_remove_direct_mapping(
356357
});
357358
} else {
358359
auto unlinked_child = std::move(std::get<0>(ret));
360+
auto retired_placeholder = cache->retire_absent_extent_addr(
361+
t, mapping.get_key(), mapping.get_val(), mapping.get_length()
362+
)->template cast<RetiredExtentPlaceholder>();
363+
unlinked_child.child_pos.link_child(retired_placeholder.get());
359364
return lba_manager->remove_mapping(t, std::move(mapping)
360-
).si_then([child_pos=unlinked_child.child_pos, &t,
361-
FNAME, this](auto result) mutable {
365+
).si_then([&t, FNAME](auto result) mutable {
362366
auto &primary_result = result.result;
363367
ceph_assert(primary_result.refcount == 0);
364368
ceph_assert(primary_result.addr.is_paddr());
365369
ceph_assert(!primary_result.addr.get_paddr().is_zero());
366-
auto retired_placeholder = cache->retire_absent_extent_addr(
367-
t, primary_result.key,
368-
primary_result.addr.get_paddr(),
369-
primary_result.length
370-
)->template cast<RetiredExtentPlaceholder>();
371-
child_pos.link_child(retired_placeholder.get());
372370
DEBUGT("removed {}~0x{:x} refcount={} -- offset={}",
373371
t, primary_result.addr, primary_result.length,
374372
primary_result.refcount, primary_result.key);

0 commit comments

Comments
 (0)