]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: Move deletion of refcount=0 indirect extents to their triggers
authorKent Overstreet <kent.overstreet@gmail.com>
Thu, 31 Mar 2022 04:03:37 +0000 (00:03 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:29 +0000 (17:09 -0400)
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>
fs/bcachefs/buckets.c
fs/bcachefs/reflink.c
fs/bcachefs/reflink.h

index a681a6045dc9a66686985cfae82f810d6bf07beb..0f2dd4b8b47dfc78c2bf0368bf1efee54ee11ddd 100644 (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)
index c8d6d73681e010c0ec00221a7a473070c4680b0a..6824730945d40bd6eea2ec225628408614738b89 100644 (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)
index 4da4330014a82167fd48fdd6fc2c19b116581e65..8eb41c0292eb7ae742e7b095f520b6ff0a425623 100644 (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)