Skip to content

Commit 03d4a0e

Browse files
authored
Merge pull request ceph#58983 from cyx1231st/wip-seastore-cleanup-cache
crimson/os/seastore/cache: cleanups and comments Reviewed-by: Xuehan Xu <[email protected]>
2 parents 2c0ea27 + 8c6cede commit 03d4a0e

File tree

6 files changed

+85
-17
lines changed

6 files changed

+85
-17
lines changed

src/crimson/os/seastore/async_cleaner.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,12 +333,12 @@ class ExtentCallbackInterface {
333333
sea_time_point modify_time) = 0;
334334

335335
/**
336-
* get_extent_if_live
336+
* get_extents_if_live
337337
*
338338
* Returns extent at specified location if still referenced by
339339
* lba_manager and not removed by t.
340340
*
341-
* See TransactionManager::get_extent_if_live and
341+
* See TransactionManager::get_extents_if_live and
342342
* LBAManager::get_physical_extent_if_live.
343343
*/
344344
using get_extents_if_live_iertr = base_iertr;

src/crimson/os/seastore/btree/fixed_kv_btree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,9 @@ class FixedKVBtree {
13831383
"looking up root on {}",
13841384
c.trans,
13851385
*root_block);
1386+
1387+
// checking the lba root node must be atomic with creating
1388+
// and linking the absent root node
13861389
auto [found, fut] = get_root_node(c);
13871390

13881391
auto on_found_internal =

src/crimson/os/seastore/cache.h

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,11 @@ class Cache {
437437
* Mostly the same as Cache::get_extent(), with the only difference
438438
* that get_absent_extent won't search the transaction's context for
439439
* the specific CachedExtent
440+
*
441+
* The extent in query is supposed to be absent in Cache.
442+
*
443+
* User is responsible to call get_extent_viewable_by_trans()
444+
* *atomically* prior to call this method.
440445
*/
441446
template <typename T>
442447
get_extent_iertr::future<TCachedExtentRef<T>> get_absent_extent(
@@ -471,18 +476,46 @@ class Cache {
471476
CachedExtentRef extent)
472477
{
473478
assert(extent->is_valid());
474-
auto p_extent = extent->get_transactional_view(t);
475-
if (!p_extent->is_pending_in_trans(t.get_trans_id())) {
476-
t.add_to_read_set(p_extent);
477-
if (!p_extent->is_mutation_pending()) {
478-
touch_extent(*p_extent);
479+
CachedExtent* p_extent;
480+
if (extent->is_stable()) {
481+
p_extent = extent->get_transactional_view(t);
482+
if (p_extent != extent.get()) {
483+
assert(!extent->is_stable_writting());
484+
assert(p_extent->is_pending_in_trans(t.get_trans_id()));
485+
assert(!p_extent->is_stable_writting());
486+
if (p_extent->is_mutable()) {
487+
assert(p_extent->is_fully_loaded());
488+
assert(!p_extent->is_pending_io());
489+
return get_extent_ertr::make_ready_future<CachedExtentRef>(
490+
CachedExtentRef(p_extent));
491+
} else {
492+
assert(p_extent->is_exist_clean());
493+
}
494+
} else {
495+
// stable from trans-view
496+
assert(!p_extent->is_pending_in_trans(t.get_trans_id()));
497+
if (t.maybe_add_to_read_set(p_extent)) {
498+
touch_extent(*p_extent);
499+
}
500+
}
501+
} else {
502+
assert(!extent->is_stable_writting());
503+
assert(extent->is_pending_in_trans(t.get_trans_id()));
504+
if (extent->is_mutable()) {
505+
assert(extent->is_fully_loaded());
506+
assert(!extent->is_pending_io());
507+
return get_extent_ertr::make_ready_future<CachedExtentRef>(extent);
508+
} else {
509+
assert(extent->is_exist_clean());
510+
p_extent = extent.get();
479511
}
480512
}
513+
514+
assert(p_extent->is_stable() || p_extent->is_exist_clean());
481515
// user should not see RETIRED_PLACEHOLDER extents
482516
ceph_assert(p_extent->get_type() != extent_types_t::RETIRED_PLACEHOLDER);
483517
if (!p_extent->is_fully_loaded()) {
484518
assert(!p_extent->is_mutable());
485-
touch_extent(*p_extent);
486519
LOG_PREFIX(Cache::get_extent_viewable_by_trans);
487520
SUBDEBUG(seastore_cache,
488521
"{} {}~{} is present without been fully loaded, reading ... -- {}",
@@ -784,6 +817,9 @@ class Cache {
784817
* and read in the extent at location offset~length.
785818
*
786819
* The extent in query is supposed to be absent in Cache.
820+
*
821+
* User is responsible to call get_extent_viewable_by_trans()
822+
* *atomically* prior to call this method.
787823
*/
788824
template <typename Func>
789825
get_extent_by_type_ret get_absent_extent_by_type(

src/crimson/os/seastore/cached_extent.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,8 @@ class CachedExtent
343343
: "nullopt";
344344
out << "CachedExtent(addr=" << this
345345
<< ", type=" << get_type()
346+
<< ", trans=" << pending_for_transaction
347+
<< ", pending_io=" << is_pending_io()
346348
<< ", version=" << version
347349
<< ", dirty_from_or_retired_at=" << dirty_from_or_retired_at
348350
<< ", modify_time=" << sea_time_point_printer_t{modify_time}
@@ -440,14 +442,18 @@ class CachedExtent
440442
state == extent_state_t::DIRTY;
441443
}
442444

445+
bool is_stable_writting() const {
446+
// MUTATION_PENDING and under-io extents are already stable and visible,
447+
// see prepare_record().
448+
//
449+
// XXX: It might be good to mark this case as DIRTY from the definition,
450+
// which probably can make things simpler.
451+
return is_mutation_pending() && is_pending_io();
452+
}
453+
443454
/// Returns true if extent is stable and shared among transactions
444455
bool is_stable() const {
445-
return is_stable_written() ||
446-
// MUTATION_PENDING and under-io extents are to-be-stable extents,
447-
// for the sake of caveats that checks the correctness of extents
448-
// states, we consider them stable.
449-
(is_mutation_pending() &&
450-
is_pending_io());
456+
return is_stable_written() || is_stable_writting();
451457
}
452458

453459
bool is_data_stable() const {

src/crimson/os/seastore/transaction.h

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,37 @@ class Transaction {
137137
}
138138
}
139139

140+
// Returns true if added, false if already added or weak
141+
bool maybe_add_to_read_set(CachedExtentRef ref) {
142+
if (is_weak()) {
143+
return false;
144+
}
145+
146+
assert(ref->is_valid());
147+
148+
auto it = ref->transactions.lower_bound(
149+
this, read_set_item_t<Transaction>::trans_cmp_t());
150+
if (it != ref->transactions.end() && it->t == this) {
151+
return false;
152+
}
153+
154+
auto [iter, inserted] = read_set.emplace(this, ref);
155+
ceph_assert(inserted);
156+
ref->transactions.insert_before(
157+
it, const_cast<read_set_item_t<Transaction>&>(*iter));
158+
return true;
159+
}
160+
140161
void add_to_read_set(CachedExtentRef ref) {
141-
if (is_weak()) return;
162+
if (is_weak()) {
163+
return;
164+
}
142165

143166
assert(ref->is_valid());
144167

145168
auto it = ref->transactions.lower_bound(
146169
this, read_set_item_t<Transaction>::trans_cmp_t());
147-
if (it != ref->transactions.end() && it->t == this) return;
170+
assert(it == ref->transactions.end() || it->t != this);
148171

149172
auto [iter, inserted] = read_set.emplace(this, ref);
150173
ceph_assert(inserted);

src/crimson/os/seastore/transaction_manager.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ TransactionManager::get_extents_if_live(
680680
laddr_t laddr,
681681
extent_len_t len)
682682
{
683-
LOG_PREFIX(TransactionManager::get_extent_if_live);
683+
LOG_PREFIX(TransactionManager::get_extents_if_live);
684684
TRACET("{} {}~{} {}", t, type, laddr, len, paddr);
685685

686686
// This only works with segments to check if alive,

0 commit comments

Comments
 (0)