aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2018-12-21 04:41:39 -0500
committerIlya Dryomov <idryomov@gmail.com>2019-03-05 12:55:16 -0500
commit84bf39509bea5b9f936281c4c660e75099fcd15f (patch)
tree399778e7d6d668af74aa31915b4a3962e1ec64ff /fs/ceph
parent5ba72e607cdb3ceebbc6ba4772b79e7e96b55cc4 (diff)
ceph: decode feature bits in session message
Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/mds_client.c46
-rw-r--r--fs/ceph/mds_client.h3
2 files changed, 44 insertions, 5 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 163fc74bf221..04f18095e306 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2777,6 +2777,25 @@ bad:
2777 pr_err("mdsc_handle_forward decode error err=%d\n", err); 2777 pr_err("mdsc_handle_forward decode error err=%d\n", err);
2778} 2778}
2779 2779
2780static int __decode_and_drop_session_metadata(void **p, void *end)
2781{
2782 /* map<string,string> */
2783 u32 n;
2784 ceph_decode_32_safe(p, end, n, bad);
2785 while (n-- > 0) {
2786 u32 len;
2787 ceph_decode_32_safe(p, end, len, bad);
2788 ceph_decode_need(p, end, len, bad);
2789 *p += len;
2790 ceph_decode_32_safe(p, end, len, bad);
2791 ceph_decode_need(p, end, len, bad);
2792 *p += len;
2793 }
2794 return 0;
2795bad:
2796 return -1;
2797}
2798
2780/* 2799/*
2781 * handle a mds session control message 2800 * handle a mds session control message
2782 */ 2801 */
@@ -2784,18 +2803,36 @@ static void handle_session(struct ceph_mds_session *session,
2784 struct ceph_msg *msg) 2803 struct ceph_msg *msg)
2785{ 2804{
2786 struct ceph_mds_client *mdsc = session->s_mdsc; 2805 struct ceph_mds_client *mdsc = session->s_mdsc;
2806 int mds = session->s_mds;
2807 int msg_version = le16_to_cpu(msg->hdr.version);
2808 void *p = msg->front.iov_base;
2809 void *end = p + msg->front.iov_len;
2810 struct ceph_mds_session_head *h;
2787 u32 op; 2811 u32 op;
2788 u64 seq; 2812 u64 seq;
2789 int mds = session->s_mds; 2813 unsigned long features = 0;
2790 struct ceph_mds_session_head *h = msg->front.iov_base;
2791 int wake = 0; 2814 int wake = 0;
2792 2815
2793 /* decode */ 2816 /* decode */
2794 if (msg->front.iov_len < sizeof(*h)) 2817 ceph_decode_need(&p, end, sizeof(*h), bad);
2795 goto bad; 2818 h = p;
2819 p += sizeof(*h);
2820
2796 op = le32_to_cpu(h->op); 2821 op = le32_to_cpu(h->op);
2797 seq = le64_to_cpu(h->seq); 2822 seq = le64_to_cpu(h->seq);
2798 2823
2824 if (msg_version >= 3) {
2825 u32 len;
2826 /* version >= 2, metadata */
2827 if (__decode_and_drop_session_metadata(&p, end) < 0)
2828 goto bad;
2829 /* version >= 3, feature bits */
2830 ceph_decode_32_safe(&p, end, len, bad);
2831 ceph_decode_need(&p, end, len, bad);
2832 memcpy(&features, p, min_t(size_t, len, sizeof(features)));
2833 p += len;
2834 }
2835
2799 mutex_lock(&mdsc->mutex); 2836 mutex_lock(&mdsc->mutex);
2800 if (op == CEPH_SESSION_CLOSE) { 2837 if (op == CEPH_SESSION_CLOSE) {
2801 get_session(session); 2838 get_session(session);
@@ -2821,6 +2858,7 @@ static void handle_session(struct ceph_mds_session *session,
2821 if (session->s_state == CEPH_MDS_SESSION_RECONNECTING) 2858 if (session->s_state == CEPH_MDS_SESSION_RECONNECTING)
2822 pr_info("mds%d reconnect success\n", session->s_mds); 2859 pr_info("mds%d reconnect success\n", session->s_mds);
2823 session->s_state = CEPH_MDS_SESSION_OPEN; 2860 session->s_state = CEPH_MDS_SESSION_OPEN;
2861 session->s_features = features;
2824 renewed_caps(mdsc, session, 0); 2862 renewed_caps(mdsc, session, 0);
2825 wake = 1; 2863 wake = 1;
2826 if (mdsc->stopping) 2864 if (mdsc->stopping)
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 729da155ebf0..0d3264cf3334 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -152,6 +152,7 @@ struct ceph_mds_session {
152 int s_mds; 152 int s_mds;
153 int s_state; 153 int s_state;
154 unsigned long s_ttl; /* time until mds kills us */ 154 unsigned long s_ttl; /* time until mds kills us */
155 unsigned long s_features;
155 u64 s_seq; /* incoming msg seq # */ 156 u64 s_seq; /* incoming msg seq # */
156 struct mutex s_mutex; /* serialize session messages */ 157 struct mutex s_mutex; /* serialize session messages */
157 158
@@ -179,7 +180,7 @@ struct ceph_mds_session {
179 unsigned long s_renew_requested; /* last time we sent a renew req */ 180 unsigned long s_renew_requested; /* last time we sent a renew req */
180 u64 s_renew_seq; 181 u64 s_renew_seq;
181 182
182 refcount_t s_ref; 183 refcount_t s_ref;
183 struct list_head s_waiting; /* waiting requests */ 184 struct list_head s_waiting; /* waiting requests */
184 struct list_head s_unsafe; /* unsafe requests */ 185 struct list_head s_unsafe; /* unsafe requests */
185}; 186};