Skip to content

Commit 4d6128d

Browse files
author
Kent Overstreet
committed
bcachefs: Guard against insufficient devices to create stripes
We can't create stripes if we don't have enough devices - this manifested as an integer underflow bug later. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
1 parent 03cc1e6 commit 4d6128d

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

fs/bcachefs/ec.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,6 +1373,15 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned target,
13731373
h->nr_active_devs++;
13741374

13751375
rcu_read_unlock();
1376+
1377+
/*
1378+
* If we only have redundancy + 1 devices, we're better off with just
1379+
* replication:
1380+
*/
1381+
if (h->nr_active_devs < h->redundancy + 2)
1382+
bch_err(c, "insufficient devices available to create stripe (have %u, need %u) - mismatched bucket sizes?",
1383+
h->nr_active_devs, h->redundancy + 2);
1384+
13761385
list_add(&h->list, &c->ec_stripe_head_list);
13771386
return h;
13781387
}
@@ -1424,6 +1433,11 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
14241433

14251434
h = ec_new_stripe_head_alloc(c, target, algo, redundancy, watermark);
14261435
found:
1436+
if (!IS_ERR_OR_NULL(h) &&
1437+
h->nr_active_devs < h->redundancy + 2) {
1438+
mutex_unlock(&h->lock);
1439+
h = NULL;
1440+
}
14271441
mutex_unlock(&c->ec_stripe_head_lock);
14281442
return h;
14291443
}
@@ -1681,8 +1695,6 @@ struct ec_stripe_head *bch2_ec_stripe_head_get(struct btree_trans *trans,
16811695
int ret;
16821696

16831697
h = __bch2_ec_stripe_head_get(trans, target, algo, redundancy, watermark);
1684-
if (!h)
1685-
bch_err(c, "no stripe head");
16861698
if (IS_ERR_OR_NULL(h))
16871699
return h;
16881700

0 commit comments

Comments
 (0)