]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
ceph: fix crush CHOOSE_LEAF when type is already a leaf
authorSage Weil <sage@newdream.net>
Thu, 24 Jun 2010 19:58:14 +0000 (12:58 -0700)
committerSage Weil <sage@newdream.net>
Thu, 24 Jun 2010 19:58:14 +0000 (12:58 -0700)
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>
fs/ceph/crush/mapper.c

index 804e6d53b77c3df2817a792109238aeafb7f1681..374266bddd9ca92883dec6f0368c3198c6c0032a 100644 (file)
@@ -238,7 +238,7 @@ static int bucket_straw_choose(struct crush_bucket_straw *bucket,
 
 static int crush_bucket_choose(struct crush_bucket *in, int x, int r)
 {
-       dprintk("choose %d x=%d r=%d\n", in->id, x, r);
+       dprintk(" crush_bucket_choose %d x=%d r=%d\n", in->id, x, r);
        switch (in->alg) {
        case CRUSH_BUCKET_UNIFORM:
                return bucket_uniform_choose((struct crush_bucket_uniform *)in,
@@ -305,7 +305,9 @@ static int crush_choose(struct crush_map *map,
        int itemtype;
        int collide, reject;
        const int orig_tries = 5; /* attempts before we fall back to search */
-       dprintk("choose bucket %d x %d outpos %d\n", bucket->id, x, outpos);
+
+       dprintk("CHOOSE%s bucket %d x %d outpos %d numrep %d\n", recurse_to_leaf ? "_LEAF" : "",
+               bucket->id, x, outpos, numrep);
 
        for (rep = outpos; rep < numrep; rep++) {
                /* keep trying until we get a non-out, non-colliding item */
@@ -378,15 +380,25 @@ static int crush_choose(struct crush_map *map,
                                        }
                                }
 
-                               if (recurse_to_leaf &&
-                                   item < 0 &&
-                                   crush_choose(map, map->buckets[-1-item],
-                                                weight,
-                                                x, outpos+1, 0,
-                                                out2, outpos,
-                                                firstn, 0, NULL) <= outpos) {
-                                       reject = 1;
-                               } else {
+                               reject = 0;
+                               if (recurse_to_leaf) {
+                                       if (item < 0) {
+                                               if (crush_choose(map,
+                                                        map->buckets[-1-item],
+                                                        weight,
+                                                        x, outpos+1, 0,
+                                                        out2, outpos,
+                                                        firstn, 0,
+                                                        NULL) <= outpos)
+                                                       /* didn't get leaf */
+                                                       reject = 1;
+                                       } else {
+                                               /* we already have a leaf! */
+                                               out2[outpos] = item;
+                                       }
+                               }
+
+                               if (!reject) {
                                        /* out? */
                                        if (itemtype == 0)
                                                reject = is_out(map, weight,
@@ -425,12 +437,12 @@ reject:
                        continue;
                }
 
-               dprintk("choose got %d\n", item);
+               dprintk("CHOOSE got %d\n", item);
                out[outpos] = item;
                outpos++;
        }
 
-       dprintk("choose returns %d\n", outpos);
+       dprintk("CHOOSE returns %d\n", outpos);
        return outpos;
 }