aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIlya Dryomov <ilya.dryomov@inktank.com>2014-03-21 13:05:28 -0400
committerSage Weil <sage@inktank.com>2014-04-05 00:07:53 -0400
commit10db634e2083a202a26123d6d4c9ede98d6a1199 (patch)
treeb4ea2a78c91e8a9a1aa07344ffad0874ec078efc /net
parent4d60351f9089ef0f39d73c0b6a103e61fc0ed187 (diff)
libceph: introduce decode{,_new}_pg_temp() and switch to them
Consolidate pg_temp (full map, map<pg_t, vector<u32>>) and new_pg_temp (inc map, same) decoding logic into a common helper and switch to it. Signed-off-by: Ilya Dryomov <ilya.dryomov@inktank.com> Reviewed-by: Alex Elder <elder@linaro.org>
Diffstat (limited to 'net')
-rw-r--r--net/ceph/osdmap.c139
1 files changed, 67 insertions, 72 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index a350286fd826..6497322d2e3c 100644
--- a/net/ceph/osdmap.c
+++ b/net/ceph/osdmap.c
@@ -732,6 +732,67 @@ static int decode_new_pools(void **p, void *end, struct ceph_osdmap *map)
732 return __decode_pools(p, end, map, true); 732 return __decode_pools(p, end, map, true);
733} 733}
734 734
735static int __decode_pg_temp(void **p, void *end, struct ceph_osdmap *map,
736 bool incremental)
737{
738 u32 n;
739
740 ceph_decode_32_safe(p, end, n, e_inval);
741 while (n--) {
742 struct ceph_pg pgid;
743 u32 len, i;
744 int ret;
745
746 ret = ceph_decode_pgid(p, end, &pgid);
747 if (ret)
748 return ret;
749
750 ceph_decode_32_safe(p, end, len, e_inval);
751
752 ret = __remove_pg_mapping(&map->pg_temp, pgid);
753 BUG_ON(!incremental && ret != -ENOENT);
754
755 if (!incremental || len > 0) {
756 struct ceph_pg_mapping *pg;
757
758 ceph_decode_need(p, end, len*sizeof(u32), e_inval);
759
760 if (len > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
761 return -EINVAL;
762
763 pg = kzalloc(sizeof(*pg) + len*sizeof(u32), GFP_NOFS);
764 if (!pg)
765 return -ENOMEM;
766
767 pg->pgid = pgid;
768 pg->len = len;
769 for (i = 0; i < len; i++)
770 pg->osds[i] = ceph_decode_32(p);
771
772 ret = __insert_pg_mapping(pg, &map->pg_temp);
773 if (ret) {
774 kfree(pg);
775 return ret;
776 }
777 }
778 }
779
780 return 0;
781
782e_inval:
783 return -EINVAL;
784}
785
786static int decode_pg_temp(void **p, void *end, struct ceph_osdmap *map)
787{
788 return __decode_pg_temp(p, end, map, false);
789}
790
791static int decode_new_pg_temp(void **p, void *end, struct ceph_osdmap *map)
792{
793 return __decode_pg_temp(p, end, map, true);
794}
795
735/* 796/*
736 * decode a full map. 797 * decode a full map.
737 */ 798 */
@@ -810,36 +871,9 @@ static int osdmap_decode(void **p, void *end, struct ceph_osdmap *map)
810 ceph_decode_addr(&map->osd_addr[i]); 871 ceph_decode_addr(&map->osd_addr[i]);
811 872
812 /* pg_temp */ 873 /* pg_temp */
813 ceph_decode_32_safe(p, end, len, e_inval); 874 err = decode_pg_temp(p, end, map);
814 for (i = 0; i < len; i++) { 875 if (err)
815 int n, j; 876 goto bad;
816 struct ceph_pg pgid;
817 struct ceph_pg_mapping *pg;
818
819 err = ceph_decode_pgid(p, end, &pgid);
820 if (err)
821 goto bad;
822 ceph_decode_need(p, end, sizeof(u32), e_inval);
823 n = ceph_decode_32(p);
824 if (n > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
825 goto e_inval;
826 ceph_decode_need(p, end, n * sizeof(u32), e_inval);
827 pg = kmalloc(sizeof(*pg) + n*sizeof(u32), GFP_NOFS);
828 if (!pg) {
829 err = -ENOMEM;
830 goto bad;
831 }
832 pg->pgid = pgid;
833 pg->len = n;
834 for (j = 0; j < n; j++)
835 pg->osds[j] = ceph_decode_32(p);
836
837 err = __insert_pg_mapping(pg, &map->pg_temp);
838 if (err)
839 goto bad;
840 dout(" added pg_temp %lld.%x len %d\n", pgid.pool, pgid.seed,
841 len);
842 }
843 877
844 /* crush */ 878 /* crush */
845 ceph_decode_32_safe(p, end, len, e_inval); 879 ceph_decode_32_safe(p, end, len, e_inval);
@@ -1038,48 +1072,9 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
1038 } 1072 }
1039 1073
1040 /* new_pg_temp */ 1074 /* new_pg_temp */
1041 ceph_decode_32_safe(p, end, len, e_inval); 1075 err = decode_new_pg_temp(p, end, map);
1042 while (len--) { 1076 if (err)
1043 struct ceph_pg_mapping *pg; 1077 goto bad;
1044 int j;
1045 struct ceph_pg pgid;
1046 u32 pglen;
1047
1048 err = ceph_decode_pgid(p, end, &pgid);
1049 if (err)
1050 goto bad;
1051 ceph_decode_need(p, end, sizeof(u32), e_inval);
1052 pglen = ceph_decode_32(p);
1053 if (pglen) {
1054 ceph_decode_need(p, end, pglen*sizeof(u32), e_inval);
1055
1056 /* removing existing (if any) */
1057 (void) __remove_pg_mapping(&map->pg_temp, pgid);
1058
1059 /* insert */
1060 if (pglen > (UINT_MAX - sizeof(*pg)) / sizeof(u32))
1061 goto e_inval;
1062 pg = kmalloc(sizeof(*pg) + sizeof(u32)*pglen, GFP_NOFS);
1063 if (!pg) {
1064 err = -ENOMEM;
1065 goto bad;
1066 }
1067 pg->pgid = pgid;
1068 pg->len = pglen;
1069 for (j = 0; j < pglen; j++)
1070 pg->osds[j] = ceph_decode_32(p);
1071 err = __insert_pg_mapping(pg, &map->pg_temp);
1072 if (err) {
1073 kfree(pg);
1074 goto bad;
1075 }
1076 dout(" added pg_temp %lld.%x len %d\n", pgid.pool,
1077 pgid.seed, pglen);
1078 } else {
1079 /* remove */
1080 __remove_pg_mapping(&map->pg_temp, pgid);
1081 }
1082 }
1083 1078
1084 /* ignore the rest */ 1079 /* ignore the rest */
1085 *p = end; 1080 *p = end;