diff options
author | Sage Weil <sage@newdream.net> | 2010-06-24 15:58:14 -0400 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2010-06-24 15:58:14 -0400 |
commit | a1a31e734241aefcb2b30fb0cc0376977b6d2ba8 (patch) | |
tree | 3247b61cf5f1cc3efb212e0362493f98f326e4ff /fs/ceph/crush | |
parent | 55bda7aacd13f5fdfeaafc16934953171405c692 (diff) |
ceph: fix crush CHOOSE_LEAF when type is already a leaf
We may not recurse for CHOOSE_LEAF if we start with a leaf node. When
that happens, the out2 vector needs to be filled in with the result.
Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph/crush')
-rw-r--r-- | fs/ceph/crush/mapper.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/fs/ceph/crush/mapper.c b/fs/ceph/crush/mapper.c index 804e6d53b77..374266bddd9 100644 --- a/fs/ceph/crush/mapper.c +++ b/fs/ceph/crush/mapper.c | |||
@@ -238,7 +238,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket, | |||
238 | 238 | ||
239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) | 239 | static int crush_bucket_choose(struct crush_bucket *in, int x, int r) |
240 | { | 240 | { |
241 | dprintk("choose %d x=%d r=%d\n", in->id, x, r); | 241 | dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r); |
242 | switch (in->alg) { | 242 | switch (in->alg) { |
243 | case CRUSH_BUCKET_UNIFORM: | 243 | case CRUSH_BUCKET_UNIFORM: |
244 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, | 244 | return bucket_uniform_choose((struct crush_bucket_uniform *)in, |
@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map, | |||
305 | int itemtype; | 305 | int itemtype; |
306 | int collide, reject; | 306 | int collide, reject; |
307 | const int orig_tries = 5; /* attempts before we fall back to search */ | 307 | const int orig_tries = 5; /* attempts before we fall back to search */ |
308 | dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos); | 308 | |
309 | dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d\n", recurse_to_leaf ? "_LEAF" : "", | ||
310 | bucket->id, x, outpos, numrep); | ||
309 | 311 | ||
310 | for (rep = outpos; rep < numrep; rep++) { | 312 | for (rep = outpos; rep < numrep; rep++) { |
311 | /* keep trying until we get a non-out, non-colliding item */ | 313 | /* keep trying until we get a non-out, non-colliding item */ |
@@ -378,15 +380,25 @@ static int crush_choose(struct crush_map *map, | |||
378 | } | 380 | } |
379 | } | 381 | } |
380 | 382 | ||
381 | if (recurse_to_leaf && | 383 | reject = 0; |
382 | item < 0 && | 384 | if (recurse_to_leaf) { |
383 | crush_choose(map, map->buckets[-1-item], | 385 | if (item < 0) { |
384 | weight, | 386 | if (crush_choose(map, |
385 | x, outpos+1, 0, | 387 | map->buckets[-1-item], |
386 | out2, outpos, | 388 | weight, |
387 | firstn, 0, NULL) <= outpos) { | 389 | x, outpos+1, 0, |
388 | reject = 1; | 390 | out2, outpos, |
389 | } else { | 391 | firstn, 0, |
392 | NULL) <= outpos) | ||
393 | /* didn't get leaf */ | ||
394 | reject = 1; | ||
395 | } else { | ||
396 | /* we already have a leaf! */ | ||
397 | out2[outpos] = item; | ||
398 | } | ||
399 | } | ||
400 | |||
401 | if (!reject) { | ||
390 | /* out? */ | 402 | /* out? */ |
391 | if (itemtype == 0) | 403 | if (itemtype == 0) |
392 | reject = is_out(map, weight, | 404 | reject = is_out(map, weight, |
@@ -425,12 +437,12 @@ reject: | |||
425 | continue; | 437 | continue; |
426 | } | 438 | } |
427 | 439 | ||
428 | dprintk("choose got %d\n", item); | 440 | dprintk("CHOOSE got %d\n", item); |
429 | out[outpos] = item; | 441 | out[outpos] = item; |
430 | outpos++; | 442 | outpos++; |
431 | } | 443 | } |
432 | 444 | ||
433 | dprintk("choose returns %d\n", outpos); | 445 | dprintk("CHOOSE returns %d\n", outpos); |
434 | return outpos; | 446 | return outpos; |
435 | } | 447 | } |
436 | 448 | ||