]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson: block io for object recovery
authorXuehan Xu <xxhdx1985126@163.com>
Mon, 8 Jun 2020 09:58:56 +0000 (17:58 +0800)
committerXuehan Xu <xxhdx1985126@163.com>
Thu, 18 Jun 2020 01:50:46 +0000 (09:50 +0800)
Signed-off-by: Xuehan Xu <xxhdx1985126@163.com>
12 files changed:
src/crimson/osd/object_context.h
src/crimson/osd/osd_operations/background_recovery.cc
src/crimson/osd/osd_operations/background_recovery.h
src/crimson/osd/osd_operations/client_request.cc
src/crimson/osd/osd_operations/client_request.h
src/crimson/osd/pg.h
src/crimson/osd/pg_recovery.cc
src/crimson/osd/pg_recovery.h
src/crimson/osd/pg_recovery_listener.h
src/crimson/osd/replicated_recovery_backend.cc
src/osd/MissingLoc.cc
src/osd/MissingLoc.h

index 6ff49dedb3f6f9f0cc6e03f7b11492de5dc98103..2a5461c4d90930c71c0083338114a63d769dfb66 100644 (file)
@@ -203,8 +203,13 @@ public:
   void drop_read() {
     return put_lock_type(RWState::RWREAD);
   }
-  bool get_recovery_read() {
-    return rwstate.get_recovery_read();
+  seastar::future<bool> get_recovery_read(bool can_wait = false) {
+    if (!can_wait) {
+      return seastar::make_ready_future<bool>(rwstate.get_recovery_read());
+    }
+    return with_queue([this] {
+      return rwstate.get_recovery_read();
+    }).then([] {return seastar::make_ready_future<bool>(true); });
   }
   void drop_recovery_read() {
     ceph_assert(rwstate.recovery_read_marker);
index 5148d46a65c43cbbc336c75443b3c0904fe018b9..29b2418c1d6d28d72aa20e8f75f9d74e1dd68322 100644 (file)
@@ -68,4 +68,33 @@ seastar::future<> BackgroundRecovery::start()
     });
 }
 
+seastar::future<bool> UrgentRecovery::do_recovery()
+{
+  if (!pg->has_reset_since(epoch_started)) {
+    auto futopt = pg->get_recovery_handler()->recover_missing(soid, need);
+    assert(futopt);
+    return with_blocking_future(std::move(*futopt)).then([] {
+      return seastar::make_ready_future<bool>(false);
+    });
+  }
+  return seastar::make_ready_future<bool>(false);
+}
+
+void UrgentRecovery::print(std::ostream &lhs) const
+{
+  lhs << "UrgentRecovery(" << pg->get_pgid() << ", "
+    << soid << ", v" << need << ")";
+}
+
+void UrgentRecovery::dump_detail(Formatter *f) const
+{
+  f->dump_stream("pgid") << pg->get_pgid();
+  f->open_object_section("recovery_detail");
+  {
+    f->dump_stream("oid") << soid;
+    f->dump_stream("version") << need;
+  }
+  f->close_section();
+}
+
 }
index 65ea5220c9ba2cfc314a0478962e20ed99353ac9..1890d22be97736cb0b572af1fe864e483f47b928 100644 (file)
@@ -13,7 +13,7 @@ namespace crimson::osd {
 class PG;
 class ShardServices;
 
-class BackgroundRecovery final : public OperationT<BackgroundRecovery> {
+class BackgroundRecovery : public OperationT<BackgroundRecovery> {
 public:
   static constexpr OperationTypeCode type = OperationTypeCode::background_recovery;
 
@@ -23,24 +23,42 @@ public:
     epoch_t epoch_started,
     crimson::osd::scheduler::scheduler_class_t scheduler_class);
 
-  void print(std::ostream &) const final;
-  void dump_detail(Formatter *f) const final;
+  virtual void print(std::ostream &) const;
+  virtual void dump_detail(Formatter *f) const;
   seastar::future<> start();
-private:
+protected:
   Ref<PG> pg;
   ShardServices &ss;
   epoch_t epoch_started;
   crimson::osd::scheduler::scheduler_class_t scheduler_class;
-
-  auto get_scheduler_params() const {
+  auto get_scheduler_params(crimson::osd::scheduler::cost_t cost = 1,
+                           crimson::osd::scheduler::client_t owner = 0) const {
     return crimson::osd::scheduler::params_t{
-      1, // cost
-      0, // owner
+      cost, // cost
+      owner, // owner
       scheduler_class
     };
   }
+  virtual seastar::future<bool> do_recovery();
+};
 
-  seastar::future<bool> do_recovery();
+class UrgentRecovery final : public BackgroundRecovery {
+public:
+  UrgentRecovery(
+    const hobject_t& soid,
+    const eversion_t& need,
+    Ref<PG> pg,
+    ShardServices& ss,
+    epoch_t epoch_started,
+    crimson::osd::scheduler::scheduler_class_t scheduler_class)
+  : BackgroundRecovery{pg, ss, epoch_started, scheduler_class},
+    soid{soid}, need(need) {}
+  void print(std::ostream&) const final;
+  void dump_detail(Formatter* f) const final;
+private:
+  const hobject_t soid;
+  const eversion_t need;
+  seastar::future<bool> do_recovery() override;
 };
 
 }
index f31621a4867d22f037f3fd2e0688a68591405275..8f8075f4efe708861d2559713d7ffdce087d5b7a 100644 (file)
@@ -68,7 +68,7 @@ seastar::future<> ClientRequest::start()
       return with_blocking_future(osd.wait_for_pg(m->get_spg()));
     }).then([this, opref=std::move(opref)](Ref<PG> pgref) {
       return seastar::do_with(
-       std::move(pgref), std::move(opref), [this](auto pgref, auto opref) {
+       std::move(pgref), std::move(opref), [this](auto& pgref, auto& opref) {
          PG &pg = *pgref;
          return with_blocking_future(
            handle.enter(pp(pg).await_map)
@@ -80,14 +80,14 @@ seastar::future<> ClientRequest::start()
              handle.enter(pp(pg).wait_for_active));
          }).then([this, &pg]() mutable {
            return with_blocking_future(pg.wait_for_active_blocker.wait());
-         }).then([this, &pg]() mutable {
+         }).then([this, &pgref]() mutable {
            if (m->finish_decode()) {
              m->clear_payload();
            }
            if (is_pg_op()) {
-             return process_pg_op(pg);
+             return process_pg_op(pgref);
            } else {
-             return process_op(pg);
+             return process_op(pgref);
            }
          });
        });
@@ -96,20 +96,33 @@ seastar::future<> ClientRequest::start()
 }
 
 seastar::future<> ClientRequest::process_pg_op(
-  PG &pg)
+  Ref<PG> &pg)
 {
-  return pg.do_pg_ops(m)
+  return pg->do_pg_ops(m)
     .then([this](Ref<MOSDOpReply> reply) {
       return conn->send(reply);
     });
 }
 
 seastar::future<> ClientRequest::process_op(
-  PG &pg)
+  Ref<PG> &pgref)
 {
+  PG& pg = *pgref;
   return with_blocking_future(
-    handle.enter(pp(pg).get_obc)
-  ).then([this, &pg]() {
+    handle.enter(pp(pg).recover_missing)
+  ).then([this, &pg, pgref=std::move(pgref)] {
+    eversion_t ver;
+    const hobject_t& soid = m->get_hobj();
+    if (pg.is_unreadable_object(soid, &ver)) {
+      auto [op, fut] = osd.get_shard_services().start_operation<UrgentRecovery>(
+                         soid, ver, pgref, osd.get_shard_services(), m->get_min_epoch(),
+                         crimson::osd::scheduler::scheduler_class_t::immediate);
+      return std::move(fut);
+    }
+    return seastar::now();
+  }).then([this, &pg] {
+    return with_blocking_future(handle.enter(pp(pg).get_obc));
+  }).then([this, &pg]() {
     op_info.set_from_op(&*m, *pg.get_osdmap());
     return pg.with_locked_obc(
       m,
@@ -130,4 +143,5 @@ seastar::future<> ClientRequest::process_op(
     return seastar::now();
   }));
 }
+
 }
index de0e914d8e6fa8efc8574c1bf6913c52ab14d6b9..d2fdbe926dfe2f4ab7f8657577ca1f9abaeaf814 100644 (file)
@@ -37,6 +37,9 @@ public:
     OrderedPipelinePhase wait_for_active = {
       "ClientRequest::PGPipeline::wait_for_active"
     };
+    OrderedPipelinePhase recover_missing = {
+      "ClientRequest::PGPipeline::recover_missing"
+    };
     OrderedPipelinePhase get_obc = {
       "ClientRequest::PGPipeline::get_obc"
     };
@@ -58,9 +61,9 @@ public:
 
 private:
   seastar::future<> process_pg_op(
-    PG &pg);
+    Ref<PG> &pg);
   seastar::future<> process_op(
-    PG &pg);
+    Ref<PG> &pg);
   bool is_pg_op() const;
 
   ConnectionPipeline &cp();
index a4e2650c99460f8a76bb1f743b4207f3fa1df189..d4beaf9a52b5862213dcfa878099cf7df8aca197 100644 (file)
@@ -661,10 +661,11 @@ private:
   bool is_missing_object(const hobject_t& soid) const {
     return peering_state.get_pg_log().get_missing().get_items().count(soid);
   }
-  bool is_unreadable_object(const hobject_t &oid) const final {
+  bool is_unreadable_object(const hobject_t &oid,
+                           eversion_t* v = 0) const final {
     return is_missing_object(oid) ||
       !peering_state.get_missing_loc().readable_with_acting(
-       oid, get_actingset());
+       oid, get_actingset(), v);
   }
   const set<pg_shard_t> &get_actingset() const {
     return peering_state.get_actingset();
index f040c7e32199b18a227960019254da43d9b9c662..a77f67ccfe1cf7526db7a8d85ac169559da56b5f 100644 (file)
@@ -332,7 +332,7 @@ void PGRecovery::on_local_recover(
       obc->obs.oi = recovery_info.oi;
       // obc is loaded the excl lock
       obc->put_lock_type(RWState::RWEXCL);
-      assert(obc->get_recovery_read());
+      assert(obc->get_recovery_read().get0());
     }
     if (!pg->is_unreadable_object(soid)) {
       pg->get_recovery_backend()->get_recovering(soid).set_readable();
index d5309550e4a7ae539c94ff1bb2c96c55befbb649..e264b76614af8a7939e9fdc22078916a4ff517df 100644 (file)
@@ -69,6 +69,7 @@ private:
   void _committed_pushed_object(epoch_t epoch,
                                eversion_t last_complete);
   friend class ReplicatedRecoveryBackend;
+  friend class crimson::osd::UrgentRecovery;
   seastar::future<> handle_pull(Ref<MOSDPGPull> m);
   seastar::future<> handle_push(Ref<MOSDPGPush> m);
   seastar::future<> handle_push_reply(Ref<MOSDPGPushReply> m);
index 29e91e403efcae18e5e8052fadb3a0749175ad67..f9df92a4aafb4ed6f84930b187ba7c82afb2fb90 100644 (file)
@@ -29,7 +29,7 @@ public:
   virtual const pg_shard_t& get_pg_whoami() const = 0;
   virtual const spg_t& get_pgid() const = 0;
   virtual RecoveryBackend* get_recovery_backend() = 0;
-  virtual bool is_unreadable_object(const hobject_t&) const = 0;
+  virtual bool is_unreadable_object(const hobject_t&, eversion_t* v = 0) const = 0;
   virtual bool has_reset_since(epoch_t) const = 0;
   virtual std::vector<pg_shard_t> get_replica_recovery_order() const = 0;
   virtual seastar::future<> stop() = 0;
index 013e2cd99da8c3a111d0ec4591526eeacc4da5c6..30df1da992818f706e6daa0c6696191cc9554a6d 100644 (file)
@@ -45,16 +45,18 @@ seastar::future<> ReplicatedRecoveryBackend::recover_object(
                                           std::move(msg),
                                           pg.get_osdmap_epoch()).then(
          [&recovery_waiter] {
-         return recovery_waiter.wait_for_pull();
+         return recovery_waiter.wait_for_pull().then([] {
+           return seastar::make_ready_future<bool>(true);
+         });
        });
       } else {
-       return seastar::make_ready_future<>();
+       return seastar::make_ready_future<bool>(false);
       }
-    }().then([this, &pops, &shards, soid, need, &recovery_waiter]() mutable {
-      return [this, &recovery_waiter, soid] {
+    }().then([this, &pops, &shards, soid, need, &recovery_waiter](bool pulled) mutable {
+      return [this, &recovery_waiter, soid, pulled] {
        if (!recovery_waiter.obc) {
          return pg.get_or_load_head_obc(soid).safe_then(
-           [&recovery_waiter](auto p) {
+           [&recovery_waiter, pulled](auto p) {
            auto& [obc, existed] = p;
            logger().debug("recover_object: loaded obc: {}", obc->obs.oi.soid);
            recovery_waiter.obc = obc;
@@ -62,7 +64,12 @@ seastar::future<> ReplicatedRecoveryBackend::recover_object(
              // obc is loaded with excl lock
              recovery_waiter.obc->put_lock_type(RWState::RWEXCL);
            }
-           assert(recovery_waiter.obc->get_recovery_read());
+           bool got = recovery_waiter.obc->get_recovery_read().get0();
+           assert(pulled ? got : 1);
+           if (!got) {
+             return recovery_waiter.obc->get_recovery_read(true)
+             .then([](bool) { return seastar::now(); });
+           }
            return seastar::make_ready_future<>();
          }, crimson::osd::PG::load_obc_ertr::all_same_way(
              [this, &recovery_waiter, soid](const std::error_code& e) {
@@ -73,7 +80,7 @@ seastar::future<> ReplicatedRecoveryBackend::recover_object(
              recovery_waiter.obc = obc;
              // obc is loaded with excl lock
              recovery_waiter.obc->put_lock_type(RWState::RWEXCL);
-             assert(recovery_waiter.obc->get_recovery_read());
+             assert(recovery_waiter.obc->get_recovery_read().get0());
              return seastar::make_ready_future<>();
            })
          );
index 2682e57c26faf622e9905a64387bec4c97e0e27b..d45220a824a81bcbea07a2725125e14083efcc25 100644 (file)
@@ -12,8 +12,9 @@ using std::set;
 
 bool MissingLoc::readable_with_acting(
   const hobject_t &hoid,
-  const set<pg_shard_t> &acting) const {
-  if (!needs_recovery(hoid))
+  const set<pg_shard_t> &acting,
+  eversion_t* v) const {
+  if (!needs_recovery(hoid, v))
     return true;
   if (is_deleted(hoid))
     return false;
index ed091bb21132053c366058857728a88c5521caef..9bce3cedad0f176e5d8722f695c6d978924eb4f6 100644 (file)
@@ -157,7 +157,8 @@ class MissingLoc {
   }
   bool readable_with_acting(
     const hobject_t &hoid,
-    const std::set<pg_shard_t> &acting) const;
+    const std::set<pg_shard_t> &acting,
+    eversion_t* v = 0) const;
   uint64_t num_unfound() const {
     uint64_t ret = 0;
     for (std::map<hobject_t, pg_missing_item>::const_iterator i =