@@ -36,57 +36,122 @@ static const struct ceph_connection_operations mon_con_ops;
3636
3737static int __validate_auth (struct ceph_mon_client * monc );
3838
39+ static int decode_mon_info (void * * p , void * end , bool msgr2 ,
40+ struct ceph_entity_addr * addr )
41+ {
42+ void * mon_info_end ;
43+ u32 struct_len ;
44+ u8 struct_v ;
45+ int ret ;
46+
47+ ret = ceph_start_decoding (p , end , 1 , "mon_info_t" , & struct_v ,
48+ & struct_len );
49+ if (ret )
50+ return ret ;
51+
52+ mon_info_end = * p + struct_len ;
53+ ceph_decode_skip_string (p , end , e_inval ); /* skip mon name */
54+ ret = ceph_decode_entity_addrvec (p , end , msgr2 , addr );
55+ if (ret )
56+ return ret ;
57+
58+ * p = mon_info_end ;
59+ return 0 ;
60+
61+ e_inval :
62+ return - EINVAL ;
63+ }
64+
3965/*
4066 * Decode a monmap blob (e.g., during mount).
67+ *
68+ * Assume MonMap v3 (i.e. encoding with MONNAMES and MONENC).
4169 */
42- static struct ceph_monmap * ceph_monmap_decode (void * p , void * end )
70+ static struct ceph_monmap * ceph_monmap_decode (void * * p , void * end , bool msgr2 )
4371{
44- struct ceph_monmap * m = NULL ;
45- int i , err = - EINVAL ;
72+ struct ceph_monmap * monmap = NULL ;
4673 struct ceph_fsid fsid ;
47- u32 epoch , num_mon ;
48- u32 len ;
74+ u32 struct_len ;
75+ int blob_len ;
76+ int num_mon ;
77+ u8 struct_v ;
78+ u32 epoch ;
79+ int ret ;
80+ int i ;
81+
82+ ceph_decode_32_safe (p , end , blob_len , e_inval );
83+ ceph_decode_need (p , end , blob_len , e_inval );
84+
85+ ret = ceph_start_decoding (p , end , 6 , "monmap" , & struct_v , & struct_len );
86+ if (ret )
87+ goto fail ;
88+
89+ dout ("%s struct_v %d\n" , __func__ , struct_v );
90+ ceph_decode_copy_safe (p , end , & fsid , sizeof (fsid ), e_inval );
91+ ceph_decode_32_safe (p , end , epoch , e_inval );
92+ if (struct_v >= 6 ) {
93+ u32 feat_struct_len ;
94+ u8 feat_struct_v ;
4995
50- ceph_decode_32_safe ( & p , end , len , bad );
51- ceph_decode_need ( & p , end , len , bad );
96+ * p += sizeof ( struct ceph_timespec ); /* skip last_changed */
97+ * p += sizeof ( struct ceph_timespec ); /* skip created */
5298
53- dout ("monmap_decode %p %p len %d (%d)\n" , p , end , len , (int )(end - p ));
54- p += sizeof (u16 ); /* skip version */
99+ ret = ceph_start_decoding (p , end , 1 , "mon_feature_t" ,
100+ & feat_struct_v , & feat_struct_len );
101+ if (ret )
102+ goto fail ;
55103
56- ceph_decode_need (& p , end , sizeof (fsid ) + 2 * sizeof (u32 ), bad );
57- ceph_decode_copy (& p , & fsid , sizeof (fsid ));
58- epoch = ceph_decode_32 (& p );
104+ * p += feat_struct_len ; /* skip persistent_features */
59105
60- num_mon = ceph_decode_32 (& p );
106+ ret = ceph_start_decoding (p , end , 1 , "mon_feature_t" ,
107+ & feat_struct_v , & feat_struct_len );
108+ if (ret )
109+ goto fail ;
61110
111+ * p += feat_struct_len ; /* skip optional_features */
112+ }
113+ ceph_decode_32_safe (p , end , num_mon , e_inval );
114+
115+ dout ("%s fsid %pU epoch %u num_mon %d\n" , __func__ , & fsid , epoch ,
116+ num_mon );
62117 if (num_mon > CEPH_MAX_MON )
63- goto bad ;
64- m = kmalloc (struct_size (m , mon_inst , num_mon ), GFP_NOFS );
65- if (m == NULL )
66- return ERR_PTR (- ENOMEM );
67- m -> fsid = fsid ;
68- m -> epoch = epoch ;
69- m -> num_mon = num_mon ;
70- for (i = 0 ; i < num_mon ; ++ i ) {
71- struct ceph_entity_inst * inst = & m -> mon_inst [i ];
72-
73- /* copy name portion */
74- ceph_decode_copy_safe (& p , end , & inst -> name ,
75- sizeof (inst -> name ), bad );
76- err = ceph_decode_entity_addr (& p , end , & inst -> addr );
77- if (err )
78- goto bad ;
118+ goto e_inval ;
119+
120+ monmap = kmalloc (struct_size (monmap , mon_inst , num_mon ), GFP_NOIO );
121+ if (!monmap ) {
122+ ret = - ENOMEM ;
123+ goto fail ;
79124 }
80- dout ("monmap_decode epoch %d, num_mon %d\n" , m -> epoch ,
81- m -> num_mon );
82- for (i = 0 ; i < m -> num_mon ; i ++ )
83- dout ("monmap_decode mon%d is %s\n" , i ,
84- ceph_pr_addr (& m -> mon_inst [i ].addr ));
85- return m ;
86- bad :
87- dout ("monmap_decode failed with %d\n" , err );
88- kfree (m );
89- return ERR_PTR (err );
125+ monmap -> fsid = fsid ;
126+ monmap -> epoch = epoch ;
127+ monmap -> num_mon = num_mon ;
128+
129+ /* legacy_mon_addr map or mon_info map */
130+ for (i = 0 ; i < num_mon ; i ++ ) {
131+ struct ceph_entity_inst * inst = & monmap -> mon_inst [i ];
132+
133+ ceph_decode_skip_string (p , end , e_inval ); /* skip mon name */
134+ inst -> name .type = CEPH_ENTITY_TYPE_MON ;
135+ inst -> name .num = cpu_to_le64 (i );
136+
137+ if (struct_v >= 6 )
138+ ret = decode_mon_info (p , end , msgr2 , & inst -> addr );
139+ else
140+ ret = ceph_decode_entity_addr (p , end , & inst -> addr );
141+ if (ret )
142+ goto fail ;
143+
144+ dout ("%s mon%d addr %s\n" , __func__ , i ,
145+ ceph_pr_addr (& inst -> addr ));
146+ }
147+
148+ return monmap ;
149+
150+ e_inval :
151+ ret = - EINVAL ;
152+ fail :
153+ kfree (monmap );
154+ return ERR_PTR (ret );
90155}
91156
92157/*
@@ -476,7 +541,7 @@ static void ceph_monc_handle_map(struct ceph_mon_client *monc,
476541 p = msg -> front .iov_base ;
477542 end = p + msg -> front .iov_len ;
478543
479- monmap = ceph_monmap_decode (p , end );
544+ monmap = ceph_monmap_decode (& p , end , false );
480545 if (IS_ERR (monmap )) {
481546 pr_err ("problem decoding monmap, %d\n" ,
482547 (int )PTR_ERR (monmap ));
0 commit comments