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 | |
| 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>
| -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; |
