bcachefs: Update path now handles triggers that generate more triggers
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 24 Jun 2019 21:50:52 +0000 (17:50 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:23 +0000 (17:08 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_types.h
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h

index bdcf9288d7493298b15c9684ce2ec3c933056566..ec14e2deecb7d5d77b97e0d33f009c740e35466f 100644 (file)
@@ -265,6 +265,7 @@ struct btree_insert_entry {
 
        bool                    deferred;
        bool                    triggered;
+       bool                    marked;
 };
 
 #define BTREE_ITER_MAX         64
index 6e63c916986e28de6d1f1a98fa1076811adba315..4461e42f2367a1630975c6212da357833122fe18 100644 (file)
@@ -542,6 +542,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
        struct bch_fs *c = trans->c;
        struct bch_fs_usage_online *fs_usage = NULL;
        struct btree_insert_entry *i;
+       bool saw_non_marked;
        unsigned mark_flags = trans->flags & BTREE_INSERT_BUCKET_INVALIDATE
                ? BCH_BUCKET_MARK_BUCKET_INVALIDATE
                : 0;
@@ -551,14 +552,28 @@ static inline int do_btree_insert_at(struct btree_trans *trans,
                BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK);
 
        trans_for_each_update_iter(trans, i)
-               if (update_has_triggers(trans, i) &&
-                   update_triggers_transactional(trans, i)) {
-                       ret = bch2_trans_mark_update(trans, i);
-                       if (ret == -EINTR)
-                               trace_trans_restart_mark(trans->ip);
-                       if (ret)
-                               goto out_clear_replicas;
+               i->marked = false;
+
+       do {
+               saw_non_marked = false;
+
+               trans_for_each_update_iter(trans, i) {
+                       if (i->marked)
+                               continue;
+
+                       saw_non_marked = true;
+                       i->marked = true;
+
+                       if (update_has_triggers(trans, i) &&
+                           update_triggers_transactional(trans, i)) {
+                               ret = bch2_trans_mark_update(trans, i->iter, i->k);
+                               if (ret == -EINTR)
+                                       trace_trans_restart_mark(trans->ip);
+                               if (ret)
+                                       goto out_clear_replicas;
+                       }
                }
+       } while (saw_non_marked);
 
        btree_trans_lock_write(c, trans);
 
index 0d96ea572bd0c9bb8b6a728eb41622b87ce96ccf..911c39c4872e31d586059c77e2cc7814771a7c56 100644 (file)
@@ -1590,9 +1590,9 @@ int bch2_trans_mark_key(struct btree_trans *trans, struct bkey_s_c k,
 }
 
 int bch2_trans_mark_update(struct btree_trans *trans,
-                          struct btree_insert_entry *insert)
+                          struct btree_iter *iter,
+                          struct bkey_i *insert)
 {
-       struct btree_iter       *iter = insert->iter;
        struct btree            *b = iter->l[0].b;
        struct btree_node_iter  node_iter = iter->l[0].iter;
        struct bkey_packed      *_k;
@@ -1602,9 +1602,9 @@ int bch2_trans_mark_update(struct btree_trans *trans,
                return 0;
 
        ret = bch2_trans_mark_key(trans,
-                       bkey_i_to_s_c(insert->k),
-                       bpos_min(insert->k->k.p, b->key.k.p).offset -
-                       bkey_start_offset(&insert->k->k),
+                       bkey_i_to_s_c(insert),
+                       bpos_min(insert->k.p, b->key.k.p).offset -
+                       bkey_start_offset(&insert->k),
                        BCH_BUCKET_MARK_INSERT);
        if (ret)
                return ret;
@@ -1618,25 +1618,25 @@ int bch2_trans_mark_update(struct btree_trans *trans,
                k = bkey_disassemble(b, _k, &unpacked);
 
                if (btree_node_is_extents(b)
-                   ? bkey_cmp(insert->k->k.p, bkey_start_pos(k.k)) <= 0
-                   : bkey_cmp(insert->k->k.p, k.k->p))
+                   ? bkey_cmp(insert->k.p, bkey_start_pos(k.k)) <= 0
+                   : bkey_cmp(insert->k.p, k.k->p))
                        break;
 
                if (btree_node_is_extents(b)) {
-                       switch (bch2_extent_overlap(&insert->k->k, k.k)) {
+                       switch (bch2_extent_overlap(&insert->k, k.k)) {
                        case BCH_EXTENT_OVERLAP_ALL:
                                sectors = -((s64) k.k->size);
                                break;
                        case BCH_EXTENT_OVERLAP_BACK:
-                               sectors = bkey_start_offset(&insert->k->k) -
+                               sectors = bkey_start_offset(&insert->k) -
                                        k.k->p.offset;
                                break;
                        case BCH_EXTENT_OVERLAP_FRONT:
                                sectors = bkey_start_offset(k.k) -
-                                       insert->k->k.p.offset;
+                                       insert->k.p.offset;
                                break;
                        case BCH_EXTENT_OVERLAP_MIDDLE:
-                               sectors = k.k->p.offset - insert->k->k.p.offset;
+                               sectors = k.k->p.offset - insert->k.p.offset;
                                BUG_ON(sectors <= 0);
 
                                ret = bch2_trans_mark_key(trans, k, sectors,
@@ -1644,7 +1644,7 @@ int bch2_trans_mark_update(struct btree_trans *trans,
                                if (ret)
                                        return ret;
 
-                               sectors = bkey_start_offset(&insert->k->k) -
+                               sectors = bkey_start_offset(&insert->k) -
                                        k.k->p.offset;
                                break;
                        }
index 793bb8cb25275acc290996e05967e37d1bbabeb7..46eb493b42cadd233f5e535dbade5d6678fb4875 100644 (file)
@@ -274,7 +274,8 @@ void bch2_replicas_delta_list_apply(struct bch_fs *,
                                    struct replicas_delta_list *);
 int bch2_trans_mark_key(struct btree_trans *, struct bkey_s_c, s64, unsigned);
 int bch2_trans_mark_update(struct btree_trans *,
-                          struct btree_insert_entry *);
+                          struct btree_iter *iter,
+                          struct bkey_i *insert);
 void bch2_trans_fs_usage_apply(struct btree_trans *, struct bch_fs_usage_online *);
 
 /* disk reservations: */