Commit 0af8a06a authored by Kent Overstreet's avatar Kent Overstreet

bcachefs: deallocate_extra_replicas()

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: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 8a443d3e
...@@ -1297,6 +1297,30 @@ static struct write_point *writepoint_find(struct btree_trans *trans, ...@@ -1297,6 +1297,30 @@ static struct write_point *writepoint_find(struct btree_trans *trans,
return wp; 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: * Get us an open_bucket we can allocate from, return with it locked:
*/ */
...@@ -1385,6 +1409,9 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans, ...@@ -1385,6 +1409,9 @@ int bch2_alloc_sectors_start_trans(struct btree_trans *trans,
if (ret) if (ret)
goto err; goto err;
if (nr_effective > nr_replicas)
deallocate_extra_replicas(c, &ptrs, &wp->ptrs, nr_effective - nr_replicas);
/* Free buckets we didn't use: */ /* Free buckets we didn't use: */
open_bucket_for_each(c, &wp->ptrs, ob, i) open_bucket_for_each(c, &wp->ptrs, ob, i)
open_bucket_free_unused(c, ob); open_bucket_free_unused(c, ob);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment