Skip to content

Commit 360e650

Browse files
xxhdx1985126Matan-B
authored andcommitted
crimson/osd/replicate_backend: add standalone delete to the push queue
if the object is deleted while it's being backfilled Fixes: https://tracker.ceph.com/issues/69027 Signed-off-by: Xuehan Xu <[email protected]>
1 parent d6d49c9 commit 360e650

File tree

5 files changed

+53
-7
lines changed

5 files changed

+53
-7
lines changed

src/crimson/osd/backfill_state.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,17 @@ void BackfillState::enqueue_standalone_push(
676676
backfill_machine.backfill_listener.enqueue_push(obj, v, peers);
677677
}
678678

679+
void BackfillState::enqueue_standalone_delete(
680+
const hobject_t &obj,
681+
const eversion_t &v,
682+
const std::vector<pg_shard_t> &peers)
683+
{
684+
progress_tracker->enqueue_drop(obj);
685+
for (auto bt : peers) {
686+
backfill_machine.backfill_listener.enqueue_drop(bt, obj, v);
687+
}
688+
}
689+
679690
std::ostream &operator<<(std::ostream &out, const BackfillState::PGFacade &pg) {
680691
return pg.print(out);
681692
}

src/crimson/osd/backfill_state.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,11 @@ struct BackfillState {
289289
const hobject_t &obj,
290290
const eversion_t &v,
291291
const std::vector<pg_shard_t> &peers);
292+
void enqueue_standalone_delete(
293+
const hobject_t &obj,
294+
const eversion_t &v,
295+
const std::vector<pg_shard_t> &peers);
296+
292297

293298
bool is_triggered() const {
294299
return backfill_machine.triggering_event() != nullptr;

src/crimson/osd/pg.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,17 @@ void PG::enqueue_push_for_backfill(
879879
backfill_state->enqueue_standalone_push(obj, v, peers);
880880
}
881881

882+
void PG::enqueue_delete_for_backfill(
883+
const hobject_t &obj,
884+
const eversion_t &v,
885+
const std::vector<pg_shard_t> &peers)
886+
{
887+
assert(recovery_handler);
888+
assert(recovery_handler->backfill_state);
889+
auto backfill_state = recovery_handler->backfill_state.get();
890+
backfill_state->enqueue_standalone_delete(obj, v, peers);
891+
}
892+
882893
PG::interruptible_future<
883894
std::tuple<PG::interruptible_future<>,
884895
PG::interruptible_future<>>>

src/crimson/osd/pg.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,11 @@ class PG : public boost::intrusive_ref_counter<
904904
const hobject_t &obj,
905905
const eversion_t &v,
906906
const std::vector<pg_shard_t> &peers);
907+
void enqueue_delete_for_backfill(
908+
const hobject_t &obj,
909+
const eversion_t &v,
910+
const std::vector<pg_shard_t> &peers);
911+
907912
bool can_discard_replica_op(const Message& m, epoch_t m_map_epoch) const;
908913
bool can_discard_op(const MOSDOp& m) const;
909914
void context_registry_on_change();

src/crimson/osd/replicated_backend.cc

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,16 @@ ReplicatedBackend::submit_transaction(
9696
bufferlist encoded_txn;
9797
encode(txn, encoded_txn);
9898

99+
bool is_delete = false;
99100
for (auto &le : log_entries) {
100101
le.mark_unrollbackable();
102+
if (le.is_delete()) {
103+
is_delete = true;
104+
}
101105
}
102106

103107
std::vector<pg_shard_t> to_push_clone;
108+
std::vector<pg_shard_t> to_push_delete;
104109
auto sends = std::make_unique<std::vector<seastar::future<>>>();
105110
for (auto &pg_shard : pg_shards) {
106111
if (pg_shard == whoami) {
@@ -115,12 +120,17 @@ ReplicatedBackend::submit_transaction(
115120
m = new_repop_msg(
116121
pg_shard, hoid, encoded_txn, osd_op_p,
117122
min_epoch, map_epoch, log_entries, false, tid);
118-
if (_new_clone && pg.is_missing_on_peer(pg_shard, hoid)) {
119-
// The head is in the push queue but hasn't been pushed yet.
120-
// We need to ensure that the newly created clone will be
121-
// pushed as well, otherwise we might skip it.
122-
// See: https://tracker.ceph.com/issues/68808
123-
to_push_clone.push_back(pg_shard);
123+
if (pg.is_missing_on_peer(pg_shard, hoid)) {
124+
if (_new_clone) {
125+
// The head is in the push queue but hasn't been pushed yet.
126+
// We need to ensure that the newly created clone will be
127+
// pushed as well, otherwise we might skip it.
128+
// See: https://tracker.ceph.com/issues/68808
129+
to_push_clone.push_back(pg_shard);
130+
}
131+
if (is_delete) {
132+
to_push_delete.push_back(pg_shard);
133+
}
124134
}
125135
}
126136
pending_txn->second.acked_peers.push_back({pg_shard, eversion_t{}});
@@ -157,7 +167,8 @@ ReplicatedBackend::submit_transaction(
157167
return seastar::now();
158168
}
159169
return peers->all_committed.get_shared_future();
160-
}).then_interruptible([pending_txn, this, _new_clone,
170+
}).then_interruptible([pending_txn, this, _new_clone, &hoid,
171+
to_push_delete=std::move(to_push_delete),
161172
to_push_clone=std::move(to_push_clone)] {
162173
auto acked_peers = std::move(pending_txn->second.acked_peers);
163174
pending_trans.erase(pending_txn);
@@ -167,6 +178,9 @@ ReplicatedBackend::submit_transaction(
167178
_new_clone->obs.oi.version,
168179
to_push_clone);
169180
}
181+
if (!to_push_delete.empty()) {
182+
pg.enqueue_delete_for_backfill(hoid, {}, to_push_delete);
183+
}
170184
return seastar::make_ready_future<
171185
crimson::osd::acked_peers_t>(std::move(acked_peers));
172186
});

0 commit comments

Comments
 (0)