|
@@ -287,6 +287,7 @@ static int is_out(const struct crush_map *map, const __u32 *weight, int item, in
|
|
|
* @outpos: our position in that vector
|
|
|
* @firstn: true if choosing "first n" items, false if choosing "indep"
|
|
|
* @recurse_to_leaf: true if we want one device under each item of given type
|
|
|
+ * @descend_once: true if we should only try one descent before giving up
|
|
|
* @out2: second output vector for leaf items (if @recurse_to_leaf)
|
|
|
*/
|
|
|
static int crush_choose(const struct crush_map *map,
|
|
@@ -295,7 +296,7 @@ static int crush_choose(const struct crush_map *map,
|
|
|
int x, int numrep, int type,
|
|
|
int *out, int outpos,
|
|
|
int firstn, int recurse_to_leaf,
|
|
|
- int *out2)
|
|
|
+ int descend_once, int *out2)
|
|
|
{
|
|
|
int rep;
|
|
|
unsigned int ftotal, flocal;
|
|
@@ -399,6 +400,7 @@ static int crush_choose(const struct crush_map *map,
|
|
|
x, outpos+1, 0,
|
|
|
out2, outpos,
|
|
|
firstn, 0,
|
|
|
+ map->chooseleaf_descend_once,
|
|
|
NULL) <= outpos)
|
|
|
/* didn't get leaf */
|
|
|
reject = 1;
|
|
@@ -422,7 +424,10 @@ reject:
|
|
|
ftotal++;
|
|
|
flocal++;
|
|
|
|
|
|
- if (collide && flocal <= map->choose_local_tries)
|
|
|
+ if (reject && descend_once)
|
|
|
+ /* let outer call try again */
|
|
|
+ skip_rep = 1;
|
|
|
+ else if (collide && flocal <= map->choose_local_tries)
|
|
|
/* retry locally a few times */
|
|
|
retry_bucket = 1;
|
|
|
else if (map->choose_local_fallback_tries > 0 &&
|
|
@@ -485,6 +490,7 @@ int crush_do_rule(const struct crush_map *map,
|
|
|
int i, j;
|
|
|
int numrep;
|
|
|
int firstn;
|
|
|
+ const int descend_once = 0;
|
|
|
|
|
|
if ((__u32)ruleno >= map->max_rules) {
|
|
|
dprintk(" bad ruleno %d\n", ruleno);
|
|
@@ -544,7 +550,8 @@ int crush_do_rule(const struct crush_map *map,
|
|
|
curstep->arg2,
|
|
|
o+osize, j,
|
|
|
firstn,
|
|
|
- recurse_to_leaf, c+osize);
|
|
|
+ recurse_to_leaf,
|
|
|
+ descend_once, c+osize);
|
|
|
}
|
|
|
|
|
|
if (recurse_to_leaf)
|