ceph: decode feature bits in session message

Signed-off-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
Yan, Zheng 2018-12-21 17:41:39 +08:00 committed by Ilya Dryomov
parent 5ba72e607c
commit 84bf39509b
2 changed files with 44 additions and 5 deletions

View file

@ -2777,6 +2777,25 @@ static void handle_forward(struct ceph_mds_client *mdsc,
pr_err("mdsc_handle_forward decode error err=%d\n", err);
}
static int __decode_and_drop_session_metadata(void **p, void *end)
{
/* map<string,string> */
u32 n;
ceph_decode_32_safe(p, end, n, bad);
while (n-- > 0) {
u32 len;
ceph_decode_32_safe(p, end, len, bad);
ceph_decode_need(p, end, len, bad);
*p += len;
ceph_decode_32_safe(p, end, len, bad);
ceph_decode_need(p, end, len, bad);
*p += len;
}
return 0;
bad:
return -1;
}
/*
* handle a mds session control message
*/
@ -2784,18 +2803,36 @@ static void handle_session(struct ceph_mds_session *session,
struct ceph_msg *msg)
{
struct ceph_mds_client *mdsc = session->s_mdsc;
int mds = session->s_mds;
int msg_version = le16_to_cpu(msg->hdr.version);
void *p = msg->front.iov_base;
void *end = p + msg->front.iov_len;
struct ceph_mds_session_head *h;
u32 op;
u64 seq;
int mds = session->s_mds;
struct ceph_mds_session_head *h = msg->front.iov_base;
unsigned long features = 0;
int wake = 0;
/* decode */
if (msg->front.iov_len < sizeof(*h))
goto bad;
ceph_decode_need(&p, end, sizeof(*h), bad);
h = p;
p += sizeof(*h);
op = le32_to_cpu(h->op);
seq = le64_to_cpu(h->seq);
if (msg_version >= 3) {
u32 len;
/* version >= 2, metadata */
if (__decode_and_drop_session_metadata(&p, end) < 0)
goto bad;
/* version >= 3, feature bits */
ceph_decode_32_safe(&p, end, len, bad);
ceph_decode_need(&p, end, len, bad);
memcpy(&features, p, min_t(size_t, len, sizeof(features)));
p += len;
}
mutex_lock(&mdsc->mutex);
if (op == CEPH_SESSION_CLOSE) {
get_session(session);
@ -2821,6 +2858,7 @@ static void handle_session(struct ceph_mds_session *session,
if (session->s_state == CEPH_MDS_SESSION_RECONNECTING)
pr_info("mds%d reconnect success\n", session->s_mds);
session->s_state = CEPH_MDS_SESSION_OPEN;
session->s_features = features;
renewed_caps(mdsc, session, 0);
wake = 1;
if (mdsc->stopping)

View file

@ -152,6 +152,7 @@ struct ceph_mds_session {
int s_mds;
int s_state;
unsigned long s_ttl; /* time until mds kills us */
unsigned long s_features;
u64 s_seq; /* incoming msg seq # */
struct mutex s_mutex; /* serialize session messages */
@ -179,7 +180,7 @@ struct ceph_mds_session {
unsigned long s_renew_requested; /* last time we sent a renew req */
u64 s_renew_seq;
refcount_t s_ref;
refcount_t s_ref;
struct list_head s_waiting; /* waiting requests */
struct list_head s_unsafe; /* unsafe requests */
};