]>
git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - fs/ceph/mdsmap.c
1 #include "ceph_debug.h"
5 #include <linux/random.h>
6 #include <linux/slab.h>
7 #include <linux/types.h>
10 #include "messenger.h"
17 * choose a random mds that is "up" (i.e. has a state > 0), or -1.
19 int ceph_mdsmap_get_random_mds(struct ceph_mdsmap
*m
)
26 for (i
= 0; i
< m
->m_max_mds
; i
++)
27 if (m
->m_info
[i
].state
> 0)
33 get_random_bytes(&r
, 1);
36 for (i
= 0; n
> 0; i
++, n
--)
37 while (m
->m_info
[i
].state
<= 0)
46 * Ignore any fields we don't care about (there are quite a few of
49 struct ceph_mdsmap
*ceph_mdsmap_decode(void **p
, void *end
)
51 struct ceph_mdsmap
*m
;
56 m
= kzalloc(sizeof(*m
), GFP_NOFS
);
58 return ERR_PTR(-ENOMEM
);
60 ceph_decode_16_safe(p
, end
, version
, bad
);
62 ceph_decode_need(p
, end
, 8*sizeof(u32
) + sizeof(u64
), bad
);
63 m
->m_epoch
= ceph_decode_32(p
);
64 m
->m_client_epoch
= ceph_decode_32(p
);
65 m
->m_last_failure
= ceph_decode_32(p
);
66 m
->m_root
= ceph_decode_32(p
);
67 m
->m_session_timeout
= ceph_decode_32(p
);
68 m
->m_session_autoclose
= ceph_decode_32(p
);
69 m
->m_max_file_size
= ceph_decode_64(p
);
70 m
->m_max_mds
= ceph_decode_32(p
);
72 m
->m_info
= kcalloc(m
->m_max_mds
, sizeof(*m
->m_info
), GFP_NOFS
);
73 if (m
->m_info
== NULL
)
76 /* pick out active nodes from mds_info (state > 0) */
77 n
= ceph_decode_32(p
);
78 for (i
= 0; i
< n
; i
++) {
83 struct ceph_entity_addr addr
;
84 u32 num_export_targets
;
85 void *pexport_targets
= NULL
;
87 ceph_decode_need(p
, end
, sizeof(addr
) + 1 + sizeof(u32
), bad
);
88 ceph_decode_copy(p
, &addr
, sizeof(addr
));
89 infoversion
= ceph_decode_8(p
);
90 namelen
= ceph_decode_32(p
); /* skip mds name */
93 ceph_decode_need(p
, end
,
94 4*sizeof(u32
) + sizeof(u64
) +
95 sizeof(addr
) + sizeof(struct ceph_timespec
),
97 mds
= ceph_decode_32(p
);
98 inc
= ceph_decode_32(p
);
99 state
= ceph_decode_32(p
);
100 state_seq
= ceph_decode_64(p
);
102 *p
+= sizeof(struct ceph_timespec
);
104 ceph_decode_32_safe(p
, end
, namelen
, bad
);
106 if (infoversion
>= 2) {
107 ceph_decode_32_safe(p
, end
, num_export_targets
, bad
);
108 pexport_targets
= *p
;
109 *p
+= num_export_targets
* sizeof(u32
);
111 num_export_targets
= 0;
114 dout("mdsmap_decode %d/%d mds%d.%d %s %s\n",
115 i
+1, n
, mds
, inc
, pr_addr(&addr
.in_addr
),
116 ceph_mds_state_name(state
));
117 if (mds
>= 0 && mds
< m
->m_max_mds
&& state
> 0) {
118 m
->m_info
[mds
].state
= state
;
119 m
->m_info
[mds
].addr
= addr
;
120 m
->m_info
[mds
].num_export_targets
= num_export_targets
;
121 if (num_export_targets
) {
122 m
->m_info
[mds
].export_targets
=
123 kcalloc(num_export_targets
, sizeof(u32
),
125 for (j
= 0; j
< num_export_targets
; j
++)
126 m
->m_info
[mds
].export_targets
[j
] =
127 ceph_decode_32(&pexport_targets
);
129 m
->m_info
[mds
].export_targets
= NULL
;
135 ceph_decode_32_safe(p
, end
, n
, bad
);
136 m
->m_num_data_pg_pools
= n
;
137 m
->m_data_pg_pools
= kcalloc(n
, sizeof(u32
), GFP_NOFS
);
138 if (!m
->m_data_pg_pools
)
140 ceph_decode_need(p
, end
, sizeof(u32
)*(n
+1), bad
);
141 for (i
= 0; i
< n
; i
++)
142 m
->m_data_pg_pools
[i
] = ceph_decode_32(p
);
143 m
->m_cas_pg_pool
= ceph_decode_32(p
);
145 /* ok, we don't care about the rest. */
146 dout("mdsmap_decode success epoch %u\n", m
->m_epoch
);
152 pr_err("corrupt mdsmap\n");
153 ceph_mdsmap_destroy(m
);
154 return ERR_PTR(-EINVAL
);
157 void ceph_mdsmap_destroy(struct ceph_mdsmap
*m
)
161 for (i
= 0; i
< m
->m_max_mds
; i
++)
162 kfree(m
->m_info
[i
].export_targets
);
164 kfree(m
->m_data_pg_pools
);