Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9794b146 authored by Sage Weil's avatar Sage Weil
Browse files

ceph: fix memory leak when destroying osdmap with pg_temp mappings



Also move _lookup_pg_mapping into a helper.

Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 7c1332b8
Loading
Loading
Loading
Loading
+33 −16
Original line number Original line Diff line number Diff line
@@ -321,8 +321,13 @@ void ceph_osdmap_destroy(struct ceph_osdmap *map)
	dout("osdmap_destroy %p\n", map);
	dout("osdmap_destroy %p\n", map);
	if (map->crush)
	if (map->crush)
		crush_destroy(map->crush);
		crush_destroy(map->crush);
	while (!RB_EMPTY_ROOT(&map->pg_temp))
	while (!RB_EMPTY_ROOT(&map->pg_temp)) {
		rb_erase(rb_first(&map->pg_temp), &map->pg_temp);
		struct ceph_pg_mapping *pg =
			rb_entry(rb_first(&map->pg_temp),
				 struct ceph_pg_mapping, node);
		rb_erase(&pg->node, &map->pg_temp);
		kfree(pg);
	}
	kfree(map->osd_state);
	kfree(map->osd_state);
	kfree(map->osd_weight);
	kfree(map->osd_weight);
	kfree(map->pg_pool);
	kfree(map->pg_pool);
@@ -367,7 +372,8 @@ static int osdmap_set_max_osd(struct ceph_osdmap *map, int max)
}
}


/*
/*
 * Insert a new pg_temp mapping
 * rbtree of pg_mapping for handling pg_temp (explicit mapping of pgid
 * to a set of osds)
 */
 */
static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
static int pgid_cmp(struct ceph_pg l, struct ceph_pg r)
{
{
@@ -406,6 +412,26 @@ static int __insert_pg_mapping(struct ceph_pg_mapping *new,
	return 0;
	return 0;
}
}


static struct ceph_pg_mapping *__lookup_pg_mapping(struct rb_root *root,
						   struct ceph_pg pgid)
{
	struct rb_node *n = root->rb_node;
	struct ceph_pg_mapping *pg;
	int c;

	while (n) {
		pg = rb_entry(n, struct ceph_pg_mapping, node);
		c = pgid_cmp(pgid, pg->pgid);
		if (c < 0)
			n = n->rb_left;
		else if (c > 0)
			n = n->rb_right;
		else
			return pg;
	}
	return NULL;
}

/*
/*
 * decode a full map.
 * decode a full map.
 */
 */
@@ -870,27 +896,18 @@ int ceph_calc_object_layout(struct ceph_object_layout *ol,
static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid,
			int *osds, int *num)
			int *osds, int *num)
{
{
	struct rb_node *n = osdmap->pg_temp.rb_node;
	struct ceph_pg_mapping *pg;
	struct ceph_pg_mapping *pg;
	struct ceph_pg_pool_info *pool;
	struct ceph_pg_pool_info *pool;
	int ruleno;
	int ruleno;
	unsigned poolid, ps, pps;
	unsigned poolid, ps, pps;
	int preferred;
	int preferred;
	int c;


	/* pg_temp? */
	/* pg_temp? */
	while (n) {
	pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
		pg = rb_entry(n, struct ceph_pg_mapping, node);
	if (pg) {
		c = pgid_cmp(pgid, pg->pgid);
		if (c < 0)
			n = n->rb_left;
		else if (c > 0)
			n = n->rb_right;
		else {
		*num = pg->len;
		*num = pg->len;
		return pg->osds;
		return pg->osds;
	}
	}
	}


	/* crush */
	/* crush */
	poolid = le32_to_cpu(pgid.pool);
	poolid = le32_to_cpu(pgid.pool);