From d5bac46e06c5420f29a021b294e391b2c6694cbd Mon Sep 17 00:00:00 2001 From: David Zafman Date: Wed, 24 Sep 2014 16:02:21 -0700 Subject: [PATCH] osd: Return EOPNOTSUPP if a set-alloc-hint occurs with OSDs that don't support Add CEPH_FEATURE_OSD_SET_ALLOC_HINT feature bit Collect the intersection of all peer feature bits during peering When handling CEPH_OSD_OP_SETALLOCHINT check that all OSDs support it by checking for CEPH_FEATURE_OSD_SET_ALLOC_HINT feature bit. Fixes: #9419 Backport: firefly Signed-off-by: David Zafman (cherry picked from commit 9b39033f2b2bcdd2be0f6da4dff06023d0f77499) Conflicts: src/include/ceph_features.h src/osd/PG.cc src/osd/PG.h src/osd/ReplicatedPG.cc --- src/include/ceph_features.h | 2 ++ src/osd/OSD.cc | 3 ++- src/osd/PG.cc | 8 +++++++- src/osd/PG.h | 13 ++++++++++--- src/osd/ReplicatedPG.cc | 4 ++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/include/ceph_features.h b/src/include/ceph_features.h index 6b2a5fb50532b..c3dfcabe51981 100644 --- a/src/include/ceph_features.h +++ b/src/include/ceph_features.h @@ -52,6 +52,7 @@ #define CEPH_FEATURE_OSD_PRIMARY_AFFINITY (1ULL<<41) /* overlap w/ tunables3 */ #define CEPH_FEATURE_MSGR_KEEPALIVE2 (1ULL<<42) #define CEPH_FEATURE_OSD_POOLRESEND (1ULL<<43) +#define CEPH_FEATURE_OSD_SET_ALLOC_HINT (1ULL<<45) /* * The introduction of CEPH_FEATURE_OSD_SNAPMAPPER caused the feature @@ -124,6 +125,7 @@ static inline unsigned long long ceph_sanitize_features(unsigned long long f) { CEPH_FEATURE_OSD_PRIMARY_AFFINITY | \ CEPH_FEATURE_MSGR_KEEPALIVE2 | \ CEPH_FEATURE_OSD_POOLRESEND | \ + CEPH_FEATURE_OSD_SET_ALLOC_HINT | \ 0ULL) #define CEPH_FEATURES_SUPPORTED_DEFAULT CEPH_FEATURES_ALL diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index dc67fdd7f0e88..f2c7acfbc4fb8 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -6732,7 +6732,8 @@ void OSD::handle_pg_notify(OpRequestRef op) PG::CephPeeringEvtRef( new PG::CephPeeringEvt( it->first.epoch_sent, it->first.query_epoch, - PG::MNotifyRec(pg_shard_t(from, it->first.from), it->first))) + PG::MNotifyRec(pg_shard_t(from, it->first.from), it->first, + op->get_req()->get_connection()->get_features()))) ); } } diff --git a/src/osd/PG.cc b/src/osd/PG.cc index f3cbc0f0a86fa..b82311a73bf8b 100644 --- a/src/osd/PG.cc +++ b/src/osd/PG.cc @@ -194,7 +194,8 @@ PG::PG(OSDService *o, OSDMapRef curmap, finish_sync_event(NULL), scrub_after_recovery(false), active_pushes(0), - recovery_state(this) + recovery_state(this), + peer_features((uint64_t)-1) { #ifdef PG_DEBUG_REFS osd->add_pgid(p, this); @@ -6809,6 +6810,7 @@ PG::RecoveryState::GetInfo::GetInfo(my_context ctx) pg->publish_stats_to_osd(); + pg->reset_peer_features(); get_infos(); if (peer_info_requested.empty() && !prior_set->pg_down) { post_event(GotInfo()); @@ -6876,6 +6878,9 @@ boost::statechart::result PG::RecoveryState::GetInfo::react(const MNotifyRec& in } get_infos(); } + dout(20) << "Adding osd: " << infoevt.from.osd << " features: " + << hex << infoevt.features << dec << dendl; + pg->apply_peer_features(infoevt.features); // are we done getting everything? if (peer_info_requested.empty() && !prior_set->pg_down) { @@ -6934,6 +6939,7 @@ boost::statechart::result PG::RecoveryState::GetInfo::react(const MNotifyRec& in break; } } + dout(20) << "Common features: " << hex << pg->get_min_peer_features() << dec << dendl; post_event(GotInfo()); } } diff --git a/src/osd/PG.h b/src/osd/PG.h index fa0bb8bee0d7a..e3194779b0e21 100644 --- a/src/osd/PG.h +++ b/src/osd/PG.h @@ -1308,10 +1308,12 @@ public: struct MNotifyRec : boost::statechart::event< MNotifyRec > { pg_shard_t from; pg_notify_t notify; - MNotifyRec(pg_shard_t from, pg_notify_t ¬ify) : - from(from), notify(notify) {} + uint64_t features; + MNotifyRec(pg_shard_t from, pg_notify_t ¬ify, uint64_t f) : + from(from), notify(notify), features(f) {} void print(std::ostream *out) const { - *out << "MNotifyRec from " << from << " notify: " << notify; + *out << "MNotifyRec from " << from << " notify: " << notify + << " features: 0x" << hex << features << dec; } }; @@ -1993,11 +1995,16 @@ public: // Prevent copying PG(const PG& rhs); PG& operator=(const PG& rhs); + uint64_t peer_features; public: spg_t get_pgid() const { return info.pgid; } int get_nrep() const { return acting.size(); } + void reset_peer_features() { peer_features = (uint64_t)-1; } + uint64_t get_min_peer_features() { return peer_features; } + void apply_peer_features(uint64_t f) { peer_features &= f; } + void init_primary_up_acting( const vector &newup, const vector &newacting, diff --git a/src/osd/ReplicatedPG.cc b/src/osd/ReplicatedPG.cc index 5600466fa4355..5114031d9a2d2 100644 --- a/src/osd/ReplicatedPG.cc +++ b/src/osd/ReplicatedPG.cc @@ -3645,6 +3645,10 @@ int ReplicatedPG::do_osd_ops(OpContext *ctx, vector& ops) case CEPH_OSD_OP_SETALLOCHINT: ++ctx->num_write; { + if (!(get_min_peer_features() & CEPH_FEATURE_OSD_SET_ALLOC_HINT)) { + result = -EOPNOTSUPP; + break; + } if (!obs.exists) { ctx->mod_desc.create(); t->touch(soid); -- 2.39.5