diff options
author | Jeff Layton <jlayton@kernel.org> | 2019-06-04 15:10:44 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2019-07-08 14:01:43 +0200 |
commit | 8cb5f2b4fcf4b8a4043e26c232b435e83e2abe87 (patch) | |
tree | 44cacb467fa11c66df717ba819f603f366c69869 /net/ceph | |
parent | 51fc7ab44519adc6684ac6575826f8b1a16ee4b3 (diff) | |
download | linux-8cb5f2b4fcf4b8a4043e26c232b435e83e2abe87.tar.bz2 |
libceph: correctly decode ADDR2 addresses in incremental OSD maps
Given the new format, we have to decode the addresses twice. Once to
skip past the new_up_client field, and a second time to collect the
addresses.
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: "Yan, Zheng" <zyan@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net/ceph')
-rw-r--r-- | net/ceph/osdmap.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 95e98ae59a54..90437906b7bc 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1618,12 +1618,17 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, void *new_state; void *new_weight_end; u32 len; + int i; new_up_client = *p; ceph_decode_32_safe(p, end, len, e_inval); - len *= sizeof(u32) + sizeof(struct ceph_entity_addr); - ceph_decode_need(p, end, len, e_inval); - *p += len; + for (i = 0; i < len; ++i) { + struct ceph_entity_addr addr; + + ceph_decode_skip_32(p, end, e_inval); + if (ceph_decode_entity_addr(p, end, &addr)) + goto e_inval; + } new_state = *p; ceph_decode_32_safe(p, end, len, e_inval); @@ -1699,9 +1704,9 @@ static int decode_new_up_state_weight(void **p, void *end, u8 struct_v, struct ceph_entity_addr addr; osd = ceph_decode_32(p); - ceph_decode_copy(p, &addr, sizeof(addr)); - ceph_decode_addr(&addr); BUG_ON(osd >= map->max_osd); + if (ceph_decode_entity_addr(p, end, &addr)) + goto e_inval; pr_info("osd%d up\n", osd); map->osd_state[osd] |= CEPH_OSD_EXISTS | CEPH_OSD_UP; map->osd_addr[osd] = addr; |