diff options
author | Sage Weil <sage@newdream.net> | 2010-08-02 14:00:55 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-08-02 14:10:07 -0400 |
commit | 73a7e693f9da464b0df07643af3f8ffc04dcc0b5 (patch) | |
tree | 1e0e09dd0ee0390e4da8f2247187b283e48b228e /fs | |
parent | 2d9c98ae97c18e8b1c363af6a2e51d5d9e8c5e04 (diff) |
ceph: fix decoding of pool snap info
The pool info contains a vector for snap_info_t, not snap ids. This fixes
the broken decoding, which would declare teh update corrupt when a pool
snapshot was created.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ceph/osdmap.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c index 1d5f58cc2d93..e94c6fb2e2a4 100644 --- a/fs/ceph/osdmap.c +++ b/fs/ceph/osdmap.c | |||
@@ -424,12 +424,30 @@ static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi) | |||
424 | kfree(pi); | 424 | kfree(pi); |
425 | } | 425 | } |
426 | 426 | ||
427 | static void __decode_pool(void **p, struct ceph_pg_pool_info *pi) | 427 | static int __decode_pool(void **p, void *end, struct ceph_pg_pool_info *pi) |
428 | { | 428 | { |
429 | unsigned n, m; | ||
430 | |||
429 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); | 431 | ceph_decode_copy(p, &pi->v, sizeof(pi->v)); |
430 | calc_pg_masks(pi); | 432 | calc_pg_masks(pi); |
431 | *p += le32_to_cpu(pi->v.num_snaps) * sizeof(u64); | 433 | |
434 | /* num_snaps * snap_info_t */ | ||
435 | n = le32_to_cpu(pi->v.num_snaps); | ||
436 | while (n--) { | ||
437 | ceph_decode_need(p, end, sizeof(u64) + 1 + sizeof(u64) + | ||
438 | sizeof(struct ceph_timespec), bad); | ||
439 | *p += sizeof(u64) + /* key */ | ||
440 | 1 + sizeof(u64) + /* u8, snapid */ | ||
441 | sizeof(struct ceph_timespec); | ||
442 | m = ceph_decode_32(p); /* snap name */ | ||
443 | *p += m; | ||
444 | } | ||
445 | |||
432 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; | 446 | *p += le32_to_cpu(pi->v.num_removed_snap_intervals) * sizeof(u64) * 2; |
447 | return 0; | ||
448 | |||
449 | bad: | ||
450 | return -EINVAL; | ||
433 | } | 451 | } |
434 | 452 | ||
435 | static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) | 453 | static int __decode_pool_names(void **p, void *end, struct ceph_osdmap *map) |
@@ -571,7 +589,9 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end) | |||
571 | kfree(pi); | 589 | kfree(pi); |
572 | goto bad; | 590 | goto bad; |
573 | } | 591 | } |
574 | __decode_pool(p, pi); | 592 | err = __decode_pool(p, end, pi); |
593 | if (err < 0) | ||
594 | goto bad; | ||
575 | __insert_pg_pool(&map->pg_pools, pi); | 595 | __insert_pg_pool(&map->pg_pools, pi); |
576 | } | 596 | } |
577 | 597 | ||
@@ -760,7 +780,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
760 | pi->id = pool; | 780 | pi->id = pool; |
761 | __insert_pg_pool(&map->pg_pools, pi); | 781 | __insert_pg_pool(&map->pg_pools, pi); |
762 | } | 782 | } |
763 | __decode_pool(p, pi); | 783 | err = __decode_pool(p, end, pi); |
784 | if (err < 0) | ||
785 | goto bad; | ||
764 | } | 786 | } |
765 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) | 787 | if (version >= 5 && __decode_pool_names(p, end, map) < 0) |
766 | goto bad; | 788 | goto bad; |