Skip to content

Commit 6d060ba

Browse files
authored
Merge pull request ceph#63972 from cyx1231st/wip-seastore-refine-extent-states-p2
crimson/os/seastore: update extent states from pending to stable upon prepare_record() Reviewed-by: Xuehan Xu <[email protected]>
2 parents d78ffd1 + b3187f4 commit 6d060ba

File tree

12 files changed

+157
-144
lines changed

12 files changed

+157
-144
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ class FixedKVBtree {
490490
}
491491
}
492492
if (ret == Transaction::get_extent_ret::PRESENT) {
493-
if (child_node->is_stable_written()) {
493+
if (child_node->is_stable_ready()) {
494494
assert(child_node->is_valid());
495495
auto cnode = child_node->template cast<child_node_t>();
496496
assert(cnode->has_parent_tracker());
@@ -1237,7 +1237,7 @@ class FixedKVBtree {
12371237
// This can only happen during init_cached_extent
12381238
// or when backref extent being rewritten by gc space reclaiming
12391239
if (ret->is_stable() && !ret->is_linked()) {
1240-
assert(ret->has_delta() || is_backref_node(ret->get_type()));
1240+
assert(ret->is_stable_dirty() || is_backref_node(ret->get_type()));
12411241
init_internal(*ret);
12421242
}
12431243
auto meta = ret->get_meta();
@@ -1320,7 +1320,7 @@ class FixedKVBtree {
13201320
// This can only happen during init_cached_extent
13211321
// or when backref extent being rewritten by gc space reclaiming
13221322
if (ret->is_stable() && !ret->is_linked()) {
1323-
assert(ret->has_delta() || is_backref_node(ret->get_type()));
1323+
assert(ret->is_stable_dirty() || is_backref_node(ret->get_type()));
13241324
init_leaf(*ret);
13251325
}
13261326
auto meta = ret->get_meta();

src/crimson/os/seastore/cache.cc

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ void Cache::add_extent(CachedExtentRef ref)
739739
void Cache::mark_dirty(CachedExtentRef ref)
740740
{
741741
assert(ref->get_paddr().is_absolute());
742-
if (ref->has_delta()) {
742+
if (ref->is_stable_dirty()) {
743743
assert(ref->primary_ref_list_hook.is_linked());
744744
return;
745745
}
@@ -753,15 +753,13 @@ void Cache::add_to_dirty(
753753
CachedExtentRef ref,
754754
const Transaction::src_t* p_src)
755755
{
756-
assert(ref->has_delta());
756+
assert(ref->is_stable_dirty());
757757
assert(!ref->primary_ref_list_hook.is_linked());
758758
ceph_assert(ref->get_modify_time() != NULL_TIME);
759759
assert(ref->is_fully_loaded());
760760
assert(ref->get_paddr().is_absolute() ||
761761
ref->get_paddr().is_root());
762762

763-
// Note: next might not be at extent_state_t::DIRTY,
764-
// also see CachedExtent::is_stable_writting()
765763
intrusive_ptr_add_ref(&*ref);
766764
dirty.push_back(*ref);
767765

@@ -785,7 +783,7 @@ void Cache::remove_from_dirty(
785783
CachedExtentRef ref,
786784
const Transaction::src_t* p_src)
787785
{
788-
assert(ref->has_delta());
786+
assert(ref->is_stable_dirty());
789787
ceph_assert(ref->primary_ref_list_hook.is_linked());
790788
assert(ref->is_fully_loaded());
791789
assert(ref->get_paddr().is_absolute() ||
@@ -817,13 +815,11 @@ void Cache::replace_dirty(
817815
CachedExtentRef prev,
818816
const Transaction::src_t& src)
819817
{
820-
assert(prev->has_delta());
818+
assert(prev->is_stable_dirty());
821819
ceph_assert(prev->primary_ref_list_hook.is_linked());
822820
assert(prev->is_fully_loaded());
823821

824-
// Note: next might not be at extent_state_t::DIRTY,
825-
// also see CachedExtent::is_stable_writting()
826-
assert(next->has_delta());
822+
assert(next->is_stable_dirty());
827823
assert(!next->primary_ref_list_hook.is_linked());
828824
ceph_assert(next->get_modify_time() != NULL_TIME);
829825
assert(next->is_fully_loaded());
@@ -849,7 +845,7 @@ void Cache::clear_dirty()
849845
{
850846
for (auto i = dirty.begin(); i != dirty.end(); ) {
851847
auto ptr = &*i;
852-
assert(ptr->has_delta());
848+
assert(ptr->is_stable_dirty());
853849
ceph_assert(ptr->primary_ref_list_hook.is_linked());
854850
assert(ptr->is_fully_loaded());
855851

@@ -873,7 +869,7 @@ void Cache::remove_extent(
873869
assert(ref->is_valid());
874870
assert(ref->get_paddr().is_absolute() ||
875871
ref->get_paddr().is_root());
876-
if (ref->has_delta()) {
872+
if (ref->is_stable_dirty()) {
877873
remove_from_dirty(ref, p_src);
878874
} else if (!ref->is_placeholder()) {
879875
assert(ref->get_paddr().is_absolute());
@@ -905,21 +901,18 @@ void Cache::commit_replace_extent(
905901

906902
const auto t_src = t.get_src();
907903
if (is_root_type(prev->get_type())) {
908-
assert(prev->is_stable_clean()
909-
|| prev->primary_ref_list_hook.is_linked());
910-
if (prev->has_delta()) {
911-
// add the new dirty root to front
912-
remove_from_dirty(prev, nullptr/* exclude root */);
913-
}
904+
assert(prev->is_stable_dirty());
905+
assert(prev->primary_ref_list_hook.is_linked());
906+
// add the new dirty root to front
907+
remove_from_dirty(prev, nullptr/* exclude root */);
914908
add_to_dirty(next, nullptr/* exclude root */);
915-
} else if (prev->has_delta()) {
909+
} else if (prev->is_stable_dirty()) {
916910
replace_dirty(next, prev, t_src);
917911
} else {
918912
lru.remove_from_lru(*prev);
919913
add_to_dirty(next, &t_src);
920914
}
921915

922-
next->on_replace_prior();
923916
invalidate_extent(t, *prev);
924917
}
925918

@@ -1306,14 +1299,9 @@ record_t Cache::prepare_record(
13061299
i->prepare_commit();
13071300

13081301
if (i->is_mutation_pending()) {
1309-
i->set_io_wait();
1310-
// extent with EXIST_MUTATION_PENDING doesn't have
1311-
// prior_instance field so skip these extents.
1312-
// the existing extents should be added into Cache
1313-
// during complete_commit to sync with gc transaction.
1314-
commit_replace_extent(t, i, i->prior_instance);
1315-
} // Note, else, add_extent() below
1316-
// Note, i->state become DIRTY in complete_commit()
1302+
i->on_replace_prior();
1303+
} // else, is_exist_mutation_pending():
1304+
// - it doesn't have prior_instance to replace
13171305

13181306
assert(i->get_version() > 0);
13191307
auto final_crc = i->calc_crc32c();
@@ -1381,6 +1369,24 @@ record_t Cache::prepare_record(
13811369
e->prepare_commit();
13821370
});
13831371

1372+
/*
1373+
* We can only update extent states after the logical linked tree is
1374+
* resolved:
1375+
* - on_replace_prior()
1376+
* - prepare_commit()
1377+
*/
1378+
for (auto &i: t.mutated_block_list) {
1379+
if (i->is_valid()) {
1380+
if (i->is_mutation_pending()) {
1381+
i->set_io_wait(CachedExtent::extent_state_t::DIRTY);
1382+
commit_replace_extent(t, i, i->prior_instance);
1383+
} // else, is_exist_mutation_pending():
1384+
// - it doesn't have prior_instance to replace
1385+
// - and add_extent() atomically below
1386+
// - set_io_wait(DIRTY) atomically below
1387+
}
1388+
}
1389+
13841390
// Transaction is now a go, set up in-memory cache state
13851391
// invalidate now invalid blocks
13861392
io_stat_t retire_stat;
@@ -1493,7 +1499,7 @@ record_t Cache::prepare_record(
14931499
i->get_length(),
14941500
i->get_type()));
14951501
}
1496-
i->set_io_wait();
1502+
i->set_io_wait(CachedExtent::extent_state_t::CLEAN);
14971503
// Note, paddr is known until complete_commit(),
14981504
// so add_extent() later.
14991505
}
@@ -1519,7 +1525,7 @@ record_t Cache::prepare_record(
15191525
i->get_length(),
15201526
i->get_type()));
15211527
}
1522-
i->set_io_wait();
1528+
i->set_io_wait(CachedExtent::extent_state_t::CLEAN);
15231529
// Note, paddr is (can be) known until complete_commit(),
15241530
// so add_extent() later.
15251531
}
@@ -1530,12 +1536,15 @@ record_t Cache::prepare_record(
15301536
}
15311537
assert(i->state == CachedExtent::extent_state_t::DIRTY);
15321538
assert(i->version > 0);
1539+
assert(i->pending_for_transaction == TRANS_ID_NULL);
1540+
assert(!i->prior_instance);
15331541
remove_from_dirty(i, &trans_src);
15341542
// set the version to zero because the extent state is now clean
15351543
// in order to handle this transparently
15361544
i->version = 0;
15371545
i->dirty_from = JOURNAL_SEQ_MIN;
1538-
// no set_io_wait()
1546+
// no set_io_wait(), skip complete_commit()
1547+
assert(!i->is_pending_io());
15391548
i->state = CachedExtent::extent_state_t::CLEAN;
15401549
assert(i->is_logical());
15411550
i->clear_modified_region();
@@ -1557,18 +1566,21 @@ record_t Cache::prepare_record(
15571566
}
15581567

15591568
if (i->is_exist_clean()) {
1560-
// no set_io_wait()
1569+
assert(i->version == 0);
1570+
assert(!i->prior_instance);
1571+
// no set_io_wait(), skip complete_commit()
1572+
assert(!i->is_pending_io());
1573+
i->pending_for_transaction = TRANS_ID_NULL;
15611574
i->state = CachedExtent::extent_state_t::CLEAN;
15621575
} else {
15631576
assert(i->is_exist_mutation_pending());
1564-
i->set_io_wait();
1565-
// Note, i->state become DIRTY in complete_commit()
1577+
i->set_io_wait(CachedExtent::extent_state_t::DIRTY);
15661578
}
15671579

15681580
// exist mutation pending extents must be in t.mutated_block_list
15691581
add_extent(i);
15701582
const auto t_src = t.get_src();
1571-
if (i->has_delta()) {
1583+
if (i->is_stable_dirty()) {
15721584
add_to_dirty(i, &t_src);
15731585
} else {
15741586
touch_extent(*i, &t_src, t.get_cache_hint());
@@ -1794,6 +1806,7 @@ void Cache::complete_commit(
17941806
return;
17951807
}
17961808

1809+
assert(i->is_stable_clean_pending());
17971810
bool is_inline = false;
17981811
if (i->is_inline()) {
17991812
is_inline = true;
@@ -1808,14 +1821,11 @@ void Cache::complete_commit(
18081821
#endif
18091822
i->pending_for_transaction = TRANS_ID_NULL;
18101823
i->on_initial_write();
1811-
1812-
i->state = CachedExtent::extent_state_t::CLEAN;
18131824
i->reset_prior_instance();
18141825
DEBUGT("add extent as fresh, inline={} -- {}",
18151826
t, is_inline, *i);
18161827
i->invalidate_hints();
18171828
add_extent(i);
1818-
assert(!i->has_delta());
18191829
const auto t_src = t.get_src();
18201830
touch_extent(*i, &t_src, t.get_cache_hint());
18211831
i->complete_io();
@@ -1858,12 +1868,14 @@ void Cache::complete_commit(
18581868
if (!i->is_valid()) {
18591869
continue;
18601870
}
1861-
assert(i->is_exist_mutation_pending() ||
1862-
i->prior_instance);
1871+
assert(i->is_stable_dirty());
1872+
assert(i->is_pending_io());
1873+
assert(i->io_wait->from_state == CachedExtent::extent_state_t::EXIST_MUTATION_PENDING
1874+
|| (i->io_wait->from_state == CachedExtent::extent_state_t::MUTATION_PENDING
1875+
&& i->prior_instance));
18631876
i->on_delta_write(final_block_start);
18641877
i->pending_for_transaction = TRANS_ID_NULL;
18651878
i->reset_prior_instance();
1866-
i->state = CachedExtent::extent_state_t::DIRTY;
18671879
assert(i->version > 0);
18681880
if (i->version == 1 || is_root_type(i->get_type())) {
18691881
i->dirty_from = start_seq;

0 commit comments

Comments
 (0)