bcachefs: Move deletion of refcount=0 indirect extents to their triggers

For backpointers, we need to switch the order triggers are run in: we
need to run triggers for deletions/overwrites before triggers for
inserts.

To avoid breaking the reflink triggers, this patch moves deleting of
indirect extents with refcount=0 to their triggers, instead of doing it
when we update those keys.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
Kent Overstreet 2022-03-31 00:03:37 -04:00 committed by Kent Overstreet
parent 1296ab5520
commit 78668fe0bb
3 changed files with 43 additions and 6 deletions

View File

@ -1798,11 +1798,6 @@ static int __bch2_trans_mark_reflink_p(struct btree_trans *trans,
le64_add_cpu(refcount, add);
if (!*refcount) {
n->k.type = KEY_TYPE_deleted;
set_bkey_val_u64s(&n->k, 0);
}
bch2_btree_iter_set_pos_to_extent_start(&iter);
ret = bch2_trans_update(trans, &iter, n, 0);
if (ret)

View File

@ -98,6 +98,24 @@ bool bch2_reflink_v_merge(struct bch_fs *c, struct bkey_s _l, struct bkey_s_c _r
return l.v->refcount == r.v->refcount && bch2_extent_merge(c, _l, _r);
}
int bch2_trans_mark_reflink_v(struct btree_trans *trans,
struct bkey_s_c old, struct bkey_i *new,
unsigned flags)
{
if (!(flags & BTREE_TRIGGER_OVERWRITE)) {
struct bkey_i_reflink_v *r = bkey_i_to_reflink_v(new);
if (!r->v.refcount) {
r->k.type = KEY_TYPE_deleted;
r->k.size = 0;
set_bkey_val_u64s(&r->k, 0);
return 0;
}
}
return bch2_trans_mark_extent(trans, old, new, flags);
}
/* indirect inline data */
const char *bch2_indirect_inline_data_invalid(const struct bch_fs *c,
@ -119,6 +137,24 @@ void bch2_indirect_inline_data_to_text(struct printbuf *out,
min(datalen, 32U), d.v->data);
}
int bch2_trans_mark_indirect_inline_data(struct btree_trans *trans,
struct bkey_s_c old, struct bkey_i *new,
unsigned flags)
{
if (!(flags & BTREE_TRIGGER_OVERWRITE)) {
struct bkey_i_indirect_inline_data *r =
bkey_i_to_indirect_inline_data(new);
if (!r->v.refcount) {
r->k.type = KEY_TYPE_deleted;
r->k.size = 0;
set_bkey_val_u64s(&r->k, 0);
}
}
return 0;
}
static int bch2_make_extent_indirect(struct btree_trans *trans,
struct btree_iter *extent_iter,
struct bkey_i *orig)

View File

@ -18,12 +18,14 @@ bool bch2_reflink_p_merge(struct bch_fs *, struct bkey_s, struct bkey_s_c);
const char *bch2_reflink_v_invalid(const struct bch_fs *, struct bkey_s_c);
void bch2_reflink_v_to_text(struct printbuf *, struct bch_fs *,
struct bkey_s_c);
int bch2_trans_mark_reflink_v(struct btree_trans *, struct bkey_s_c,
struct bkey_i *, unsigned);
#define bch2_bkey_ops_reflink_v (struct bkey_ops) { \
.key_invalid = bch2_reflink_v_invalid, \
.val_to_text = bch2_reflink_v_to_text, \
.swab = bch2_ptr_swab, \
.trans_trigger = bch2_trans_mark_extent, \
.trans_trigger = bch2_trans_mark_reflink_v, \
.atomic_trigger = bch2_mark_extent, \
}
@ -31,10 +33,14 @@ const char *bch2_indirect_inline_data_invalid(const struct bch_fs *,
struct bkey_s_c);
void bch2_indirect_inline_data_to_text(struct printbuf *,
struct bch_fs *, struct bkey_s_c);
int bch2_trans_mark_indirect_inline_data(struct btree_trans *,
struct bkey_s_c, struct bkey_i *,
unsigned);
#define bch2_bkey_ops_indirect_inline_data (struct bkey_ops) { \
.key_invalid = bch2_indirect_inline_data_invalid, \
.val_to_text = bch2_indirect_inline_data_to_text, \
.trans_trigger = bch2_trans_mark_indirect_inline_data, \
}
static inline const __le64 *bkey_refcount_c(struct bkey_s_c k)