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);
                }
 
                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);
 
 
        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: */
 
 
 #include "mean_and_variance.h"
 
+#include "darray.h"
+
 struct closure;
 
 #ifdef CONFIG_BCACHEFS_DEBUG
 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)