summaryrefslogtreecommitdiff
path: root/libbcachefs/buckets.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/buckets.c')
-rw-r--r--libbcachefs/buckets.c132
1 files changed, 70 insertions, 62 deletions
diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c
index 4d55ef51..5ff4e911 100644
--- a/libbcachefs/buckets.c
+++ b/libbcachefs/buckets.c
@@ -949,38 +949,34 @@ static int bch2_mark_stripe_ptr(struct btree_trans *trans,
bool gc = flags & BTREE_TRIGGER_GC;
struct bch_fs *c = trans->c;
struct bch_replicas_padded r;
- struct stripe *m;
- unsigned i, blocks_nonempty = 0;
- m = genradix_ptr(&c->stripes[gc], p.idx);
+ if (!gc) {
+ BUG();
+ } else {
+ struct gc_stripe *m = genradix_ptr_alloc(&c->gc_stripes, p.idx, GFP_KERNEL);
- spin_lock(&c->ec_stripes_heap_lock);
+ if (!m)
+ return -ENOMEM;
- if (!m || !m->alive) {
- spin_unlock(&c->ec_stripes_heap_lock);
- bch_err_ratelimited(c, "pointer to nonexistent stripe %llu",
- (u64) p.idx);
- bch2_inconsistent_error(c);
- return -EIO;
- }
+ spin_lock(&c->ec_stripes_heap_lock);
- m->block_sectors[p.block] += sectors;
+ if (!m || !m->alive) {
+ spin_unlock(&c->ec_stripes_heap_lock);
+ bch_err_ratelimited(c, "pointer to nonexistent stripe %llu",
+ (u64) p.idx);
+ bch2_inconsistent_error(c);
+ return -EIO;
+ }
- r = m->r;
+ m->block_sectors[p.block] += sectors;
- for (i = 0; i < m->nr_blocks; i++)
- blocks_nonempty += m->block_sectors[i] != 0;
+ r = m->r;
+ spin_unlock(&c->ec_stripes_heap_lock);
- if (m->blocks_nonempty != blocks_nonempty) {
- m->blocks_nonempty = blocks_nonempty;
- if (!gc)
- bch2_stripes_heap_update(c, m, p.idx);
+ r.e.data_type = data_type;
+ update_replicas(c, k, &r.e, sectors, trans->journal_res.seq, gc);
}
- spin_unlock(&c->ec_stripes_heap_lock);
-
- r.e.data_type = data_type;
- update_replicas(c, k, &r.e, sectors, trans->journal_res.seq, gc);
return 0;
}
@@ -1077,67 +1073,70 @@ static int bch2_mark_stripe(struct btree_trans *trans,
? bkey_s_c_to_stripe(old).v : NULL;
const struct bch_stripe *new_s = new.k->type == KEY_TYPE_stripe
? bkey_s_c_to_stripe(new).v : NULL;
- struct stripe *m = genradix_ptr(&c->stripes[gc], idx);
unsigned i;
int ret;
BUG_ON(gc && old_s);
- if (!m || (old_s && !m->alive)) {
- char buf1[200], buf2[200];
-
- bch2_bkey_val_to_text(&PBUF(buf1), c, old);
- bch2_bkey_val_to_text(&PBUF(buf2), c, new);
- bch_err_ratelimited(c, "error marking nonexistent stripe %zu while marking\n"
- "old %s\n"
- "new %s", idx, buf1, buf2);
- bch2_inconsistent_error(c);
- return -1;
- }
+ if (!gc) {
+ struct stripe *m = genradix_ptr(&c->stripes, idx);
- if (!new_s) {
- spin_lock(&c->ec_stripes_heap_lock);
- bch2_stripes_heap_del(c, m, idx);
- spin_unlock(&c->ec_stripes_heap_lock);
+ if (!m || (old_s && !m->alive)) {
+ char buf1[200], buf2[200];
- memset(m, 0, sizeof(*m));
- } else {
- m->alive = true;
- m->sectors = le16_to_cpu(new_s->sectors);
- m->algorithm = new_s->algorithm;
- m->nr_blocks = new_s->nr_blocks;
- m->nr_redundant = new_s->nr_redundant;
- m->blocks_nonempty = 0;
+ bch2_bkey_val_to_text(&PBUF(buf1), c, old);
+ bch2_bkey_val_to_text(&PBUF(buf2), c, new);
+ bch_err_ratelimited(c, "error marking nonexistent stripe %zu while marking\n"
+ "old %s\n"
+ "new %s", idx, buf1, buf2);
+ bch2_inconsistent_error(c);
+ return -1;
+ }
- for (i = 0; i < new_s->nr_blocks; i++) {
- m->block_sectors[i] =
- stripe_blockcount_get(new_s, i);
- m->blocks_nonempty += !!m->block_sectors[i];
+ if (!new_s) {
+ spin_lock(&c->ec_stripes_heap_lock);
+ bch2_stripes_heap_del(c, m, idx);
+ spin_unlock(&c->ec_stripes_heap_lock);
- m->ptrs[i] = new_s->ptrs[i];
- }
+ memset(m, 0, sizeof(*m));
+ } else {
+ m->alive = true;
+ m->sectors = le16_to_cpu(new_s->sectors);
+ m->algorithm = new_s->algorithm;
+ m->nr_blocks = new_s->nr_blocks;
+ m->nr_redundant = new_s->nr_redundant;
+ m->blocks_nonempty = 0;
- bch2_bkey_to_replicas(&m->r.e, new);
+ for (i = 0; i < new_s->nr_blocks; i++)
+ m->blocks_nonempty += !!stripe_blockcount_get(new_s, i);
- if (!gc) {
spin_lock(&c->ec_stripes_heap_lock);
bch2_stripes_heap_update(c, m, idx);
spin_unlock(&c->ec_stripes_heap_lock);
}
- }
+ } else {
+ struct gc_stripe *m = genradix_ptr(&c->gc_stripes, idx);
- if (gc) {
/*
* This will be wrong when we bring back runtime gc: we should
* be unmarking the old key and then marking the new key
*/
+ m->alive = true;
+ m->sectors = le16_to_cpu(new_s->sectors);
+ m->algorithm = new_s->algorithm;
+ m->nr_blocks = new_s->nr_blocks;
+ m->nr_redundant = new_s->nr_redundant;
+
+ for (i = 0; i < new_s->nr_blocks; i++)
+ m->ptrs[i] = new_s->ptrs[i];
+
+ bch2_bkey_to_replicas(&m->r.e, new);
/*
* gc recalculates this field from stripe ptr
* references:
*/
memset(m->block_sectors, 0, sizeof(m->block_sectors));
- m->blocks_nonempty = 0;
for (i = 0; i < new_s->nr_blocks; i++) {
ret = mark_stripe_bucket(trans, new, i, journal_seq, flags);
@@ -1544,7 +1543,9 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
goto out;
bch2_alloc_pack(c, a, u);
- bch2_trans_update(trans, &iter, &a->k, 0);
+ ret = bch2_trans_update(trans, &iter, &a->k, 0);
+ if (ret)
+ goto out;
out:
bch2_trans_iter_exit(trans, &iter);
return ret;
@@ -1595,7 +1596,10 @@ static int bch2_trans_mark_stripe_ptr(struct btree_trans *trans,
stripe_blockcount_set(&s->v, p.ec.block,
stripe_blockcount_get(&s->v, p.ec.block) +
sectors);
- bch2_trans_update(trans, &iter, &s->k_i, 0);
+
+ ret = bch2_trans_update(trans, &iter, &s->k_i, 0);
+ if (ret)
+ goto err;
bch2_bkey_to_replicas(&r.e, bkey_i_to_s_c(&s->k_i));
r.e.data_type = data_type;
@@ -1733,7 +1737,9 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans,
u.data_type = !deleting ? data_type : 0;
bch2_alloc_pack(c, a, u);
- bch2_trans_update(trans, &iter, &a->k, 0);
+ ret = bch2_trans_update(trans, &iter, &a->k, 0);
+ if (ret)
+ goto err;
err:
bch2_trans_iter_exit(trans, &iter);
return ret;
@@ -2012,7 +2018,9 @@ static int __bch2_trans_mark_metadata_bucket(struct btree_trans *trans,
u.dirty_sectors = sectors;
bch2_alloc_pack(c, a, u);
- bch2_trans_update(trans, &iter, &a->k, 0);
+ ret = bch2_trans_update(trans, &iter, &a->k, 0);
+ if (ret)
+ goto out;
out:
bch2_trans_iter_exit(trans, &iter);
return ret;