]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/osd: check full 46064/head
authorchunmei-liu <chunmei.liu@intel.com>
Sat, 7 May 2022 23:42:11 +0000 (16:42 -0700)
committerchunmei-liu <chunmei.liu@intel.com>
Sat, 7 May 2022 23:47:33 +0000 (16:47 -0700)
need check if pool exceeds its quota

Signed-off-by: chunmei-liu <chunmei.liu@intel.com>
src/crimson/osd/ops_executer.h
src/crimson/osd/pg.cc
src/crimson/osd/pg.h

index fe9e4597255a8867b72f6547848ae4ef113c4c0b..0387ef8dc0b587b8881484eb753d49995c69015c 100644 (file)
@@ -41,6 +41,9 @@ class OpsExecuter : public seastar::enable_lw_shared_from_this<OpsExecuter> {
     crimson::stateful_ec,
     crimson::ct_error::enoent,
     crimson::ct_error::eexist,
+    crimson::ct_error::enospc,
+    crimson::ct_error::edquot,
+    crimson::ct_error::eagain,
     crimson::ct_error::invarg,
     crimson::ct_error::erange,
     crimson::ct_error::ecanceled,
@@ -97,6 +100,7 @@ public:
     virtual epoch_t get_map_epoch() const = 0;
     virtual entity_inst_t get_orig_source_inst() const = 0;
     virtual uint64_t get_features() const = 0;
+    virtual bool has_flag(uint32_t flag) const = 0;
   };
 
   template <class ImplT>
@@ -111,6 +115,9 @@ public:
     osd_reqid_t get_reqid() const final {
       return pimpl->get_reqid();
     }
+    bool has_flag(uint32_t flag) const final {
+      return pimpl->has_flag(flag);
+    }
     utime_t get_mtime() const final {
       return pimpl->get_mtime();
     };
@@ -142,6 +149,7 @@ public:
     ::crimson::interruptible::interruptible_errorator<
       IOInterruptCondition, osd_op_errorator>;
 
+  object_stat_sum_t delta_stats;
 private:
   // an operation can be divided into two stages: main and effect-exposing
   // one. The former is performed immediately on call to `do_osd_op()` while
@@ -167,7 +175,6 @@ private:
 
   size_t num_read = 0;    ///< count read ops
   size_t num_write = 0;   ///< count update ops
-  object_stat_sum_t delta_stats;
 
   // this gizmo could be wrapped in std::optional for the sake of lazy
   // initialization. we don't need it for ops that doesn't have effect
index 4b0bdc0c8a9316ce9e75f4158d4348dfb414b83f..70d49b9e24ddf271d2c1504897ae67df1d787451 100644 (file)
@@ -625,6 +625,37 @@ PG::do_osd_ops_execute(
     logger().debug(
       "do_osd_ops_execute: object {} all operations successful",
       ox->get_target());
+    // check for full
+    if ((ox->delta_stats.num_bytes > 0 ||
+      ox->delta_stats.num_objects > 0) &&
+      get_pool().info.has_flag(pg_pool_t::FLAG_FULL)) {
+      const auto& m = ox->get_message();
+      if (m.get_reqid().name.is_mds() ||   // FIXME: ignore MDS for now
+        m.has_flag(CEPH_OSD_FLAG_FULL_FORCE)) {
+        logger().info(" full, but proceeding due to FULL_FORCE or MDS");
+      } else if (m.has_flag(CEPH_OSD_FLAG_FULL_TRY)) {
+        // they tried, they failed.
+        logger().info(" full, replying to FULL_TRY op");
+        if (get_pool().info.has_flag(pg_pool_t::FLAG_FULL_QUOTA))
+          return interruptor::make_ready_future<OpsExecuter::rep_op_fut_tuple>(
+            seastar::now(),
+            OpsExecuter::osd_op_ierrorator::future<>(
+              crimson::ct_error::edquot::make()));
+        else
+          return interruptor::make_ready_future<OpsExecuter::rep_op_fut_tuple>(
+            seastar::now(),
+            OpsExecuter::osd_op_ierrorator::future<>(
+              crimson::ct_error::enospc::make()));
+      } else {
+        // drop request
+        logger().info(" full, dropping request (bad client)");
+        return interruptor::make_ready_future<OpsExecuter::rep_op_fut_tuple>(
+          seastar::now(),
+          OpsExecuter::osd_op_ierrorator::future<>(
+            crimson::ct_error::eagain::make()));
+      }
+    }
+
     peering_state.apply_op_stats(ox->get_target(), ox->get_stats());
     return std::move(*ox).flush_changes_n_do_ops_effects(ops,
       [this] (auto&& txn,
index b44aac4a952325db4f452cb236fb1415c3c14f7a..a5398b3df57d63d795e771829658e4bc7468ea6a 100644 (file)
@@ -781,6 +781,10 @@ struct PG::do_osd_ops_params_t {
   uint64_t get_features() const {
     return features;
   }
+  // Only used by InternalClientRequest, no op flags
+  bool has_flag(uint32_t flag) const {
+    return false;
+ }
   crimson::net::ConnectionRef conn;
   osd_reqid_t reqid;
   utime_t mtime;