Skip to content
osdmap.c 25.1 KiB
Newer Older
	pg = __lookup_pg_mapping(&osdmap->pg_temp, pgid);
	if (pg) {
		*num = pg->len;
		return pg->osds;
Sage Weil's avatar
Sage Weil committed
	}

	/* crush */
	poolid = le32_to_cpu(pgid.pool);
	ps = le16_to_cpu(pgid.ps);
	preferred = (s16)le16_to_cpu(pgid.preferred);

	/* don't forcefeed bad device ids to crush */
	if (preferred >= osdmap->max_osd ||
	    preferred >= osdmap->crush->max_devices)
		preferred = -1;

	pool = __lookup_pg_pool(&osdmap->pg_pools, poolid);
	if (!pool)
Sage Weil's avatar
Sage Weil committed
		return NULL;
	ruleno = crush_find_rule(osdmap->crush, pool->v.crush_ruleset,
				 pool->v.type, pool->v.size);
	if (ruleno < 0) {
		pr_err("no crush rule pool %d type %d size %d\n",
		       poolid, pool->v.type, pool->v.size);
Sage Weil's avatar
Sage Weil committed
		return NULL;
	}

	if (preferred >= 0)
		pps = ceph_stable_mod(ps,
Sage Weil's avatar
Sage Weil committed
				      le32_to_cpu(pool->v.lpgp_num),
				      pool->lpgp_num_mask);
	else
		pps = ceph_stable_mod(ps,
Sage Weil's avatar
Sage Weil committed
				      le32_to_cpu(pool->v.pgp_num),
				      pool->pgp_num_mask);
	pps += poolid;
Sage Weil's avatar
Sage Weil committed
	*num = crush_do_rule(osdmap->crush, ruleno, pps, osds,
			     min_t(int, pool->v.size, *num),
			     preferred, osdmap->osd_weight);
Sage Weil's avatar
Sage Weil committed
	return osds;
}

/*
 * Return primary osd for given pgid, or -1 if none.
 */
int ceph_calc_pg_primary(struct ceph_osdmap *osdmap, struct ceph_pg pgid)
Sage Weil's avatar
Sage Weil committed
{
	int rawosds[10], *osds;
	int i, num = ARRAY_SIZE(rawosds);

	osds = calc_pg_raw(osdmap, pgid, rawosds, &num);
	if (!osds)
		return -1;

	/* primary is first up osd */
	for (i = 0; i < num; i++)
		if (ceph_osd_is_up(osdmap, osds[i])) {
			return osds[i];
			break;
		}
	return -1;
}