bcachefs: for_each_btree_node() now returns errors directly

This changes for_each_btree_node() to work like for_each_btree_key(),
and to that end bch2_btree_iter_peek_node() and next_node() also return
error ptrs.

Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c
index ea3f733..315a78b 100644
--- a/fs/bcachefs/btree_gc.c
+++ b/fs/bcachefs/btree_gc.c
@@ -806,7 +806,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
 	gc_pos_set(c, gc_pos_btree(btree_id, POS_MIN, 0));
 
 	__for_each_btree_node(&trans, iter, btree_id, POS_MIN,
-			      0, depth, BTREE_ITER_PREFETCH, b) {
+			      0, depth, BTREE_ITER_PREFETCH, b, ret) {
 		bch2_verify_btree_nr_keys(b);
 
 		gc_pos_set(c, gc_pos_btree_node(b));
@@ -833,7 +833,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
 	}
 	bch2_trans_iter_exit(&trans, &iter);
 
-	ret = bch2_trans_exit(&trans) ?: ret;
+	bch2_trans_exit(&trans);
 	if (ret)
 		return ret;
 
diff --git a/fs/bcachefs/btree_iter.c b/fs/bcachefs/btree_iter.c
index dd0cd4a..339b365 100644
--- a/fs/bcachefs/btree_iter.c
+++ b/fs/bcachefs/btree_iter.c
@@ -1900,7 +1900,7 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
 
 	ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
 	if (ret)
-		goto out;
+		goto err;
 
 	b = btree_path_node(iter->path, iter->path->level);
 	if (!b)
@@ -1920,6 +1920,9 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
 	bch2_btree_iter_verify(iter);
 
 	return b;
+err:
+	b = ERR_PTR(ret);
+	goto out;
 }
 
 struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
@@ -1936,7 +1939,9 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
 	if (!btree_path_node(path, path->level))
 		goto out;
 
-	bch2_trans_cond_resched(trans);
+	ret = bch2_trans_cond_resched(trans);
+	if (ret)
+		goto err;
 
 	btree_node_unlock(path, path->level);
 	path->l[path->level].b = BTREE_ITER_NO_NODE_UP;
@@ -1945,7 +1950,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
 	btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
 	ret = bch2_btree_path_traverse(trans, path, iter->flags);
 	if (ret)
-		goto out;
+		goto err;
 
 	/* got to end? */
 	b = btree_path_node(path, path->level);
@@ -1969,10 +1974,8 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
 		bch2_btree_iter_verify(iter);
 
 		ret = bch2_btree_path_traverse(trans, path, iter->flags);
-		if (ret) {
-			b = NULL;
-			goto out;
-		}
+		if (ret)
+			goto err;
 
 		b = path->l[path->level].b;
 	}
@@ -1989,6 +1992,9 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
 	bch2_btree_iter_verify(iter);
 
 	return b;
+err:
+	b = ERR_PTR(ret);
+	goto out;
 }
 
 /* Iterate across keys (in leaf nodes only) */
diff --git a/fs/bcachefs/btree_iter.h b/fs/bcachefs/btree_iter.h
index feb2fcf..1cb4261 100644
--- a/fs/bcachefs/btree_iter.h
+++ b/fs/bcachefs/btree_iter.h
@@ -284,18 +284,18 @@ static inline int bch2_trans_cond_resched(struct btree_trans *trans)
 	}
 }
 
-#define __for_each_btree_node(_trans, _iter, _btree_id, _start,	\
-			      _locks_want, _depth, _flags, _b)		\
+#define __for_each_btree_node(_trans, _iter, _btree_id, _start,		\
+			      _locks_want, _depth, _flags, _b, _ret)	\
 	for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id),	\
 				_start, _locks_want, _depth, _flags),	\
 	     _b = bch2_btree_iter_peek_node(&(_iter));			\
-	     (_b);							\
+	     !((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b);			\
 	     (_b) = bch2_btree_iter_next_node(&(_iter)))
 
 #define for_each_btree_node(_trans, _iter, _btree_id, _start,		\
-			    _flags, _b)					\
+			    _flags, _b, _ret)				\
 	__for_each_btree_node(_trans, _iter, _btree_id, _start,		\
-			      0, 0, _flags, _b)
+			      0, 0, _flags, _b, _ret)
 
 static inline struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter,
 						     unsigned flags)
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
index 4ca2de3..14ecd3f 100644
--- a/fs/bcachefs/btree_update_interior.c
+++ b/fs/bcachefs/btree_update_interior.c
@@ -1736,6 +1736,10 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
 		goto out;
 
 	b = bch2_btree_iter_peek_node(iter);
+	ret = PTR_ERR_OR_ZERO(b);
+	if (ret)
+		goto out;
+
 	if (!b || b->data->keys.seq != seq)
 		goto out;
 
diff --git a/fs/bcachefs/debug.c b/fs/bcachefs/debug.c
index 5ffb7f0..8b25ef9 100644
--- a/fs/bcachefs/debug.c
+++ b/fs/bcachefs/debug.c
@@ -318,7 +318,7 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf,
 
 	bch2_trans_init(&trans, i->c, 0, 0);
 
-	for_each_btree_node(&trans, iter, i->id, i->from, 0, b) {
+	for_each_btree_node(&trans, iter, i->id, i->from, 0, b, err) {
 		bch2_btree_node_to_text(&PBUF(i->buf), i->c, b);
 		i->bytes = strlen(i->buf);
 		err = flush_buf(i);
diff --git a/fs/bcachefs/journal_seq_blacklist.c b/fs/bcachefs/journal_seq_blacklist.c
index 68fb2eb..f84a63a 100644
--- a/fs/bcachefs/journal_seq_blacklist.c
+++ b/fs/bcachefs/journal_seq_blacklist.c
@@ -254,7 +254,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
 		struct btree *b;
 
 		for_each_btree_node(&trans, iter, i, POS_MIN,
-				    BTREE_ITER_PREFETCH, b)
+				    BTREE_ITER_PREFETCH, b, ret)
 			if (test_bit(BCH_FS_STOPPING, &c->flags)) {
 				bch2_trans_exit(&trans);
 				return;
@@ -262,7 +262,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
 		bch2_trans_iter_exit(&trans, &iter);
 	}
 
-	ret = bch2_trans_exit(&trans);
+	bch2_trans_exit(&trans);
 	if (ret)
 		return;
 
diff --git a/fs/bcachefs/migrate.c b/fs/bcachefs/migrate.c
index 94d5d99..111a411 100644
--- a/fs/bcachefs/migrate.c
+++ b/fs/bcachefs/migrate.c
@@ -135,9 +135,10 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
 	for (id = 0; id < BTREE_ID_NR; id++) {
 		bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
 					  BTREE_ITER_PREFETCH);
-
+retry:
 		while (bch2_trans_begin(&trans),
-		       (b = bch2_btree_iter_peek_node(&iter))) {
+		       (b = bch2_btree_iter_peek_node(&iter)) &&
+		       !(ret = PTR_ERR_OR_ZERO(b))) {
 			if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key),
 						  dev_idx))
 				goto next;
@@ -164,6 +165,9 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
 next:
 			bch2_btree_iter_next_node(&iter);
 		}
+		if (ret == -EINTR)
+			goto retry;
+
 		bch2_trans_iter_exit(&trans, &iter);
 
 		if (ret)
diff --git a/fs/bcachefs/move.c b/fs/bcachefs/move.c
index 0db0ce5..2f60863 100644
--- a/fs/bcachefs/move.c
+++ b/fs/bcachefs/move.c
@@ -885,9 +885,10 @@ static int bch2_move_btree(struct bch_fs *c,
 
 		bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
 					  BTREE_ITER_PREFETCH);
-
+retry:
 		while (bch2_trans_begin(&trans),
-		       (b = bch2_btree_iter_peek_node(&iter))) {
+		       (b = bch2_btree_iter_peek_node(&iter)) &&
+		       !(ret = PTR_ERR_OR_ZERO(b))) {
 			if (kthread && kthread_should_stop())
 				break;
 
@@ -915,6 +916,9 @@ static int bch2_move_btree(struct bch_fs *c,
 			bch2_trans_cond_resched(&trans);
 			bch2_btree_iter_next_node(&iter);
 		}
+		if (ret == -EINTR)
+			goto retry;
+
 		bch2_trans_iter_exit(&trans, &iter);
 
 		if (kthread && kthread_should_stop())