diff options
author | Ilya Dryomov <ilya.dryomov@inktank.com> | 2014-03-21 13:05:29 -0400 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2014-04-05 00:07:55 -0400 |
commit | ec7af97258396161e6effba7e788c3fc3cb55263 (patch) | |
tree | fc00b89d05b40fadd9dba80fe8c31fc316a605eb /net/ceph | |
parent | 10db634e2083a202a26123d6d4c9ede98d6a1199 (diff) |
libceph: introduce get_osdmap_client_data_v()
Full and incremental osdmaps are structured identically and have
identical headers. Add a helper to decode both "old" (16-bit version,
v6) and "new" (8-bit struct_v+struct_compat+struct_len, v7) osdmap
enconding headers and switch to it.
Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com>
Reviewed-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'net/ceph')
-rw-r--r-- | net/ceph/osdmap.c | 81 |
1 files changed, 65 insertions, 16 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 6497322d2e3c..be2a65fbd902 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -683,6 +683,63 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max) | |||
683 | return 0; | 683 | return 0; |
684 | } | 684 | } |
685 | 685 | ||
686 | #define OSDMAP_WRAPPER_COMPAT_VER 7 | ||
687 | #define OSDMAP_CLIENT_DATA_COMPAT_VER 1 | ||
688 | |||
689 | /* | ||
690 | * Return 0 or error. On success, *v is set to 0 for old (v6) osdmaps, | ||
691 | * to struct_v of the client_data section for new (v7 and above) | ||
692 | * osdmaps. | ||
693 | */ | ||
694 | static int get_osdmap_client_data_v(void **p, void *end, | ||
695 | const char *prefix, u8 *v) | ||
696 | { | ||
697 | u8 struct_v; | ||
698 | |||
699 | ceph_decode_8_safe(p, end, struct_v, e_inval); | ||
700 | if (struct_v >= 7) { | ||
701 | u8 struct_compat; | ||
702 | |||
703 | ceph_decode_8_safe(p, end, struct_compat, e_inval); | ||
704 | if (struct_compat > OSDMAP_WRAPPER_COMPAT_VER) { | ||
705 | pr_warning("got v %d cv %d > %d of %s ceph_osdmap\n", | ||
706 | struct_v, struct_compat, | ||
707 | OSDMAP_WRAPPER_COMPAT_VER, prefix); | ||
708 | return -EINVAL; | ||
709 | } | ||
710 | *p += 4; /* ignore wrapper struct_len */ | ||
711 | |||
712 | ceph_decode_8_safe(p, end, struct_v, e_inval); | ||
713 | ceph_decode_8_safe(p, end, struct_compat, e_inval); | ||
714 | if (struct_compat > OSDMAP_CLIENT_DATA_COMPAT_VER) { | ||
715 | pr_warning("got v %d cv %d > %d of %s ceph_osdmap client data\n", | ||
716 | struct_v, struct_compat, | ||
717 | OSDMAP_CLIENT_DATA_COMPAT_VER, prefix); | ||
718 | return -EINVAL; | ||
719 | } | ||
720 | *p += 4; /* ignore client data struct_len */ | ||
721 | } else { | ||
722 | u16 version; | ||
723 | |||
724 | *p -= 1; | ||
725 | ceph_decode_16_safe(p, end, version, e_inval); | ||
726 | if (version < 6) { | ||
727 | pr_warning("got v %d < 6 of %s ceph_osdmap\n", version, | ||
728 | prefix); | ||
729 | return -EINVAL; | ||
730 | } | ||
731 | |||
732 | /* old osdmap enconding */ | ||
733 | struct_v = 0; | ||
734 | } | ||
735 | |||
736 | *v = struct_v; | ||
737 | return 0; | ||
738 | |||
739 | e_inval: | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | |||
686 | static int __decode_pools(void **p, void *end, struct ceph_osdmap *map, | 743 | static int __decode_pools(void **p, void *end, struct ceph_osdmap *map, |
687 | bool incremental) | 744 | bool incremental) |
688 | { | 745 | { |
@@ -798,7 +855,7 @@ static int decode_new_pg_temp(void **p, void *end, struct ceph_osdmap *map) | |||
798 | */ | 855 | */ |
799 | static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map) | 856 | static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map) |
800 | { | 857 | { |
801 | u16 version; | 858 | u8 struct_v; |
802 | u32 epoch = 0; | 859 | u32 epoch = 0; |
803 | void *start = *p; | 860 | void *start = *p; |
804 | u32 max; | 861 | u32 max; |
@@ -807,15 +864,9 @@ static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map) | |||
807 | 864 | ||
808 | dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p)); | 865 | dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p)); |
809 | 866 | ||
810 | ceph_decode_16_safe(p, end, version, e_inval); | 867 | err = get_osdmap_client_data_v(p, end, "full", &struct_v); |
811 | if (version > 6) { | 868 | if (err) |
812 | pr_warning("got unknown v %d > 6 of osdmap\n", version); | 869 | goto bad; |
813 | goto e_inval; | ||
814 | } | ||
815 | if (version < 6) { | ||
816 | pr_warning("got old v %d < 6 of osdmap\n", version); | ||
817 | goto e_inval; | ||
818 | } | ||
819 | 870 | ||
820 | /* fsid, epoch, created, modified */ | 871 | /* fsid, epoch, created, modified */ |
821 | ceph_decode_need(p, end, sizeof(map->fsid) + sizeof(u32) + | 872 | ceph_decode_need(p, end, sizeof(map->fsid) + sizeof(u32) + |
@@ -943,15 +994,13 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
943 | __s32 new_flags, max; | 994 | __s32 new_flags, max; |
944 | void *start = *p; | 995 | void *start = *p; |
945 | int err; | 996 | int err; |
946 | u16 version; | 997 | u8 struct_v; |
947 | 998 | ||
948 | dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p)); | 999 | dout("%s %p to %p len %d\n", __func__, *p, end, (int)(end - *p)); |
949 | 1000 | ||
950 | ceph_decode_16_safe(p, end, version, e_inval); | 1001 | err = get_osdmap_client_data_v(p, end, "inc", &struct_v); |
951 | if (version != 6) { | 1002 | if (err) |
952 | pr_warning("got unknown v %d != 6 of inc osdmap\n", version); | 1003 | goto bad; |
953 | goto e_inval; | ||
954 | } | ||
955 | 1004 | ||
956 | /* fsid, epoch, modified, new_pool_max, new_flags */ | 1005 | /* fsid, epoch, modified, new_pool_max, new_flags */ |
957 | ceph_decode_need(p, end, sizeof(fsid) + sizeof(u32) + sizeof(modified) + | 1006 | ceph_decode_need(p, end, sizeof(fsid) + sizeof(u32) + sizeof(modified) + |