bcachefs: Fix livelock calling bch2_mark_bkey_replicas()
authorKent Overstreet <kent.overstreet@gmail.com>
Sat, 3 Apr 2021 23:41:09 +0000 (19:41 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:08:59 +0000 (17:08 -0400)
The bug was that we were trying to find a replicas entry that wasn't
sorted - but, we can also simplify the code by not using
bch2_mark_bkey_replicas and instead ensuring the list of replicas
entries exists directly.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_update_leaf.c
fs/bcachefs/buckets.c
fs/bcachefs/buckets.h

index ee1c26f2901f675cdef3cb26337be874ab90b5c3..54e3850df009f41cc9603ae501034e6fe59592df 100644 (file)
@@ -707,11 +707,9 @@ int bch2_trans_commit_error(struct btree_trans *trans,
        case BTREE_INSERT_NEED_MARK_REPLICAS:
                bch2_trans_unlock(trans);
 
-               trans_for_each_update(trans, i) {
-                       ret = bch2_mark_bkey_replicas(c, bkey_i_to_s_c(i->k));
-                       if (ret)
-                               return ret;
-               }
+               ret = bch2_replicas_delta_list_mark(c, trans->fs_usage_deltas);
+               if (ret)
+                       return ret;
 
                if (bch2_trans_relock(trans))
                        return 0;
index 4c2485afe43cf366fa4f291e6feee95507809d3e..0b90104ffe7b659b487aeb3c43bd3e21afdbbdf3 100644 (file)
@@ -565,6 +565,7 @@ static inline void update_replicas_list(struct btree_trans *trans,
        n->delta = sectors;
        memcpy((void *) n + offsetof(struct replicas_delta, r),
               r, replicas_entry_bytes(r));
+       bch2_replicas_entry_sort(&n->r);
        d->used += b;
 }
 
@@ -615,6 +616,18 @@ unwind:
        return -1;
 }
 
+int bch2_replicas_delta_list_mark(struct bch_fs *c,
+                                 struct replicas_delta_list *r)
+{
+       struct replicas_delta *d = r->d;
+       struct replicas_delta *top = (void *) r->d + r->used;
+       int ret = 0;
+
+       for (d = r->d; !ret && d != top; d = replicas_delta_next(d))
+               ret = bch2_mark_replicas(c, &d->r);
+       return ret;
+}
+
 #define do_mark_fn(fn, c, pos, flags, ...)                             \
 ({                                                                     \
        int gc, ret = 0;                                                \
index af8cb74d71e0c59df7f4aeba26b23e11f7d8dba9..1b83a768ba06450386184e220ffd186cdb32c93f 100644 (file)
@@ -253,6 +253,8 @@ int bch2_mark_update(struct btree_trans *, struct btree_iter *,
 int bch2_replicas_delta_list_apply(struct bch_fs *,
                                   struct bch_fs_usage *,
                                   struct replicas_delta_list *);
+int bch2_replicas_delta_list_mark(struct bch_fs *,
+                                 struct replicas_delta_list *);
 int bch2_trans_mark_key(struct btree_trans *, struct bkey_s_c, struct bkey_s_c,
                        unsigned, s64, unsigned);
 int bch2_trans_mark_update(struct btree_trans *, struct btree_iter *iter,