]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Update bcachefs sources to 8dbfede1d9 fixup! bcachefs: More info on check_bucket_ref...
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 13 Feb 2023 20:51:27 +0000 (15:51 -0500)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 13 Feb 2023 20:51:27 +0000 (15:51 -0500)
.bcachefs_revision
libbcachefs/btree_iter.c
libbcachefs/btree_iter.h
libbcachefs/btree_locking.c
libbcachefs/btree_types.h
libbcachefs/buckets.c
libbcachefs/debug.c
libbcachefs/move.c
libbcachefs/super-io.c
libbcachefs/util.c
libbcachefs/util.h

index f6330b43bf426d6285a6d9e04654227dc93d6f1b..bfcbcf58204593cf8c08f392b560b4c70cd07390 100644 (file)
@@ -1 +1 @@
-3e0c5b0722d7fccf0ba83435c5da8892b00c0fe0
+8dbfede1d9e6483c682956c7c8a4900a65f98dde
index dc2b2a0819bd886330b6a910dcc74448c6c2b870..3977bb1fd8345bb8b9c0b970e56f15e3f9fcb853 100644 (file)
@@ -1174,10 +1174,17 @@ int bch2_btree_path_traverse_one(struct btree_trans *trans,
 
        path->uptodate = BTREE_ITER_UPTODATE;
 out:
-       if (bch2_err_matches(ret, BCH_ERR_transaction_restart) != !!trans->restarted)
-               panic("ret %s (%i) trans->restarted %s (%i)\n",
-                     bch2_err_str(ret), ret,
-                     bch2_err_str(trans->restarted), trans->restarted);
+       if (bch2_err_matches(ret, BCH_ERR_transaction_restart) != !!trans->restarted) {
+               struct printbuf buf = PRINTBUF;
+
+               prt_printf(&buf, "ret %s (%i) trans->restarted %s (%i)\n",
+                          bch2_err_str(ret), ret,
+                          bch2_err_str(trans->restarted), trans->restarted);
+#ifdef CONFIG_BCACHEFS_DEBUG
+               bch2_prt_backtrace(&buf, &trans->last_restarted);
+#endif
+               panic("%s", buf.buf);
+       }
        bch2_btree_path_verify(trans, path);
        return ret;
 }
@@ -1360,14 +1367,14 @@ void bch2_trans_restart_error(struct btree_trans *trans, u32 restart_count)
 {
        panic("trans->restart_count %u, should be %u, last restarted by %pS\n",
              trans->restart_count, restart_count,
-             (void *) trans->last_restarted_ip);
+             (void *) trans->last_begin_ip);
 }
 
 void bch2_trans_in_restart_error(struct btree_trans *trans)
 {
        panic("in transaction restart: %s, last restarted by %pS\n",
              bch2_err_str(trans->restarted),
-             (void *) trans->last_restarted_ip);
+             (void *) trans->last_begin_ip);
 }
 
 noinline __cold
@@ -2865,7 +2872,7 @@ u32 bch2_trans_begin(struct btree_trans *trans)
        if (unlikely(time_after(jiffies, trans->srcu_lock_time + msecs_to_jiffies(10))))
                bch2_trans_reset_srcu_lock(trans);
 
-       trans->last_restarted_ip = _RET_IP_;
+       trans->last_begin_ip = _RET_IP_;
        if (trans->restarted) {
                bch2_btree_path_traverse_all(trans);
                trans->notrace_relock_fail = false;
@@ -3046,6 +3053,10 @@ void bch2_trans_exit(struct btree_trans *trans)
        if (trans->paths)
                mempool_free(trans->paths, &c->btree_paths_pool);
 
+#ifdef CONFIG_BCACHEFS_DEBUG
+       darray_exit(&trans->last_restarted);
+#endif
+
        trans->mem      = (void *) 0x1;
        trans->paths    = (void *) 0x1;
 }
index 0ede02c34eac59ce84828f860ee91a3711fdefa4..bbbbe52be83942ebc986eae30d688eb1acf2dbbc 100644 (file)
@@ -251,6 +251,10 @@ static inline int btree_trans_restart_nounlock(struct btree_trans *trans, int er
        BUG_ON(err <= 0);
        BUG_ON(!bch2_err_matches(err, BCH_ERR_transaction_restart));
 
+#ifdef CONFIG_BCACHEFS_DEBUG
+       bch2_save_backtrace(&trans->last_restarted, current);
+#endif
+
        trans->restarted = err;
        return -err;
 }
index 1ddac23cc50985f4ace1c7dd2eec179c81214c06..80398e497bd53a3a546a77c45bafd522c065ad4d 100644 (file)
@@ -191,7 +191,7 @@ static noinline int break_cycle(struct lock_graph *g, struct printbuf *cycle)
                        prt_printf(&buf, "backtrace:");
                        prt_newline(&buf);
                        printbuf_indent_add(&buf, 2);
-                       bch2_prt_backtrace(&buf, trans->locking_wait.task);
+                       bch2_prt_task_backtrace(&buf, trans->locking_wait.task);
                        printbuf_indent_sub(&buf, 2);
                        prt_newline(&buf);
                }
@@ -225,6 +225,10 @@ static int lock_graph_descend(struct lock_graph *g, struct btree_trans *trans,
 
                while (g->nr)
                        lock_graph_up(g);
+
+               if (cycle)
+                       return 0;
+
                trace_and_count(trans->c, trans_restart_would_deadlock_recursion_limit, trans, _RET_IP_);
                return btree_trans_restart(orig_trans, BCH_ERR_transaction_restart_deadlock_recursion_limit);
        }
@@ -247,6 +251,9 @@ int bch2_check_for_deadlock(struct btree_trans *trans, struct printbuf *cycle)
        int ret;
 
        if (trans->lock_must_abort) {
+               if (cycle)
+                       return -1;
+
                trace_and_count(trans->c, trans_restart_would_deadlock, trans, _RET_IP_);
                return btree_trans_restart(trans, BCH_ERR_transaction_restart_would_deadlock);
        }
index ad73cd2e81475dea677a62f0617ab74c996a223d..97ff267c3aff069ff54d2f2bc0512506a6c80c30 100644 (file)
@@ -442,7 +442,10 @@ struct btree_trans {
        bool                    notrace_relock_fail:1;
        enum bch_errcode        restarted:16;
        u32                     restart_count;
-       unsigned long           last_restarted_ip;
+#ifdef CONFIG_BCACHEFS_DEBUG
+       bch_stacktrace          last_restarted;
+#endif
+       unsigned long           last_begin_ip;
        unsigned long           srcu_lock_time;
 
        /*
index ebfbfd97b0a396d21425b9a4ba3470f75cf4ceda..fd3ba10bc8a74c4df2d24b9a1b4f1c08a51cd50b 100644 (file)
@@ -727,7 +727,7 @@ static int check_bucket_ref(struct btree_trans *trans,
 
        if (b_gen != ptr->gen) {
                ret = 1;
-               goto err;
+               goto out;
        }
 
        if (!data_type_is_empty(bucket_data_type) &&
index fcefd55a5322474405ae9558a7008439aa51e309..8f43581f3972d283f847723459981ca7068d58fd 100644 (file)
@@ -527,7 +527,7 @@ static ssize_t bch2_btree_transactions_read(struct file *file, char __user *buf,
                prt_printf(&i->buf, "backtrace:");
                prt_newline(&i->buf);
                printbuf_indent_add(&i->buf, 2);
-               bch2_prt_backtrace(&i->buf, trans->locking_wait.task);
+               bch2_prt_task_backtrace(&i->buf, trans->locking_wait.task);
                printbuf_indent_sub(&i->buf, 2);
                prt_newline(&i->buf);
 
index 7e7e9042de402f0a92787dd080d3284159ee4d50..e7eb55bd8a251cf40d7ded91e66012e45cbd7b46 100644 (file)
@@ -584,7 +584,7 @@ int bch2_move_data(struct bch_fs *c,
        return ret;
 }
 
-static int verify_bucket_evacuated(struct btree_trans *trans, struct bpos bucket, int gen)
+static noinline void verify_bucket_evacuated(struct btree_trans *trans, struct bpos bucket, int gen)
 {
        struct bch_fs *c = trans->c;
        struct btree_iter iter;
@@ -597,8 +597,8 @@ static int verify_bucket_evacuated(struct btree_trans *trans, struct bpos bucket
        bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc,
                             bucket, BTREE_ITER_CACHED);
 again:
-       k = bch2_btree_iter_peek_slot(&iter);
-       ret = bkey_err(k);
+       ret = lockrestart_do(trans,
+                       bkey_err(k = bch2_btree_iter_peek_slot(&iter)));
 
        if (!ret && k.k->type == KEY_TYPE_alloc_v4) {
                struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
@@ -615,7 +615,7 @@ again:
        }
 
        bch2_trans_iter_exit(trans, &iter);
-       return ret;
+       return;
 failed_to_evacuate:
        bch2_trans_iter_exit(trans, &iter);
 
@@ -651,7 +651,6 @@ failed_to_evacuate:
 
        bch2_print_string_as_lines(KERN_ERR, buf.buf);
        printbuf_exit(&buf);
-       return 0;
 }
 
 int __bch2_evacuate_bucket(struct moving_context *ctxt,
@@ -800,7 +799,7 @@ next:
                move_ctxt_wait_event(ctxt, NULL, list_empty(&ctxt->reads));
                closure_sync(&ctxt->cl);
                if (!ctxt->write_error)
-                       lockrestart_do(&trans, verify_bucket_evacuated(&trans, bucket, gen));
+                       verify_bucket_evacuated(&trans, bucket, gen);
        }
 err:
        bch2_trans_exit(&trans);
index 00c1f69bbe346e0b135b720671d93b91ad421b21..b9af78203fb895fbec60da9d6d8435e02e271cd8 100644 (file)
@@ -432,7 +432,7 @@ static void bch2_sb_update(struct bch_fs *c)
                ca->mi = bch2_mi_to_cpu(mi->members + i);
 }
 
-static void __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
+static int __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
 {
        struct bch_sb_field *src_f, *dst_f;
        struct bch_sb *dst = dst_handle->sb;
@@ -457,42 +457,45 @@ static void __copy_super(struct bch_sb_handle *dst_handle, struct bch_sb *src)
        memcpy(dst->compat,     src->compat,    sizeof(dst->compat));
 
        for (i = 0; i < BCH_SB_FIELD_NR; i++) {
+               int d;
+
                if ((1U << i) & BCH_SINGLE_DEVICE_SB_FIELDS)
                        continue;
 
                src_f = bch2_sb_field_get(src, i);
                dst_f = bch2_sb_field_get(dst, i);
+
+               d = (src_f ? le32_to_cpu(src_f->u64s) : 0) -
+                   (dst_f ? le32_to_cpu(dst_f->u64s) : 0);
+               if (d > 0) {
+                       int ret = bch2_sb_realloc(dst_handle, le32_to_cpu(dst_handle->sb->u64s) + d);
+                       if (ret)
+                               return ret;
+
+                       dst = dst_handle->sb;
+                       dst_f = bch2_sb_field_get(dst, i);
+               }
+
                dst_f = __bch2_sb_field_resize(dst_handle, dst_f,
                                src_f ? le32_to_cpu(src_f->u64s) : 0);
 
                if (src_f)
                        memcpy(dst_f, src_f, vstruct_bytes(src_f));
        }
+
+       return 0;
 }
 
 int bch2_sb_to_fs(struct bch_fs *c, struct bch_sb *src)
 {
-       struct bch_sb_field_journal *journal_buckets =
-               bch2_sb_get_journal(src);
-       unsigned journal_u64s = journal_buckets
-               ? le32_to_cpu(journal_buckets->field.u64s)
-               : 0;
        int ret;
 
        lockdep_assert_held(&c->sb_lock);
 
-       ret = bch2_sb_realloc(&c->disk_sb,
-                             le32_to_cpu(src->u64s) - journal_u64s);
-       if (ret)
-               return ret;
-
-       __copy_super(&c->disk_sb, src);
-
-       ret = bch2_sb_replicas_to_cpu_replicas(c);
-       if (ret)
-               return ret;
-
-       ret = bch2_sb_disk_groups_to_cpu(c);
+       ret =   bch2_sb_realloc(&c->disk_sb, 0) ?:
+               __copy_super(&c->disk_sb, src) ?:
+               bch2_sb_replicas_to_cpu_replicas(c) ?:
+               bch2_sb_disk_groups_to_cpu(c);
        if (ret)
                return ret;
 
@@ -502,21 +505,7 @@ int bch2_sb_to_fs(struct bch_fs *c, struct bch_sb *src)
 
 int bch2_sb_from_fs(struct bch_fs *c, struct bch_dev *ca)
 {
-       struct bch_sb *src = c->disk_sb.sb, *dst = ca->disk_sb.sb;
-       struct bch_sb_field_journal *journal_buckets =
-               bch2_sb_get_journal(dst);
-       unsigned journal_u64s = journal_buckets
-               ? le32_to_cpu(journal_buckets->field.u64s)
-               : 0;
-       unsigned u64s = le32_to_cpu(src->u64s) + journal_u64s;
-       int ret;
-
-       ret = bch2_sb_realloc(&ca->disk_sb, u64s);
-       if (ret)
-               return ret;
-
-       __copy_super(&ca->disk_sb, src);
-       return 0;
+       return __copy_super(&ca->disk_sb, c->disk_sb.sb);
 }
 
 /* read superblock: */
index 9939bf2a8f6caf06a3874e5690871a7b9728b298..a9790954aa5ad5a3c8c6c6b78e9c1ae4cd249cb5 100644 (file)
@@ -296,22 +296,48 @@ void bch2_print_string_as_lines(const char *prefix, const char *lines)
        console_unlock();
 }
 
-int bch2_prt_backtrace(struct printbuf *out, struct task_struct *task)
+int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *task)
 {
-       unsigned long entries[32];
-       unsigned i, nr_entries;
+       unsigned nr_entries = 0;
+       int ret = 0;
+
+       stack->nr = 0;
+       ret = darray_make_room(stack, 32);
+       if (ret)
+               return ret;
 
        if (!down_read_trylock(&task->signal->exec_update_lock))
-               return 0;
+               return -1;
+
+       do {
+               nr_entries = stack_trace_save_tsk(task, stack->data, stack->size, 0);
+       } while (nr_entries == stack->size &&
+                !(ret = darray_make_room(stack, stack->size * 2)));
+
+       stack->nr = nr_entries;
+       up_read(&task->signal->exec_update_lock);
 
-       nr_entries = stack_trace_save_tsk(task, entries, ARRAY_SIZE(entries), 0);
-       for (i = 0; i < nr_entries; i++) {
-               prt_printf(out, "[<0>] %pB", (void *)entries[i]);
+       return ret;
+}
+
+void bch2_prt_backtrace(struct printbuf *out, bch_stacktrace *stack)
+{
+       unsigned long *i;
+
+       darray_for_each(*stack, i) {
+               prt_printf(out, "[<0>] %pB", (void *) *i);
                prt_newline(out);
        }
+}
 
-       up_read(&task->signal->exec_update_lock);
-       return 0;
+int bch2_prt_task_backtrace(struct printbuf *out, struct task_struct *task)
+{
+       bch_stacktrace stack = { 0 };
+       int ret = bch2_save_backtrace(&stack, task);
+
+       bch2_prt_backtrace(out, &stack);
+       darray_exit(&stack);
+       return ret;
 }
 
 /* time stats: */
index 09e272932dff388b2962f853898f6f3786a34338..c3718d3693718e7e49ff5e15eb36bd8295d4ac2d 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/workqueue.h>
 #include <linux/mean_and_variance.h>
 
+#include "darray.h"
+
 struct closure;
 
 #ifdef CONFIG_BCACHEFS_DEBUG
@@ -360,7 +362,11 @@ u64 bch2_read_flag_list(char *, const char * const[]);
 void bch2_prt_u64_binary(struct printbuf *, u64, unsigned);
 
 void bch2_print_string_as_lines(const char *prefix, const char *lines);
-int bch2_prt_backtrace(struct printbuf *, struct task_struct *);
+
+typedef DARRAY(unsigned long) bch_stacktrace;
+int bch2_save_backtrace(bch_stacktrace *stack, struct task_struct *);
+void bch2_prt_backtrace(struct printbuf *, bch_stacktrace *);
+int bch2_prt_task_backtrace(struct printbuf *, struct task_struct *);
 
 #define NR_QUANTILES   15
 #define QUANTILE_IDX(i)        inorder_to_eytzinger0(i, NR_QUANTILES)