client_metadata_t client_metadata(std::move(m->metadata),
std::move(m->supported_features));
+ if (client_metadata.features.empty())
+ infer_supported_features(session, client_metadata);
+
dout(20) << __func__ << " CEPH_SESSION_REQUEST_OPEN metadata entries:" << dendl;
dout(20) << " features: '" << client_metadata.features << dendl;
for (auto& p : client_metadata) {
} else if (mdcache->is_readonly()) {
error_str = "mds is readonly";
} else {
+ if (session->info.client_metadata.features.empty())
+ infer_supported_features(session, session->info.client_metadata);
+
feature_bitset_t missing_features = required_client_features;
missing_features -= session->info.client_metadata.features;
if (!missing_features.empty()) {
m->put();
}
+void Server::infer_supported_features(Session *session, client_metadata_t& client_metadata)
+{
+ int supported = -1;
+ auto it = client_metadata.find("ceph_version");
+ if (it != client_metadata.end()) {
+ // user space client
+ if (it->second.compare(0, 16, "ceph version 12.") == 0)
+ supported = CEPHFS_FEATURE_LUMINOUS;
+ else if (session->connection->has_feature(CEPH_FEATURE_FS_CHANGE_ATTR))
+ supported = CEPHFS_FEATURE_KRAKEN;
+ } else {
+ it = client_metadata.find("kernel_version");
+ if (it != client_metadata.end()) {
+ // kernel client
+ if (session->connection->has_feature(CEPH_FEATURE_NEW_OSDOP_ENCODING))
+ supported = CEPHFS_FEATURE_LUMINOUS;
+ }
+ }
+ if (supported == -1 &&
+ session->connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2))
+ supported = CEPHFS_FEATURE_JEWEL;
+
+ if (supported >= 0) {
+ unsigned long value = (1UL << (supported + 1)) - 1;
+ client_metadata.features = std::move(feature_bitset_t(value));
+ dout(10) << __func__ << " got '" << client_metadata.features << "'" << dendl;
+ }
+}
+
void Server::update_required_client_features()
{
vector<size_t> bits = CEPHFS_FEATURES_MDS_REQUIRED;
int min_compat = mds->mdsmap->get_min_compat_client();
if (min_compat >= CEPH_RELEASE_MIMIC)
bits.push_back(CEPHFS_FEATURE_MIMIC);
+ else if (min_compat >= CEPH_RELEASE_LUMINOUS)
+ bits.push_back(CEPHFS_FEATURE_LUMINOUS);
+ else if (min_compat >= CEPH_RELEASE_KRAKEN)
+ bits.push_back(CEPHFS_FEATURE_KRAKEN);
+ else if (min_compat >= CEPH_RELEASE_JEWEL)
+ bits.push_back(CEPHFS_FEATURE_JEWEL);
std::sort(bits.begin(), bits.end());
required_client_features = feature_bitset_t(bits);
void journal_close_session(Session *session, int state, Context *on_safe);
void reconnect_clients(MDSInternalContext *reconnect_done_);
void handle_client_reconnect(class MClientReconnect *m);
+ void infer_supported_features(Session *session, client_metadata_t& client_metadata);
void update_required_client_features();
//void process_reconnect_cap(CInode *in, int from, ceph_mds_cap_reconnect& capinfo);
// Please add feature bits for later ceph releases and update
// Server::update_required_client_features().
-// The first 8 bits are reserved for old ceph releases.
-#define CEPHFS_FEATURE_MIMIC 8
+// The first 5 bits are reserved for old ceph releases.
+#define CEPHFS_FEATURE_JEWEL 5
+#define CEPHFS_FEATURE_KRAKEN 6
+#define CEPHFS_FEATURE_LUMINOUS 7
+#define CEPHFS_FEATURE_MIMIC 8
#define CEPHFS_FEATURES_ALL { \
- 0, 1, 2, 3, 4, 5, 6, 7, \
+ 0, 1, 2, 3, 4, \
+ CEPHFS_FEATURE_JEWEL, \
+ CEPHFS_FEATURE_KRAKEN, \
+ CEPHFS_FEATURE_LUMINOUS, \
CEPHFS_FEATURE_MIMIC, \
}