diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-06-24 17:50:52 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:23 -0400 |
commit | 88767d65d84257f9b5dfed1aa89404f1b6ddf142 (patch) | |
tree | 5796773313bd997142f61b5372c7cada6dda8d44 | |
parent | 44da9767bb32467ac660ce6bacf75162f5abf9a1 (diff) |
bcachefs: Update path now handles triggers that generate more triggers
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_types.h | 1 | ||||
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 29 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 24 | ||||
-rw-r--r-- | fs/bcachefs/buckets.h | 3 |
4 files changed, 37 insertions, 20 deletions
diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index bdcf9288d749..ec14e2deecb7 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -265,6 +265,7 @@ struct btree_insert_entry { bool deferred; bool triggered; + bool marked; }; #define BTREE_ITER_MAX 64 diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index 6e63c916986e..4461e42f2367 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -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); diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 0d96ea572bd0..911c39c4872e 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -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; } diff --git a/fs/bcachefs/buckets.h b/fs/bcachefs/buckets.h index 793bb8cb2527..46eb493b42ca 100644 --- a/fs/bcachefs/buckets.h +++ b/fs/bcachefs/buckets.h @@ -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: */ |