aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2010-02-16 18:53:32 -0500
committerSage Weil <sage@newdream.net>2010-02-17 13:02:48 -0500
commit9794b146fa7b93f8ab74fb62d67fdefad760769f (patch)
tree9478fc2cad415db3baf69e8b975fc33b5917bdf6 /fs
parent7c1332b8cb5b27656cf6ab1f5fe808a8eb8bb2c0 (diff)
ceph: fix memory leak when destroying osdmap with pg_temp mappings
Also move _lookup_pg_mapping into a helper. Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/osdmap.c49
1 files changed, 33 insertions, 16 deletions
diff --git a/fs/ceph/osdmap.c b/fs/ceph/osdmap.c
index a6afe3836f7e..443fdcdb19c4 100644
--- a/fs/ceph/osdmap.c
+++ b/fs/ceph/osdmap.c
@@ -321,8 +321,13 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map)
321 dout("osdmap_destroy %p\n", map); 321 dout("osdmap_destroy %p\n", map);
322 if (map->crush) 322 if (map->crush)
323 crush_destroy(map->crush); 323 crush_destroy(map->crush);
324 while (!RB_EMPTY_ROOT(&map->pg_temp)) 324 while (!RB_EMPTY_ROOT(&map->pg_temp)) {
325 rb_erase(rb_first(&map->pg_temp), &map->pg_temp); 325 struct ceph_pg_mapping *pg =
326 rb_entry(rb_first(&map->pg_temp),
327 struct ceph_pg_mapping, node);
328 rb_erase(&pg->node, &map->pg_temp);
329 kfree(pg);
330 }
326 kfree(map->osd_state); 331 kfree(map->osd_state);
327 kfree(map->osd_weight); 332 kfree(map->osd_weight);
328 kfree(map->pg_pool); 333 kfree(map->pg_pool);
@@ -367,7 +372,8 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
367} 372}
368 373
369/* 374/*
370 * Insert a new pg_temp mapping 375 * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
376 * to a set of osds)
371 */ 377 */
372static int pgid_cmp(struct ceph_pg l, struct ceph_pg r) 378static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
373{ 379{
@@ -406,6 +412,26 @@ static int __insert_pg_mapping(struct ceph_pg_mapping *new,
406 return 0; 412 return 0;
407} 413}
408 414
415static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root,
416 struct ceph_pg pgid)
417{
418 struct rb_node *n = root->rb_node;
419 struct ceph_pg_mapping *pg;
420 int c;
421
422 while (n) {
423 pg = rb_entry(n, struct ceph_pg_mapping, node);
424 c = pgid_cmp(pgid, pg->pgid);
425 if (c < 0)
426 n = n->rb_left;
427 else if (c > 0)
428 n = n->rb_right;
429 else
430 return pg;
431 }
432 return NULL;
433}
434
409/* 435/*
410 * decode a full map. 436 * decode a full map.
411 */ 437 */
@@ -870,26 +896,17 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
870static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, 896static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
871 int *osds, int *num) 897 int *osds, int *num)
872{ 898{
873 struct rb_node *n = osdmap->pg_temp.rb_node;
874 struct ceph_pg_mapping *pg; 899 struct ceph_pg_mapping *pg;
875 struct ceph_pg_pool_info *pool; 900 struct ceph_pg_pool_info *pool;
876 int ruleno; 901 int ruleno;
877 unsigned poolid, ps, pps; 902 unsigned poolid, ps, pps;
878 int preferred; 903 int preferred;
879 int c;
880 904
881 /* pg_temp? */ 905 /* pg_temp? */
882 while (n) { 906 pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
883 pg = rb_entry(n, struct ceph_pg_mapping, node); 907 if (pg) {
884 c = pgid_cmp(pgid, pg->pgid); 908 *num = pg->len;
885 if (c < 0) 909 return pg->osds;
886 n = n->rb_left;
887 else if (c > 0)
888 n = n->rb_right;
889 else {
890 *num = pg->len;
891 return pg->osds;
892 }
893 } 910 }
894 911
895 /* crush */ 912 /* crush */