aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2015-04-14 09:04:23 -0400
committerIlya Dryomov <idryomov@gmail.com>2015-04-22 11:33:42 -0400
commit45002267e8d2699bf9b022315bee3dd13b044843 (patch)
tree9cbbc74ef620e4cc6b8f34cee1f1539fb11c0e93 /net/ceph
parent9be6df215a1baa57ccad0c388daeb2ad8f8d99ee (diff)
crush: ensuring at most num-rep osds are selected
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>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/crush/mapper.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/net/ceph/crush/mapper.c b/net/ceph/crush/mapper.c
index 5549fb609358..91c41fe83113 100644
--- a/net/ceph/crush/mapper.c
+++ b/net/ceph/crush/mapper.c
@@ -289,6 +289,7 @@ static int is_out(const struct crush_map *map,
289 * @type: the type of item to choose 289 * @type: the type of item to choose
290 * @out: pointer to output vector 290 * @out: pointer to output vector
291 * @outpos: our position in that vector 291 * @outpos: our position in that vector
292 * @out_size: size of the out vector
292 * @tries: number of attempts to make 293 * @tries: number of attempts to make
293 * @recurse_tries: number of attempts to have recursive chooseleaf make 294 * @recurse_tries: number of attempts to have recursive chooseleaf make
294 * @local_retries: localized retries 295 * @local_retries: localized retries
@@ -303,6 +304,7 @@ static int crush_choose_firstn(const struct crush_map *map,
303 const __u32 *weight, int weight_max, 304 const __u32 *weight, int weight_max,
304 int x, int numrep, int type, 305 int x, int numrep, int type,
305 int *out, int outpos, 306 int *out, int outpos,
307 int out_size,
306 unsigned int tries, 308 unsigned int tries,
307 unsigned int recurse_tries, 309 unsigned int recurse_tries,
308 unsigned int local_retries, 310 unsigned int local_retries,
@@ -321,6 +323,7 @@ static int crush_choose_firstn(const struct crush_map *map,
321 int item = 0; 323 int item = 0;
322 int itemtype; 324 int itemtype;
323 int collide, reject; 325 int collide, reject;
326 int count = out_size;
324 327
325 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", 328 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",
326 recurse_to_leaf ? "_LEAF" : "", 329 recurse_to_leaf ? "_LEAF" : "",
@@ -328,7 +331,7 @@ static int crush_choose_firstn(const struct crush_map *map,
328 tries, recurse_tries, local_retries, local_fallback_retries, 331 tries, recurse_tries, local_retries, local_fallback_retries,
329 parent_r); 332 parent_r);
330 333
331 for (rep = outpos; rep < numrep; rep++) { 334 for (rep = outpos; rep < numrep && count > 0 ; rep++) {
332 /* keep trying until we get a non-out, non-colliding item */ 335 /* keep trying until we get a non-out, non-colliding item */
333 ftotal = 0; 336 ftotal = 0;
334 skip_rep = 0; 337 skip_rep = 0;
@@ -402,7 +405,7 @@ static int crush_choose_firstn(const struct crush_map *map,
402 map->buckets[-1-item], 405 map->buckets[-1-item],
403 weight, weight_max, 406 weight, weight_max,
404 x, outpos+1, 0, 407 x, outpos+1, 0,
405 out2, outpos, 408 out2, outpos, count,
406 recurse_tries, 0, 409 recurse_tries, 0,
407 local_retries, 410 local_retries,
408 local_fallback_retries, 411 local_fallback_retries,
@@ -462,6 +465,7 @@ reject:
462 dprintk("CHOOSE got %d\n", item); 465 dprintk("CHOOSE got %d\n", item);
463 out[outpos] = item; 466 out[outpos] = item;
464 outpos++; 467 outpos++;
468 count--;
465 } 469 }
466 470
467 dprintk("CHOOSE returns %d\n", outpos); 471 dprintk("CHOOSE returns %d\n", outpos);
@@ -653,6 +657,7 @@ int crush_do_rule(const struct crush_map *map,
653 __u32 step; 657 __u32 step;
654 int i, j; 658 int i, j;
655 int numrep; 659 int numrep;
660 int out_size;
656 /* 661 /*
657 * the original choose_total_tries value was off by one (it 662 * the original choose_total_tries value was off by one (it
658 * counted "retries" and not "tries"). add one. 663 * counted "retries" and not "tries"). add one.
@@ -760,6 +765,7 @@ int crush_do_rule(const struct crush_map *map,
760 x, numrep, 765 x, numrep,
761 curstep->arg2, 766 curstep->arg2,
762 o+osize, j, 767 o+osize, j,
768 result_max-osize,
763 choose_tries, 769 choose_tries,
764 recurse_tries, 770 recurse_tries,
765 choose_local_retries, 771 choose_local_retries,
@@ -769,11 +775,13 @@ int crush_do_rule(const struct crush_map *map,
769 c+osize, 775 c+osize,
770 0); 776 0);
771 } else { 777 } else {
778 out_size = ((numrep < (result_max-osize)) ?
779 numrep : (result_max-osize));
772 crush_choose_indep( 780 crush_choose_indep(
773 map, 781 map,
774 map->buckets[-1-w[i]], 782 map->buckets[-1-w[i]],
775 weight, weight_max, 783 weight, weight_max,
776 x, numrep, numrep, 784 x, out_size, numrep,
777 curstep->arg2, 785 curstep->arg2,
778 o+osize, j, 786 o+osize, j,
779 choose_tries, 787 choose_tries,
@@ -782,7 +790,7 @@ int crush_do_rule(const struct crush_map *map,
782 recurse_to_leaf, 790 recurse_to_leaf,
783 c+osize, 791 c+osize,
784 0); 792 0);
785 osize += numrep; 793 osize += out_size;
786 } 794 }
787 } 795 }
788 796