ceph: decode v5 of osdmap (pool names) [protocol change]
Teach the client to decode an updated format for the osdmap. The new format includes pool names, which will be useful shortly. Get this change in earlier rather than later. Signed-off-by: Sage Weil <sage@newdream.net>
This commit is contained in:
parent
0e0d5e0c4b
commit
2844a76a25
180
fs/ceph/osdmap.c
180
fs/ceph/osdmap.c
@ -312,71 +312,6 @@ static struct crush_map *crush_decode(void *pbyval, void *end)
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* osd map
|
||||
*/
|
||||
void ceph_osdmap_destroy(struct ceph_osdmap *map)
|
||||
{
|
||||
dout("osdmap_destroy %p\n", map);
|
||||
if (map->crush)
|
||||
crush_destroy(map->crush);
|
||||
while (!RB_EMPTY_ROOT(&map->pg_temp)) {
|
||||
struct ceph_pg_mapping *pg =
|
||||
rb_entry(rb_first(&map->pg_temp),
|
||||
struct ceph_pg_mapping, node);
|
||||
rb_erase(&pg->node, &map->pg_temp);
|
||||
kfree(pg);
|
||||
}
|
||||
while (!RB_EMPTY_ROOT(&map->pg_pools)) {
|
||||
struct ceph_pg_pool_info *pi =
|
||||
rb_entry(rb_first(&map->pg_pools),
|
||||
struct ceph_pg_pool_info, node);
|
||||
rb_erase(&pi->node, &map->pg_pools);
|
||||
kfree(pi);
|
||||
}
|
||||
kfree(map->osd_state);
|
||||
kfree(map->osd_weight);
|
||||
kfree(map->osd_addr);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust max osd value. reallocate arrays.
|
||||
*/
|
||||
static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
|
||||
{
|
||||
u8 *state;
|
||||
struct ceph_entity_addr *addr;
|
||||
u32 *weight;
|
||||
|
||||
state = kcalloc(max, sizeof(*state), GFP_NOFS);
|
||||
addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
|
||||
weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
|
||||
if (state == NULL || addr == NULL || weight == NULL) {
|
||||
kfree(state);
|
||||
kfree(addr);
|
||||
kfree(weight);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* copy old? */
|
||||
if (map->osd_state) {
|
||||
memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
|
||||
memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
|
||||
memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
|
||||
kfree(map->osd_state);
|
||||
kfree(map->osd_addr);
|
||||
kfree(map->osd_weight);
|
||||
}
|
||||
|
||||
map->osd_state = state;
|
||||
map->osd_weight = weight;
|
||||
map->osd_addr = addr;
|
||||
map->max_osd = max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
|
||||
* to a set of osds)
|
||||
@ -480,6 +415,13 @@ static struct ceph_pg_pool_info *__lookup_pg_pool(struct rb_root *root, int id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
|
||||
{
|
||||
rb_erase(&pi->node, root);
|
||||
kfree(pi->name);
|
||||
kfree(pi);
|
||||
}
|
||||
|
||||
void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
|
||||
{
|
||||
ceph_decode_copy(p, &pi->v, sizeof(pi->v));
|
||||
@ -488,6 +430,98 @@ void __decode_pool(void **p, struct ceph_pg_pool_info *pi)
|
||||
*p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2;
|
||||
}
|
||||
|
||||
static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map)
|
||||
{
|
||||
struct ceph_pg_pool_info *pi;
|
||||
u32 num, len, pool;
|
||||
|
||||
ceph_decode_32_safe(p, end, num, bad);
|
||||
dout(" %d pool names\n", num);
|
||||
while (num--) {
|
||||
ceph_decode_32_safe(p, end, pool, bad);
|
||||
ceph_decode_32_safe(p, end, len, bad);
|
||||
dout(" pool %d len %d\n", pool, len);
|
||||
pi = __lookup_pg_pool(&map->pg_pools, pool);
|
||||
if (pi) {
|
||||
kfree(pi->name);
|
||||
pi->name = kmalloc(len + 1, GFP_NOFS);
|
||||
if (pi->name) {
|
||||
memcpy(pi->name, *p, len);
|
||||
pi->name[len] = '\0';
|
||||
dout(" name is %s\n", pi->name);
|
||||
}
|
||||
}
|
||||
*p += len;
|
||||
}
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* osd map
|
||||
*/
|
||||
void ceph_osdmap_destroy(struct ceph_osdmap *map)
|
||||
{
|
||||
dout("osdmap_destroy %p\n", map);
|
||||
if (map->crush)
|
||||
crush_destroy(map->crush);
|
||||
while (!RB_EMPTY_ROOT(&map->pg_temp)) {
|
||||
struct ceph_pg_mapping *pg =
|
||||
rb_entry(rb_first(&map->pg_temp),
|
||||
struct ceph_pg_mapping, node);
|
||||
rb_erase(&pg->node, &map->pg_temp);
|
||||
kfree(pg);
|
||||
}
|
||||
while (!RB_EMPTY_ROOT(&map->pg_pools)) {
|
||||
struct ceph_pg_pool_info *pi =
|
||||
rb_entry(rb_first(&map->pg_pools),
|
||||
struct ceph_pg_pool_info, node);
|
||||
__remove_pg_pool(&map->pg_pools, pi);
|
||||
}
|
||||
kfree(map->osd_state);
|
||||
kfree(map->osd_weight);
|
||||
kfree(map->osd_addr);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
/*
|
||||
* adjust max osd value. reallocate arrays.
|
||||
*/
|
||||
static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
|
||||
{
|
||||
u8 *state;
|
||||
struct ceph_entity_addr *addr;
|
||||
u32 *weight;
|
||||
|
||||
state = kcalloc(max, sizeof(*state), GFP_NOFS);
|
||||
addr = kcalloc(max, sizeof(*addr), GFP_NOFS);
|
||||
weight = kcalloc(max, sizeof(*weight), GFP_NOFS);
|
||||
if (state == NULL || addr == NULL || weight == NULL) {
|
||||
kfree(state);
|
||||
kfree(addr);
|
||||
kfree(weight);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* copy old? */
|
||||
if (map->osd_state) {
|
||||
memcpy(state, map->osd_state, map->max_osd*sizeof(*state));
|
||||
memcpy(addr, map->osd_addr, map->max_osd*sizeof(*addr));
|
||||
memcpy(weight, map->osd_weight, map->max_osd*sizeof(*weight));
|
||||
kfree(map->osd_state);
|
||||
kfree(map->osd_addr);
|
||||
kfree(map->osd_weight);
|
||||
}
|
||||
|
||||
map->osd_state = state;
|
||||
map->osd_weight = weight;
|
||||
map->osd_addr = addr;
|
||||
map->max_osd = max;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* decode a full map.
|
||||
*/
|
||||
@ -524,7 +558,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
|
||||
ceph_decode_32_safe(p, end, max, bad);
|
||||
while (max--) {
|
||||
ceph_decode_need(p, end, 4 + 1 + sizeof(pi->v), bad);
|
||||
pi = kmalloc(sizeof(*pi), GFP_NOFS);
|
||||
pi = kzalloc(sizeof(*pi), GFP_NOFS);
|
||||
if (!pi)
|
||||
goto bad;
|
||||
pi->id = ceph_decode_32(p);
|
||||
@ -537,6 +571,10 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
|
||||
__decode_pool(p, pi);
|
||||
__insert_pg_pool(&map->pg_pools, pi);
|
||||
}
|
||||
|
||||
if (version >= 5 && __decode_pool_names(p, end, map) < 0)
|
||||
goto bad;
|
||||
|
||||
ceph_decode_32_safe(p, end, map->pool_max, bad);
|
||||
|
||||
ceph_decode_32_safe(p, end, map->flags, bad);
|
||||
@ -710,7 +748,7 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
|
||||
}
|
||||
pi = __lookup_pg_pool(&map->pg_pools, pool);
|
||||
if (!pi) {
|
||||
pi = kmalloc(sizeof(*pi), GFP_NOFS);
|
||||
pi = kzalloc(sizeof(*pi), GFP_NOFS);
|
||||
if (!pi) {
|
||||
err = -ENOMEM;
|
||||
goto bad;
|
||||
@ -720,6 +758,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
|
||||
}
|
||||
__decode_pool(p, pi);
|
||||
}
|
||||
if (version >= 5 && __decode_pool_names(p, end, map) < 0)
|
||||
goto bad;
|
||||
|
||||
/* old_pool */
|
||||
ceph_decode_32_safe(p, end, len, bad);
|
||||
@ -728,10 +768,8 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
|
||||
|
||||
ceph_decode_32_safe(p, end, pool, bad);
|
||||
pi = __lookup_pg_pool(&map->pg_pools, pool);
|
||||
if (pi) {
|
||||
rb_erase(&pi->node, &map->pg_pools);
|
||||
kfree(pi);
|
||||
}
|
||||
if (pi)
|
||||
__remove_pg_pool(&map->pg_pools, pi);
|
||||
}
|
||||
|
||||
/* new_up */
|
||||
|
@ -23,6 +23,7 @@ struct ceph_pg_pool_info {
|
||||
int id;
|
||||
struct ceph_pg_pool v;
|
||||
int pg_num_mask, pgp_num_mask, lpg_num_mask, lpgp_num_mask;
|
||||
char *name;
|
||||
};
|
||||
|
||||
struct ceph_pg_mapping {
|
||||
|
@ -11,8 +11,10 @@
|
||||
/*
|
||||
* osdmap encoding versions
|
||||
*/
|
||||
#define CEPH_OSDMAP_INC_VERSION 4
|
||||
#define CEPH_OSDMAP_VERSION 4
|
||||
#define CEPH_OSDMAP_INC_VERSION 5
|
||||
#define CEPH_OSDMAP_INC_VERSION_EXT 5
|
||||
#define CEPH_OSDMAP_VERSION 5
|
||||
#define CEPH_OSDMAP_VERSION_EXT 5
|
||||
|
||||
/*
|
||||
* fs id
|
||||
|
Loading…
Reference in New Issue
Block a user