ceph: fail the request if the peer MDS doesn't support getvxattr op
Just fail the request instead sending the request out, or the peer MDS will crash. Link: https://tracker.ceph.com/issues/56529 Signed-off-by: Xiubo Li <xiubli@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
f791357330
commit
6eb06c4621
@ -2356,6 +2356,7 @@ int ceph_do_getvxattr(struct inode *inode, const char *name, void *value,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
req->r_feature_needed = CEPHFS_FEATURE_OP_GETVXATTR;
|
||||||
req->r_path2 = kstrdup(name, GFP_NOFS);
|
req->r_path2 = kstrdup(name, GFP_NOFS);
|
||||||
if (!req->r_path2) {
|
if (!req->r_path2) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
@ -2318,6 +2318,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
|
|||||||
INIT_LIST_HEAD(&req->r_unsafe_dir_item);
|
INIT_LIST_HEAD(&req->r_unsafe_dir_item);
|
||||||
INIT_LIST_HEAD(&req->r_unsafe_target_item);
|
INIT_LIST_HEAD(&req->r_unsafe_target_item);
|
||||||
req->r_fmode = -1;
|
req->r_fmode = -1;
|
||||||
|
req->r_feature_needed = -1;
|
||||||
kref_init(&req->r_kref);
|
kref_init(&req->r_kref);
|
||||||
RB_CLEAR_NODE(&req->r_node);
|
RB_CLEAR_NODE(&req->r_node);
|
||||||
INIT_LIST_HEAD(&req->r_wait);
|
INIT_LIST_HEAD(&req->r_wait);
|
||||||
@ -2916,6 +2917,16 @@ static void __do_request(struct ceph_mds_client *mdsc,
|
|||||||
|
|
||||||
dout("do_request mds%d session %p state %s\n", mds, session,
|
dout("do_request mds%d session %p state %s\n", mds, session,
|
||||||
ceph_session_state_name(session->s_state));
|
ceph_session_state_name(session->s_state));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The old ceph will crash the MDSs when see unknown OPs
|
||||||
|
*/
|
||||||
|
if (req->r_feature_needed > 0 &&
|
||||||
|
!test_bit(req->r_feature_needed, &session->s_features)) {
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
goto out_session;
|
||||||
|
}
|
||||||
|
|
||||||
if (session->s_state != CEPH_MDS_SESSION_OPEN &&
|
if (session->s_state != CEPH_MDS_SESSION_OPEN &&
|
||||||
session->s_state != CEPH_MDS_SESSION_HUNG) {
|
session->s_state != CEPH_MDS_SESSION_HUNG) {
|
||||||
/*
|
/*
|
||||||
|
@ -31,8 +31,9 @@ enum ceph_feature_type {
|
|||||||
CEPHFS_FEATURE_METRIC_COLLECT,
|
CEPHFS_FEATURE_METRIC_COLLECT,
|
||||||
CEPHFS_FEATURE_ALTERNATE_NAME,
|
CEPHFS_FEATURE_ALTERNATE_NAME,
|
||||||
CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
|
CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
|
||||||
|
CEPHFS_FEATURE_OP_GETVXATTR,
|
||||||
|
|
||||||
CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_NOTIFY_SESSION_STATE,
|
CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_OP_GETVXATTR,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CEPHFS_FEATURES_CLIENT_SUPPORTED { \
|
#define CEPHFS_FEATURES_CLIENT_SUPPORTED { \
|
||||||
@ -44,6 +45,7 @@ enum ceph_feature_type {
|
|||||||
CEPHFS_FEATURE_DELEG_INO, \
|
CEPHFS_FEATURE_DELEG_INO, \
|
||||||
CEPHFS_FEATURE_METRIC_COLLECT, \
|
CEPHFS_FEATURE_METRIC_COLLECT, \
|
||||||
CEPHFS_FEATURE_NOTIFY_SESSION_STATE, \
|
CEPHFS_FEATURE_NOTIFY_SESSION_STATE, \
|
||||||
|
CEPHFS_FEATURE_OP_GETVXATTR, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -336,6 +338,8 @@ struct ceph_mds_request {
|
|||||||
long long r_dir_ordered_cnt;
|
long long r_dir_ordered_cnt;
|
||||||
int r_readdir_cache_idx;
|
int r_readdir_cache_idx;
|
||||||
|
|
||||||
|
int r_feature_needed;
|
||||||
|
|
||||||
struct ceph_cap_reservation r_caps_reservation;
|
struct ceph_cap_reservation r_caps_reservation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user