]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
crimson/osd/replicate_backend: add standalone delete to the push queue
authorXuehan Xu <xuxuehan@qianxin.com>
Sat, 23 Nov 2024 08:38:36 +0000 (16:38 +0800)
committerMatan Breizman <mbreizma@redhat.com>
Sun, 5 Jan 2025 16:22:12 +0000 (16:22 +0000)
if the object is deleted while it's being backfilled

Fixes: https://tracker.ceph.com/issues/69027
Signed-off-by: Xuehan Xu <xuxuehan@qianxin.com>
src/crimson/osd/backfill_state.cc
src/crimson/osd/backfill_state.h
src/crimson/osd/pg.cc
src/crimson/osd/pg.h
src/crimson/osd/replicated_backend.cc

index 1392ee330ac2077f37772a62140edb6998c40b89..9fc838aedd3ac254c4df94c0f01d4e14295c9f0f 100644 (file)
@@ -676,6 +676,17 @@ void BackfillState::enqueue_standalone_push(
   backfill_machine.backfill_listener.enqueue_push(obj, v, peers);
 }
 
+void BackfillState::enqueue_standalone_delete(
+  const hobject_t &obj,
+  const eversion_t &v,
+  const std::vector<pg_shard_t> &peers)
+{
+  progress_tracker->enqueue_drop(obj);
+  for (auto bt : peers) {
+    backfill_machine.backfill_listener.enqueue_drop(bt, obj, v);
+  }
+}
+
 std::ostream &operator<<(std::ostream &out, const BackfillState::PGFacade &pg) {
   return pg.print(out);
 }
index 463be4a7a2eb5ef1f7e8364427dd137352bceea0..efc7795682b359653f0afe51e823496668d8b25e 100644 (file)
@@ -289,6 +289,11 @@ public:
     const hobject_t &obj,
     const eversion_t &v,
     const std::vector<pg_shard_t> &peers);
+  void enqueue_standalone_delete(
+    const hobject_t &obj,
+    const eversion_t &v,
+    const std::vector<pg_shard_t> &peers);
+
 
   bool is_triggered() const {
     return backfill_machine.triggering_event() != nullptr;
index bf521498abf4987964632e862f73cff8dc91d209..2746e730f2b8d3da5c55ea6673504b7ac537fea4 100644 (file)
@@ -879,6 +879,17 @@ void PG::enqueue_push_for_backfill(
   backfill_state->enqueue_standalone_push(obj, v, peers);
 }
 
+void PG::enqueue_delete_for_backfill(
+  const hobject_t &obj,
+  const eversion_t &v,
+  const std::vector<pg_shard_t> &peers)
+{
+  assert(recovery_handler);
+  assert(recovery_handler->backfill_state);
+  auto backfill_state = recovery_handler->backfill_state.get();
+  backfill_state->enqueue_standalone_delete(obj, v, peers);
+}
+
 PG::interruptible_future<
   std::tuple<PG::interruptible_future<>,
              PG::interruptible_future<>>>
index 6db73ee835b63c620a760a2dd4225ebe1ea54ce6..06038c0aa005c8e3cdffd6e8bacaf96688d0d793 100644 (file)
@@ -904,6 +904,11 @@ private:
     const hobject_t &obj,
     const eversion_t &v,
     const std::vector<pg_shard_t> &peers);
+  void enqueue_delete_for_backfill(
+    const hobject_t &obj,
+    const eversion_t &v,
+    const std::vector<pg_shard_t> &peers);
+
   bool can_discard_replica_op(const Message& m, epoch_t m_map_epoch) const;
   bool can_discard_op(const MOSDOp& m) const;
   void context_registry_on_change();
index f09cd147ea9e4e2234341c534c6432e9b6b0b72d..f25409b5c7be7800fa56f6998b30278ff4393ab4 100644 (file)
@@ -96,11 +96,16 @@ ReplicatedBackend::submit_transaction(
   bufferlist encoded_txn;
   encode(txn, encoded_txn);
 
+  bool is_delete = false;
   for (auto &le : log_entries) {
     le.mark_unrollbackable();
+    if (le.is_delete()) {
+      is_delete = true;
+    }
   }
 
   std::vector<pg_shard_t> to_push_clone;
+  std::vector<pg_shard_t> to_push_delete;
   auto sends = std::make_unique<std::vector<seastar::future<>>>();
   for (auto &pg_shard : pg_shards) {
     if (pg_shard == whoami) {
@@ -115,12 +120,17 @@ ReplicatedBackend::submit_transaction(
       m = new_repop_msg(
        pg_shard, hoid, encoded_txn, osd_op_p,
        min_epoch, map_epoch, log_entries, false, tid);
-      if (_new_clone && pg.is_missing_on_peer(pg_shard, hoid)) {
-       // The head is in the push queue but hasn't been pushed yet.
-       // We need to ensure that the newly created clone will be 
-       // pushed as well, otherwise we might skip it.
-       // See: https://tracker.ceph.com/issues/68808
-       to_push_clone.push_back(pg_shard);
+      if (pg.is_missing_on_peer(pg_shard, hoid)) {
+       if (_new_clone) {
+         // The head is in the push queue but hasn't been pushed yet.
+         // We need to ensure that the newly created clone will be
+         // pushed as well, otherwise we might skip it.
+         // See: https://tracker.ceph.com/issues/68808
+         to_push_clone.push_back(pg_shard);
+       }
+       if (is_delete) {
+         to_push_delete.push_back(pg_shard);
+       }
       }
     }
     pending_txn->second.acked_peers.push_back({pg_shard, eversion_t{}});
@@ -157,7 +167,8 @@ ReplicatedBackend::submit_transaction(
       return seastar::now();
     }
     return peers->all_committed.get_shared_future();
-  }).then_interruptible([pending_txn, this, _new_clone,
+  }).then_interruptible([pending_txn, this, _new_clone, &hoid,
+                       to_push_delete=std::move(to_push_delete),
                        to_push_clone=std::move(to_push_clone)] {
     auto acked_peers = std::move(pending_txn->second.acked_peers);
     pending_trans.erase(pending_txn);
@@ -167,6 +178,9 @@ ReplicatedBackend::submit_transaction(
        _new_clone->obs.oi.version,
        to_push_clone);
     }
+    if (!to_push_delete.empty()) {
+      pg.enqueue_delete_for_backfill(hoid, {}, to_push_delete);
+    }
     return seastar::make_ready_future<
       crimson::osd::acked_peers_t>(std::move(acked_peers));
   });