diff --git a/src/include/ceph_features.h b/src/include/ceph_features.h index f72e1028898b2..362a459bde683 100644 --- a/src/include/ceph_features.h +++ b/src/include/ceph_features.h @@ -40,6 +40,28 @@ #define CEPH_FEATURE_MON_SCRUB (1ULL<<33) #define CEPH_FEATURE_OSD_PACKED_RECOVERY (1ULL<<34) +/* + * The introduction of CEPH_FEATURE_OSD_SNAPMAPPER caused the feature + * vector to evaluate to 64 bit ~0. To cope, we designate 1ULL << 63 + * to mean 33 bit ~0, and introduce a helper below to do the + * translation. + * + * This was introduced by commit + * 9ea02b84104045c2ffd7e7f4e7af512953855ecd v0.58-657-g9ea02b8 + * and fixed by commit + * 4255b5c2fb54ae40c53284b3ab700fdfc7e61748 v0.65-263-g4255b5c + */ +#define CEPH_FEATURE_RESERVED (1ULL<<63) + +static inline unsigned long long ceph_sanitize_features(unsigned long long f) { + if (f & CEPH_FEATURE_RESERVED) { + /* everything through OSD_SNAPMAPPER */ + return 0x1ffffffffull; + } else { + return f; + } +} + /* * Features supported. Should be everything above. */ diff --git a/src/msg/Pipe.cc b/src/msg/Pipe.cc index 03ee79a15c2ff..6f271c812f386 100644 --- a/src/msg/Pipe.cc +++ b/src/msg/Pipe.cc @@ -313,6 +313,9 @@ int Pipe::accept() goto fail_unlocked; } + // sanitize features + connect.features = ceph_sanitize_features(connect.features); + authorizer.clear(); if (connect.authorizer_len) { bp = buffer::create(connect.authorizer_len); @@ -920,12 +923,17 @@ int Pipe::connect() ldout(msgr->cct,2) << "connect read reply " << strerror_r(errno, buf, sizeof(buf)) << dendl; goto fail; } + + // sanitize features + reply.features = ceph_sanitize_features(reply.features); + ldout(msgr->cct,20) << "connect got reply tag " << (int)reply.tag - << " connect_seq " << reply.connect_seq - << " global_seq " << reply.global_seq - << " proto " << reply.protocol_version - << " flags " << (int)reply.flags - << dendl; + << " connect_seq " << reply.connect_seq + << " global_seq " << reply.global_seq + << " proto " << reply.protocol_version + << " flags " << (int)reply.flags + << " features " << reply.features + << dendl; authorizer_reply.clear();