diff options
Diffstat (limited to 'net/ceph/osdmap.c')
-rw-r--r-- | net/ceph/osdmap.c | 84 |
1 files changed, 45 insertions, 39 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index e97c3588c3ec..fd863fe76934 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -339,6 +339,7 @@ static int __insert_pg_mapping(struct ceph_pg_mapping *new, | |||
339 | struct ceph_pg_mapping *pg = NULL; | 339 | struct ceph_pg_mapping *pg = NULL; |
340 | int c; | 340 | int c; |
341 | 341 | ||
342 | dout("__insert_pg_mapping %llx %p\n", *(u64 *)&new->pgid, new); | ||
342 | while (*p) { | 343 | while (*p) { |
343 | parent = *p; | 344 | parent = *p; |
344 | pg = rb_entry(parent, struct ceph_pg_mapping, node); | 345 | pg = rb_entry(parent, struct ceph_pg_mapping, node); |
@@ -366,16 +367,33 @@ static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root, | |||
366 | while (n) { | 367 | while (n) { |
367 | pg = rb_entry(n, struct ceph_pg_mapping, node); | 368 | pg = rb_entry(n, struct ceph_pg_mapping, node); |
368 | c = pgid_cmp(pgid, pg->pgid); | 369 | c = pgid_cmp(pgid, pg->pgid); |
369 | if (c < 0) | 370 | if (c < 0) { |
370 | n = n->rb_left; | 371 | n = n->rb_left; |
371 | else if (c > 0) | 372 | } else if (c > 0) { |
372 | n = n->rb_right; | 373 | n = n->rb_right; |
373 | else | 374 | } else { |
375 | dout("__lookup_pg_mapping %llx got %p\n", | ||
376 | *(u64 *)&pgid, pg); | ||
374 | return pg; | 377 | return pg; |
378 | } | ||
375 | } | 379 | } |
376 | return NULL; | 380 | return NULL; |
377 | } | 381 | } |
378 | 382 | ||
383 | static int __remove_pg_mapping(struct rb_root *root, struct ceph_pg pgid) | ||
384 | { | ||
385 | struct ceph_pg_mapping *pg = __lookup_pg_mapping(root, pgid); | ||
386 | |||
387 | if (pg) { | ||
388 | dout("__remove_pg_mapping %llx %p\n", *(u64 *)&pgid, pg); | ||
389 | rb_erase(&pg->node, root); | ||
390 | kfree(pg); | ||
391 | return 0; | ||
392 | } | ||
393 | dout("__remove_pg_mapping %llx dne\n", *(u64 *)&pgid); | ||
394 | return -ENOENT; | ||
395 | } | ||
396 | |||
379 | /* | 397 | /* |
380 | * rbtree of pg pool info | 398 | * rbtree of pg pool info |
381 | */ | 399 | */ |
@@ -711,7 +729,6 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
711 | void *start = *p; | 729 | void *start = *p; |
712 | int err = -EINVAL; | 730 | int err = -EINVAL; |
713 | u16 version; | 731 | u16 version; |
714 | struct rb_node *rbp; | ||
715 | 732 | ||
716 | ceph_decode_16_safe(p, end, version, bad); | 733 | ceph_decode_16_safe(p, end, version, bad); |
717 | if (version > CEPH_OSDMAP_INC_VERSION) { | 734 | if (version > CEPH_OSDMAP_INC_VERSION) { |
@@ -861,7 +878,6 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
861 | } | 878 | } |
862 | 879 | ||
863 | /* new_pg_temp */ | 880 | /* new_pg_temp */ |
864 | rbp = rb_first(&map->pg_temp); | ||
865 | ceph_decode_32_safe(p, end, len, bad); | 881 | ceph_decode_32_safe(p, end, len, bad); |
866 | while (len--) { | 882 | while (len--) { |
867 | struct ceph_pg_mapping *pg; | 883 | struct ceph_pg_mapping *pg; |
@@ -872,18 +888,6 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
872 | ceph_decode_copy(p, &pgid, sizeof(pgid)); | 888 | ceph_decode_copy(p, &pgid, sizeof(pgid)); |
873 | pglen = ceph_decode_32(p); | 889 | pglen = ceph_decode_32(p); |
874 | 890 | ||
875 | /* remove any? */ | ||
876 | while (rbp && pgid_cmp(rb_entry(rbp, struct ceph_pg_mapping, | ||
877 | node)->pgid, pgid) <= 0) { | ||
878 | struct ceph_pg_mapping *cur = | ||
879 | rb_entry(rbp, struct ceph_pg_mapping, node); | ||
880 | |||
881 | rbp = rb_next(rbp); | ||
882 | dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid); | ||
883 | rb_erase(&cur->node, &map->pg_temp); | ||
884 | kfree(cur); | ||
885 | } | ||
886 | |||
887 | if (pglen) { | 891 | if (pglen) { |
888 | /* insert */ | 892 | /* insert */ |
889 | ceph_decode_need(p, end, pglen*sizeof(u32), bad); | 893 | ceph_decode_need(p, end, pglen*sizeof(u32), bad); |
@@ -903,17 +907,11 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end, | |||
903 | } | 907 | } |
904 | dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, | 908 | dout(" added pg_temp %llx len %d\n", *(u64 *)&pgid, |
905 | pglen); | 909 | pglen); |
910 | } else { | ||
911 | /* remove */ | ||
912 | __remove_pg_mapping(&map->pg_temp, pgid); | ||
906 | } | 913 | } |
907 | } | 914 | } |
908 | while (rbp) { | ||
909 | struct ceph_pg_mapping *cur = | ||
910 | rb_entry(rbp, struct ceph_pg_mapping, node); | ||
911 | |||
912 | rbp = rb_next(rbp); | ||
913 | dout(" removed pg_temp %llx\n", *(u64 *)&cur->pgid); | ||
914 | rb_erase(&cur->node, &map->pg_temp); | ||
915 | kfree(cur); | ||
916 | } | ||
917 | 915 | ||
918 | /* ignore the rest */ | 916 | /* ignore the rest */ |
919 | *p = end; | 917 | *p = end; |
@@ -1046,10 +1044,25 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
1046 | struct ceph_pg_mapping *pg; | 1044 | struct ceph_pg_mapping *pg; |
1047 | struct ceph_pg_pool_info *pool; | 1045 | struct ceph_pg_pool_info *pool; |
1048 | int ruleno; | 1046 | int ruleno; |
1049 | unsigned poolid, ps, pps; | 1047 | unsigned poolid, ps, pps, t; |
1050 | int preferred; | 1048 | int preferred; |
1051 | 1049 | ||
1050 | poolid = le32_to_cpu(pgid.pool); | ||
1051 | ps = le16_to_cpu(pgid.ps); | ||
1052 | preferred = (s16)le16_to_cpu(pgid.preferred); | ||
1053 | |||
1054 | pool = __lookup_pg_pool(&osdmap->pg_pools, poolid); | ||
1055 | if (!pool) | ||
1056 | return NULL; | ||
1057 | |||
1052 | /* pg_temp? */ | 1058 | /* pg_temp? */ |
1059 | if (preferred >= 0) | ||
1060 | t = ceph_stable_mod(ps, le32_to_cpu(pool->v.lpg_num), | ||
1061 | pool->lpgp_num_mask); | ||
1062 | else | ||
1063 | t = ceph_stable_mod(ps, le32_to_cpu(pool->v.pg_num), | ||
1064 | pool->pgp_num_mask); | ||
1065 | pgid.ps = cpu_to_le16(t); | ||
1053 | pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid); | 1066 | pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid); |
1054 | if (pg) { | 1067 | if (pg) { |
1055 | *num = pg->len; | 1068 | *num = pg->len; |
@@ -1057,18 +1070,6 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
1057 | } | 1070 | } |
1058 | 1071 | ||
1059 | /* crush */ | 1072 | /* crush */ |
1060 | poolid = le32_to_cpu(pgid.pool); | ||
1061 | ps = le16_to_cpu(pgid.ps); | ||
1062 | preferred = (s16)le16_to_cpu(pgid.preferred); | ||
1063 | |||
1064 | /* don't forcefeed bad device ids to crush */ | ||
1065 | if (preferred >= osdmap->max_osd || | ||
1066 | preferred >= osdmap->crush->max_devices) | ||
1067 | preferred = -1; | ||
1068 | |||
1069 | pool = __lookup_pg_pool(&osdmap->pg_pools, poolid); | ||
1070 | if (!pool) | ||
1071 | return NULL; | ||
1072 | ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset, | 1073 | ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset, |
1073 | pool->v.type, pool->v.size); | 1074 | pool->v.type, pool->v.size); |
1074 | if (ruleno < 0) { | 1075 | if (ruleno < 0) { |
@@ -1078,6 +1079,11 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, | |||
1078 | return NULL; | 1079 | return NULL; |
1079 | } | 1080 | } |
1080 | 1081 | ||
1082 | /* don't forcefeed bad device ids to crush */ | ||
1083 | if (preferred >= osdmap->max_osd || | ||
1084 | preferred >= osdmap->crush->max_devices) | ||
1085 | preferred = -1; | ||
1086 | |||
1081 | if (preferred >= 0) | 1087 | if (preferred >= 0) |
1082 | pps = ceph_stable_mod(ps, | 1088 | pps = ceph_stable_mod(ps, |
1083 | le32_to_cpu(pool->v.lpgp_num), | 1089 | le32_to_cpu(pool->v.lpgp_num), |