Skip to content

Commit

Permalink
crush: ensuring at most num-rep osds are selected
Browse files Browse the repository at this point in the history
Crush temporary buffers are allocated as per replica size configured
by the user.  When there are more final osds (to be selected as per
rule) than the replicas, buffer overlaps and it causes crash.  Now, it
ensures that at most num-rep osds are selected even if more number of
osds are allowed by the rule.

Reflects ceph.git commits 6b4d1aa99718e3b367496326c1e64551330fabc0,
                          234b066ba04976783d15ff2abc3e81b6cc06fb10.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
  • Loading branch information
Ilya Dryomov committed Apr 22, 2015
1 parent 9be6df2 commit 4500226
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions net/ceph/crush/mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ static int is_out(const struct crush_map *map,
* @type: the type of item to choose
* @out: pointer to output vector
* @outpos: our position in that vector
* @out_size: size of the out vector
* @tries: number of attempts to make
* @recurse_tries: number of attempts to have recursive chooseleaf make
* @local_retries: localized retries
Expand All @@ -303,6 +304,7 @@ static int crush_choose_firstn(const struct crush_map *map,
const __u32 *weight, int weight_max,
int x, int numrep, int type,
int *out, int outpos,
int out_size,
unsigned int tries,
unsigned int recurse_tries,
unsigned int local_retries,
Expand All @@ -321,14 +323,15 @@ static int crush_choose_firstn(const struct crush_map *map,
int item = 0;
int itemtype;
int collide, reject;
int count = out_size;

dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d tries %d recurse_tries %d local_retries %d local_fallback_retries %d parent_r %d\n",
recurse_to_leaf ? "_LEAF" : "",
bucket->id, x, outpos, numrep,
tries, recurse_tries, local_retries, local_fallback_retries,
parent_r);

for (rep = outpos; rep < numrep; rep++) {
for (rep = outpos; rep < numrep && count > 0 ; rep++) {
/* keep trying until we get a non-out, non-colliding item */
ftotal = 0;
skip_rep = 0;
Expand Down Expand Up @@ -402,7 +405,7 @@ static int crush_choose_firstn(const struct crush_map *map,
map->buckets[-1-item],
weight, weight_max,
x, outpos+1, 0,
out2, outpos,
out2, outpos, count,
recurse_tries, 0,
local_retries,
local_fallback_retries,
Expand Down Expand Up @@ -462,6 +465,7 @@ static int crush_choose_firstn(const struct crush_map *map,
dprintk("CHOOSE got %d\n", item);
out[outpos] = item;
outpos++;
count--;
}

dprintk("CHOOSE returns %d\n", outpos);
Expand Down Expand Up @@ -653,6 +657,7 @@ int crush_do_rule(const struct crush_map *map,
__u32 step;
int i, j;
int numrep;
int out_size;
/*
* the original choose_total_tries value was off by one (it
* counted "retries" and not "tries"). add one.
Expand Down Expand Up @@ -760,6 +765,7 @@ int crush_do_rule(const struct crush_map *map,
x, numrep,
curstep->arg2,
o+osize, j,
result_max-osize,
choose_tries,
recurse_tries,
choose_local_retries,
Expand All @@ -769,11 +775,13 @@ int crush_do_rule(const struct crush_map *map,
c+osize,
0);
} else {
out_size = ((numrep < (result_max-osize)) ?
numrep : (result_max-osize));
crush_choose_indep(
map,
map->buckets[-1-w[i]],
weight, weight_max,
x, numrep, numrep,
x, out_size, numrep,
curstep->arg2,
o+osize, j,
choose_tries,
Expand All @@ -782,7 +790,7 @@ int crush_do_rule(const struct crush_map *map,
recurse_to_leaf,
c+osize,
0);
osize += numrep;
osize += out_size;
}
}

Expand Down

0 comments on commit 4500226

Please sign in to comment.