diff options
author | Yan, Zheng <zyan@redhat.com> | 2018-12-21 04:41:39 -0500 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-03-05 12:55:16 -0500 |
commit | 84bf39509bea5b9f936281c4c660e75099fcd15f (patch) | |
tree | 399778e7d6d668af74aa31915b4a3962e1ec64ff /fs/ceph | |
parent | 5ba72e607cdb3ceebbc6ba4772b79e7e96b55cc4 (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.c | 46 | ||||
-rw-r--r-- | fs/ceph/mds_client.h | 3 |
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 | ||
2780 | static 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; | ||
2795 | bad: | ||
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 | }; |