From 4b55a2b41152deb7e5018afcbd9d84464f5fe2ef Mon Sep 17 00:00:00 2001 From: chunmei-liu Date: Sat, 7 May 2022 16:42:11 -0700 Subject: [PATCH] crimson/osd: check full need check if pool exceeds its quota Signed-off-by: chunmei-liu --- src/crimson/osd/ops_executer.h | 9 ++++++++- src/crimson/osd/pg.cc | 31 +++++++++++++++++++++++++++++++ src/crimson/osd/pg.h | 4 ++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/crimson/osd/ops_executer.h b/src/crimson/osd/ops_executer.h index fe9e4597255a8..0387ef8dc0b58 100644 --- a/src/crimson/osd/ops_executer.h +++ b/src/crimson/osd/ops_executer.h @@ -41,6 +41,9 @@ class OpsExecuter : public seastar::enable_lw_shared_from_this { 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 @@ -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 diff --git a/src/crimson/osd/pg.cc b/src/crimson/osd/pg.cc index 4b0bdc0c8a931..70d49b9e24ddf 100644 --- a/src/crimson/osd/pg.cc +++ b/src/crimson/osd/pg.cc @@ -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( + seastar::now(), + OpsExecuter::osd_op_ierrorator::future<>( + crimson::ct_error::edquot::make())); + else + return interruptor::make_ready_future( + 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( + 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, diff --git a/src/crimson/osd/pg.h b/src/crimson/osd/pg.h index b44aac4a95232..a5398b3df57d6 100644 --- a/src/crimson/osd/pg.h +++ b/src/crimson/osd/pg.h @@ -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; -- 2.39.5