@@ -1274,10 +1274,9 @@ record_t Cache::prepare_record(
12741274 i->set_modify_time (commit_time);
12751275 DEBUGT (" mutated extent with {}B delta -- {}" ,
12761276 t, delta_length, *i);
1277- if (i->is_mutation_pending ()) {
1278- DEBUGT (" commit replace extent ... -- {}, prior={}" ,
1279- t, *i, *i->prior_instance );
1277+ assert (delta_length);
12801278
1279+ if (i->is_mutation_pending ()) {
12811280 // If inplace rewrite happens from a concurrent transaction,
12821281 // i->prior_instance will be changed from DIRTY to CLEAN implicitly, thus
12831282 // i->prior_instance->version become 0. This won't cause conflicts
@@ -1286,27 +1285,36 @@ record_t Cache::prepare_record(
12861285 // However, this leads to version mismatch below, thus we reset the
12871286 // version to 1 in this case.
12881287 if (i->prior_instance ->version == 0 && i->version > 1 ) {
1288+ DEBUGT (" commit replace extent (inplace-rewrite) ... -- {}, prior={}" ,
1289+ t, *i, *i->prior_instance );
1290+
12891291 assert (can_inplace_rewrite (i->get_type ()));
12901292 assert (can_inplace_rewrite (i->prior_instance ->get_type ()));
12911293 assert (i->prior_instance ->dirty_from == JOURNAL_SEQ_MIN);
12921294 assert (i->prior_instance ->state == CachedExtent::extent_state_t ::CLEAN);
12931295 assert (i->prior_instance ->get_paddr ().is_absolute_random_block ());
12941296 i->version = 1 ;
1297+ } else {
1298+ DEBUGT (" commit replace extent ... -- {}, prior={}" ,
1299+ t, *i, *i->prior_instance );
12951300 }
1296-
1297- // extent with EXIST_MUTATION_PENDING doesn't have
1298- // prior_instance field so skip these extents.
1299- // the existing extents should be added into Cache
1300- // during complete_commit to sync with gc transaction.
1301- commit_replace_extent (t, i, i->prior_instance );
13021301 } else {
13031302 assert (i->is_exist_mutation_pending ());
13041303 }
13051304
13061305 i->prepare_write ();
1307- i->set_io_wait ();
13081306 i->prepare_commit ();
13091307
1308+ 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()
1317+
13101318 assert (i->get_version () > 0 );
13111319 auto final_crc = i->calc_crc32c ();
13121320 if (is_root_type (i->get_type ())) {
@@ -1359,7 +1367,7 @@ record_t Cache::prepare_record(
13591367 });
13601368 i->last_committed_crc = final_crc;
13611369 }
1362- assert (delta_length);
1370+
13631371 get_by_ext (efforts.delta_bytes_by_ext ,
13641372 i->get_type ()) += delta_length;
13651373 delta_stat.increment (delta_length);
@@ -1370,7 +1378,6 @@ record_t Cache::prepare_record(
13701378 // retiering extents, this is because logical linked tree
13711379 // nodes needs to access their prior instances in this
13721380 // phase if they are rewritten.
1373- e->set_io_wait ();
13741381 e->prepare_commit ();
13751382 });
13761383
@@ -1486,6 +1493,9 @@ record_t Cache::prepare_record(
14861493 i->get_length (),
14871494 i->get_type ()));
14881495 }
1496+ i->set_io_wait ();
1497+ // Note, paddr is known until complete_commit(),
1498+ // so add_extent() later.
14891499 }
14901500
14911501 for (auto &i: t.ool_block_list ) {
@@ -1509,6 +1519,9 @@ record_t Cache::prepare_record(
15091519 i->get_length (),
15101520 i->get_type ()));
15111521 }
1522+ i->set_io_wait ();
1523+ // Note, paddr is (can be) known until complete_commit(),
1524+ // so add_extent() later.
15121525 }
15131526
15141527 for (auto &i: t.inplace_ool_block_list ) {
@@ -1522,6 +1535,7 @@ record_t Cache::prepare_record(
15221535 // in order to handle this transparently
15231536 i->version = 0 ;
15241537 i->dirty_from = JOURNAL_SEQ_MIN;
1538+ // no set_io_wait()
15251539 i->state = CachedExtent::extent_state_t ::CLEAN;
15261540 assert (i->is_logical ());
15271541 i->clear_modified_region ();
@@ -1543,10 +1557,12 @@ record_t Cache::prepare_record(
15431557 }
15441558
15451559 if (i->is_exist_clean ()) {
1560+ // no set_io_wait()
15461561 i->state = CachedExtent::extent_state_t ::CLEAN;
15471562 } else {
15481563 assert (i->is_exist_mutation_pending ());
1549- // i->state must become DIRTY in complete_commit()
1564+ i->set_io_wait ();
1565+ // Note, i->state become DIRTY in complete_commit()
15501566 }
15511567
15521568 // exist mutation pending extents must be in t.mutated_block_list
@@ -1855,6 +1871,7 @@ void Cache::complete_commit(
18551871 } else {
18561872 DEBUGT (" commit extent done -- {}" , t, *i);
18571873 }
1874+ i->complete_io ();
18581875 }
18591876
18601877 for (auto &i: t.retired_set ) {
@@ -1867,24 +1884,16 @@ void Cache::complete_commit(
18671884 }
18681885 epm.mark_space_used (i->get_paddr (), i->get_length ());
18691886 }
1870-
1871- for (auto &i: t.mutated_block_list ) {
1887+ for (auto &i: t.pre_alloc_list ) {
18721888 if (!i->is_valid ()) {
1873- continue ;
1889+ epm. mark_space_free (i-> get_paddr (), i-> get_length ()) ;
18741890 }
1875- i->complete_io ();
18761891 }
18771892
18781893 last_commit = start_seq;
18791894
18801895 apply_backref_byseq (t.move_backref_entries (), start_seq);
18811896 commit_backref_entries (std::move (backref_entries), start_seq);
1882-
1883- for (auto &i: t.pre_alloc_list ) {
1884- if (!i->is_valid ()) {
1885- epm.mark_space_free (i->get_paddr (), i->get_length ());
1886- }
1887- }
18881897}
18891898
18901899void Cache::init ()
0 commit comments