X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fbuckets.c;h=6805f2c0f08a23fde10324fec3f56ef481b18df3;hb=1ee7dc7a55273d34358a0ee525a9e823c999ffe6;hp=ebfbfd97b0a396d21425b9a4ba3470f75cf4ceda;hpb=e160e9b97986d908bce40ab40ee5d930453a3bf1;p=bcachefs-tools-debian diff --git a/libbcachefs/buckets.c b/libbcachefs/buckets.c index ebfbfd9..6805f2c 100644 --- a/libbcachefs/buckets.c +++ b/libbcachefs/buckets.c @@ -486,6 +486,7 @@ static inline void update_cached_sectors_list(struct btree_trans *trans, } int bch2_mark_alloc(struct btree_trans *trans, + enum btree_id btree, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -727,7 +728,7 @@ static int check_bucket_ref(struct btree_trans *trans, if (b_gen != ptr->gen) { ret = 1; - goto err; + goto out; } if (!data_type_is_empty(bucket_data_type) && @@ -775,7 +776,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, const struct bch_stripe *s = bkey_s_c_to_stripe(k).v; unsigned nr_data = s->nr_blocks - s->nr_redundant; bool parity = ptr_idx >= nr_data; - enum bch_data_type data_type = parity ? BCH_DATA_parity : 0; + enum bch_data_type data_type = parity ? BCH_DATA_parity : BCH_DATA_stripe; s64 sectors = parity ? le16_to_cpu(s->sectors) : 0; const struct bch_extent_ptr *ptr = s->ptrs + ptr_idx; struct bch_dev *ca = bch_dev_bkey_exists(c, ptr->dev); @@ -810,8 +811,7 @@ static int mark_stripe_bucket(struct btree_trans *trans, if (ret) goto err; - if (data_type) - g->data_type = data_type; + g->data_type = data_type; g->dirty_sectors += sectors; g->stripe = k.k->p.offset; @@ -850,15 +850,17 @@ static int __mark_pointer(struct btree_trans *trans, } static int bch2_mark_pointer(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c k, struct extent_ptr_decoded p, - s64 sectors, enum bch_data_type data_type, + s64 sectors, unsigned flags) { u64 journal_seq = trans->journal_res.seq; struct bch_fs *c = trans->c; struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev); struct bucket old, new, *g; + enum bch_data_type data_type = bkey_ptr_data_type(btree_id, level, k, p); u8 bucket_data_type; int ret = 0; @@ -907,10 +909,10 @@ static int bch2_mark_stripe_ptr(struct btree_trans *trans, return -ENOMEM; } - spin_lock(&c->ec_stripes_heap_lock); + mutex_lock(&c->ec_stripes_heap_lock); if (!m || !m->alive) { - spin_unlock(&c->ec_stripes_heap_lock); + mutex_unlock(&c->ec_stripes_heap_lock); bch_err_ratelimited(c, "pointer to nonexistent stripe %llu", (u64) p.idx); bch2_inconsistent_error(c); @@ -920,7 +922,7 @@ static int bch2_mark_stripe_ptr(struct btree_trans *trans, m->block_sectors[p.block] += sectors; r = m->r; - spin_unlock(&c->ec_stripes_heap_lock); + mutex_unlock(&c->ec_stripes_heap_lock); r.e.data_type = data_type; update_replicas(c, k, &r.e, sectors, trans->journal_res.seq, true); @@ -929,6 +931,7 @@ static int bch2_mark_stripe_ptr(struct btree_trans *trans, } int bch2_mark_extent(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -961,8 +964,7 @@ int bch2_mark_extent(struct btree_trans *trans, if (flags & BTREE_TRIGGER_OVERWRITE) disk_sectors = -disk_sectors; - ret = bch2_mark_pointer(trans, k, p, disk_sectors, - data_type, flags); + ret = bch2_mark_pointer(trans, btree_id, level, k, p, disk_sectors, flags); if (ret < 0) return ret; @@ -1012,6 +1014,7 @@ int bch2_mark_extent(struct btree_trans *trans, } int bch2_mark_stripe(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -1031,7 +1034,7 @@ int bch2_mark_stripe(struct btree_trans *trans, if (!gc) { struct stripe *m = genradix_ptr(&c->stripes, idx); - if (!m || (old_s && !m->alive)) { + if (!m) { struct printbuf buf1 = PRINTBUF; struct printbuf buf2 = PRINTBUF; @@ -1047,13 +1050,10 @@ int bch2_mark_stripe(struct btree_trans *trans, } if (!new_s) { - spin_lock(&c->ec_stripes_heap_lock); bch2_stripes_heap_del(c, m, idx); - spin_unlock(&c->ec_stripes_heap_lock); 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; @@ -1063,9 +1063,10 @@ int bch2_mark_stripe(struct btree_trans *trans, for (i = 0; i < new_s->nr_blocks; i++) m->blocks_nonempty += !!stripe_blockcount_get(new_s, i); - spin_lock(&c->ec_stripes_heap_lock); - bch2_stripes_heap_update(c, m, idx); - spin_unlock(&c->ec_stripes_heap_lock); + if (!old_s) + bch2_stripes_heap_insert(c, m, idx); + else + bch2_stripes_heap_update(c, m, idx); } } else { struct gc_stripe *m = @@ -1119,6 +1120,7 @@ int bch2_mark_stripe(struct btree_trans *trans, } int bch2_mark_inode(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -1150,6 +1152,7 @@ int bch2_mark_inode(struct btree_trans *trans, } int bch2_mark_reservation(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -1236,6 +1239,7 @@ fsck_err: } int bch2_mark_reflink_p(struct btree_trans *trans, + enum btree_id btree_id, unsigned level, struct bkey_s_c old, struct bkey_s_c new, unsigned flags) { @@ -1592,6 +1596,7 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans, a->v.stripe = s.k->p.offset; a->v.stripe_redundancy = s.v->nr_redundant; + a->v.data_type = BCH_DATA_stripe; } else { if (bch2_trans_inconsistent_on(a->v.stripe != s.k->p.offset || a->v.stripe_redundancy != s.v->nr_redundant, trans, @@ -1604,6 +1609,7 @@ static int bch2_trans_mark_stripe_bucket(struct btree_trans *trans, a->v.stripe = 0; a->v.stripe_redundancy = 0; + a->v.data_type = alloc_data_type(a->v, BCH_DATA_user); } a->v.dirty_sectors += sectors;