Skip to content

Commit 829c857

Browse files
committed
crimson/os/seastore: fix data inconsistency during ool writes
In RBM, seastore issues ool writes with allocated address. If a transaction conflict occurs at this point, the allocated address is freed, allowing the address to be reused. However, data inconsistency can occur if seastore issues ool writes with freed address before the preceding ool write has not been complete. To fix this issue, this commit frees the allocated address after ool writes is don in the event of the transaction conflict after ool write is issued. Signed-off-by: Myoungwon Oh <[email protected]>
1 parent 0d61375 commit 829c857

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

src/crimson/os/seastore/cache.cc

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -990,8 +990,12 @@ void Cache::mark_transaction_conflicted(
990990
}
991991
efforts.mutate_delta_bytes += delta_stat.bytes;
992992

993-
for (auto &i: t.pre_alloc_list) {
994-
epm.mark_space_free(i->get_paddr(), i->get_length());
993+
if (t.get_pending_ool()) {
994+
t.get_pending_ool()->is_conflicted = true;
995+
} else {
996+
for (auto &i: t.pre_alloc_list) {
997+
epm.mark_space_free(i->get_paddr(), i->get_length());
998+
}
995999
}
9961000

9971001
auto& ool_stats = t.get_ool_write_stats();

src/crimson/os/seastore/extent_placement_manager.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,19 @@ RandomBlockOolWriter::alloc_write_ool_extents(
987987
return alloc_write_iertr::now();
988988
}
989989
return seastar::with_gate(write_guard, [this, &t, &extents] {
990-
return do_write(t, extents);
990+
seastar::lw_shared_ptr<rbm_pending_ool_t> ptr =
991+
seastar::make_lw_shared<rbm_pending_ool_t>();
992+
ptr->pending_extents = t.get_pre_alloc_list();
993+
assert(!t.is_conflicted());
994+
t.set_pending_ool(ptr);
995+
return do_write(t, extents
996+
).finally([this, ptr=ptr] {
997+
if (ptr->is_conflicted) {
998+
for (auto &e : ptr->pending_extents) {
999+
rb_cleaner->mark_space_free(e->get_paddr(), e->get_length());
1000+
}
1001+
}
1002+
});
9911003
});
9921004
}
9931005

src/crimson/os/seastore/transaction.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ struct rewrite_stats_t {
8080
}
8181
};
8282

83+
struct rbm_pending_ool_t {
84+
bool is_conflicted = false;
85+
std::list<CachedExtentRef> pending_extents;
86+
};
87+
8388
/**
8489
* Transaction
8590
*
@@ -554,6 +559,18 @@ class Transaction {
554559
return static_cast<T&>(*view);
555560
}
556561

562+
void set_pending_ool(seastar::lw_shared_ptr<rbm_pending_ool_t> ptr) {
563+
pending_ool = ptr;
564+
}
565+
566+
seastar::lw_shared_ptr<rbm_pending_ool_t> get_pending_ool() {
567+
return pending_ool;
568+
}
569+
570+
const auto& get_pre_alloc_list() {
571+
return pre_alloc_list;
572+
}
573+
557574
private:
558575
friend class Cache;
559576
friend Ref make_test_transaction();
@@ -650,6 +667,8 @@ class Transaction {
650667
const src_t src;
651668

652669
transaction_id_t trans_id = TRANS_ID_NULL;
670+
671+
seastar::lw_shared_ptr<rbm_pending_ool_t> pending_ool;
653672
};
654673
using TransactionRef = Transaction::Ref;
655674

0 commit comments

Comments
 (0)