diff --git a/include/linux/crush/crush.h b/include/linux/crush/crush.h index 09561a04c127..83543c504b5a 100644 --- a/include/linux/crush/crush.h +++ b/include/linux/crush/crush.h @@ -21,7 +21,6 @@ #define CRUSH_MAX_DEPTH 10 /* max crush hierarchy depth */ -#define CRUSH_MAX_SET 10 /* max size of a mapping result */ /* diff --git a/include/linux/crush/mapper.h b/include/linux/crush/mapper.h index 69310b031875..eab367446eea 100644 --- a/include/linux/crush/mapper.h +++ b/include/linux/crush/mapper.h @@ -14,6 +14,7 @@ extern int crush_find_rule(const struct crush_map *map, int ruleset, int type, i extern int crush_do_rule(const struct crush_map *map, int ruleno, int x, int *result, int result_max, - const __u32 *weights, int weight_max); + const __u32 *weights, int weight_max, + int *scratch); #endif diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c index 82cab7d3e89d..dcf48bc504ea 100644 --- a/net/ceph/crush/mapper.c +++ b/net/ceph/crush/mapper.c @@ -478,15 +478,17 @@ reject: * @result_max: maximum result size * @weight: weight vector (for map leaves) * @weight_max: size of weight vector + * @scratch: scratch vector for private use; must be >= 3 * result_max */ int crush_do_rule(const struct crush_map *map, int ruleno, int x, int *result, int result_max, - const __u32 *weight, int weight_max) + const __u32 *weight, int weight_max, + int *scratch) { int result_len; - int a[CRUSH_MAX_SET]; - int b[CRUSH_MAX_SET]; - int c[CRUSH_MAX_SET]; + int *a = scratch; + int *b = scratch + result_max; + int *c = scratch + result_max*2; int recurse_to_leaf; int *w; int wsize = 0; diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 6477a68ddecb..8b1a6b48bb5d 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c @@ -1110,6 +1110,16 @@ int ceph_calc_ceph_pg(struct ceph_pg *pg, const char *oid, } EXPORT_SYMBOL(ceph_calc_ceph_pg); +static int crush_do_rule_ary(const struct crush_map *map, int ruleno, int x, + int *result, int result_max, + const __u32 *weight, int weight_max) +{ + int scratch[result_max * 3]; + + return crush_do_rule(map, ruleno, x, result, result_max, + weight, weight_max, scratch); +} + /* * Calculate raw osd vector for the given pgid. Return pointer to osd * array, or NULL on failure. @@ -1163,9 +1173,9 @@ static int *calc_pg_raw(struct ceph_osdmap *osdmap, struct ceph_pg pgid, pool->pgp_num_mask) + (unsigned)pgid.pool; } - r = crush_do_rule(osdmap->crush, ruleno, pps, osds, - min_t(int, pool->size, *num), - osdmap->osd_weight, osdmap->max_osd); + r = crush_do_rule_ary(osdmap->crush, ruleno, pps, + osds, min_t(int, pool->size, *num), + osdmap->osd_weight, osdmap->max_osd); if (r < 0) { pr_err("error %d from crush rule: pool %lld ruleset %d type %d" " size %d\n", r, pgid.pool, pool->crush_ruleset,