]> Git Repo - linux.git/commitdiff
bcachefs: deallocate_extra_replicas()
authorKent Overstreet <[email protected]>
Mon, 20 Nov 2023 23:23:26 +0000 (18:23 -0500)
committerKent Overstreet <[email protected]>
Fri, 24 Nov 2023 08:03:47 +0000 (03:03 -0500)
When allocating from devices with different durability, we might end up
with more replicas than required; this changes
bch2_alloc_sectors_start() to check for this, and drop replicas that
aren't needed to hit the number of replicas requested.

Signed-off-by: Kent Overstreet <[email protected]>
fs/bcachefs/alloc_foreground.c

index 5042858719c087969d9eacc55dc337a8123a269b..1ba0eeb7552a2795d033d2603cccce611c8f3381 100644 (file)
@@ -1297,6 +1297,30 @@ out:
        return wp;
 }
 
+static noinline void
+deallocate_extra_replicas(struct bch_fs *c,
+                         struct open_buckets *ptrs,
+                         struct open_buckets *ptrs_no_use,
+                         unsigned extra_replicas)
+{
+       struct open_buckets ptrs2 = { 0 };
+       struct open_bucket *ob;
+       unsigned i;
+
+       open_bucket_for_each(c, ptrs, ob, i) {
+               unsigned d = bch_dev_bkey_exists(c, ob->dev)->mi.durability;
+
+               if (d && d <= extra_replicas) {
+                       extra_replicas -= d;
+                       ob_push(c, ptrs_no_use, ob);
+               } else {
+                       ob_push(c, &ptrs2, ob);
+               }
+       }
+
+       *ptrs = ptrs2;
+}
+
 /*
  * Get us an open_bucket we can allocate from, return with it locked:
  */
@@ -1385,6 +1409,9 @@ alloc_done:
        if (ret)
                goto err;
 
+       if (nr_effective > nr_replicas)
+               deallocate_extra_replicas(c, &ptrs, &wp->ptrs, nr_effective - nr_replicas);
+
        /* Free buckets we didn't use: */
        open_bucket_for_each(c, &wp->ptrs, ob, i)
                open_bucket_free_unused(c, ob);
This page took 0.056801 seconds and 4 git commands to generate.