aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/osdmap.c
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-09-28 13:11:04 -0400
committerSage Weil <sage@newdream.net>2011-09-28 13:13:35 -0400
commit8adc8b3d780363d5df0dd6ace10336e3d7e331a1 (patch)
tree18ea04f84f3138561f5a5d09699271b213827f3e /net/ceph/osdmap.c
parent782e182e91e97f529a1edb30fdece9f1bef90ecc (diff)
libceph: fix pg_temp mapping update
The incremental map updates have a record for each pg_temp mapping that is to be add/updated (len > 0) or removed (len == 0). The old code was written as if the updates were a complete enumeration; that was just wrong. Update the code to remove 0-length entries and drop the rbtree traversal. This avoids misdirected (and hung) requests that manifest as server errors like [WRN] client4104 10.0.1.219:0/275025290 misdirected client4104.1:129 0.1 to osd0 not [1,0] in e11/11 Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'net/ceph/osdmap.c')
-rw-r--r--net/ceph/osdmap.c50
1 files changed, 24 insertions, 26 deletions
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
index eceb8d56703c..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
383static 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;