Commit d355c6f4 authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

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: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent dfc276df
...@@ -806,7 +806,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id, ...@@ -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)); gc_pos_set(c, gc_pos_btree(btree_id, POS_MIN, 0));
__for_each_btree_node(&trans, iter, btree_id, POS_MIN, __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); bch2_verify_btree_nr_keys(b);
gc_pos_set(c, gc_pos_btree_node(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, ...@@ -833,7 +833,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
} }
bch2_trans_iter_exit(&trans, &iter); bch2_trans_iter_exit(&trans, &iter);
ret = bch2_trans_exit(&trans) ?: ret; bch2_trans_exit(&trans);
if (ret) if (ret)
return ret; return ret;
......
...@@ -1900,7 +1900,7 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter) ...@@ -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); ret = bch2_btree_path_traverse(trans, iter->path, iter->flags);
if (ret) if (ret)
goto out; goto err;
b = btree_path_node(iter->path, iter->path->level); b = btree_path_node(iter->path, iter->path->level);
if (!b) if (!b)
...@@ -1920,6 +1920,9 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter) ...@@ -1920,6 +1920,9 @@ struct btree *bch2_btree_iter_peek_node(struct btree_iter *iter)
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
return b; return b;
err:
b = ERR_PTR(ret);
goto out;
} }
struct btree *bch2_btree_iter_next_node(struct btree_iter *iter) 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) ...@@ -1936,7 +1939,9 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
if (!btree_path_node(path, path->level)) if (!btree_path_node(path, path->level))
goto out; goto out;
bch2_trans_cond_resched(trans); ret = bch2_trans_cond_resched(trans);
if (ret)
goto err;
btree_node_unlock(path, path->level); btree_node_unlock(path, path->level);
path->l[path->level].b = BTREE_ITER_NO_NODE_UP; 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) ...@@ -1945,7 +1950,7 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE); btree_path_set_dirty(path, BTREE_ITER_NEED_TRAVERSE);
ret = bch2_btree_path_traverse(trans, path, iter->flags); ret = bch2_btree_path_traverse(trans, path, iter->flags);
if (ret) if (ret)
goto out; goto err;
/* got to end? */ /* got to end? */
b = btree_path_node(path, path->level); b = btree_path_node(path, path->level);
...@@ -1969,10 +1974,8 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter) ...@@ -1969,10 +1974,8 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
ret = bch2_btree_path_traverse(trans, path, iter->flags); ret = bch2_btree_path_traverse(trans, path, iter->flags);
if (ret) { if (ret)
b = NULL; goto err;
goto out;
}
b = path->l[path->level].b; b = path->l[path->level].b;
} }
...@@ -1989,6 +1992,9 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter) ...@@ -1989,6 +1992,9 @@ struct btree *bch2_btree_iter_next_node(struct btree_iter *iter)
bch2_btree_iter_verify(iter); bch2_btree_iter_verify(iter);
return b; return b;
err:
b = ERR_PTR(ret);
goto out;
} }
/* Iterate across keys (in leaf nodes only) */ /* Iterate across keys (in leaf nodes only) */
......
...@@ -284,18 +284,18 @@ static inline int bch2_trans_cond_resched(struct btree_trans *trans) ...@@ -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, \ #define __for_each_btree_node(_trans, _iter, _btree_id, _start, \
_locks_want, _depth, _flags, _b) \ _locks_want, _depth, _flags, _b, _ret) \
for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \ for (bch2_trans_node_iter_init((_trans), &(_iter), (_btree_id), \
_start, _locks_want, _depth, _flags), \ _start, _locks_want, _depth, _flags), \
_b = bch2_btree_iter_peek_node(&(_iter)); \ _b = bch2_btree_iter_peek_node(&(_iter)); \
(_b); \ !((_ret) = PTR_ERR_OR_ZERO(_b)) && (_b); \
(_b) = bch2_btree_iter_next_node(&(_iter))) (_b) = bch2_btree_iter_next_node(&(_iter)))
#define for_each_btree_node(_trans, _iter, _btree_id, _start, \ #define for_each_btree_node(_trans, _iter, _btree_id, _start, \
_flags, _b) \ _flags, _b, _ret) \
__for_each_btree_node(_trans, _iter, _btree_id, _start, \ __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, static inline struct bkey_s_c __bch2_btree_iter_peek(struct btree_iter *iter,
unsigned flags) unsigned flags)
......
...@@ -1736,6 +1736,10 @@ int bch2_btree_node_rewrite(struct btree_trans *trans, ...@@ -1736,6 +1736,10 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
goto out; goto out;
b = bch2_btree_iter_peek_node(iter); b = bch2_btree_iter_peek_node(iter);
ret = PTR_ERR_OR_ZERO(b);
if (ret)
goto out;
if (!b || b->data->keys.seq != seq) if (!b || b->data->keys.seq != seq)
goto out; goto out;
......
...@@ -318,7 +318,7 @@ static ssize_t bch2_read_btree_formats(struct file *file, char __user *buf, ...@@ -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); 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); bch2_btree_node_to_text(&PBUF(i->buf), i->c, b);
i->bytes = strlen(i->buf); i->bytes = strlen(i->buf);
err = flush_buf(i); err = flush_buf(i);
......
...@@ -254,7 +254,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work) ...@@ -254,7 +254,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
struct btree *b; struct btree *b;
for_each_btree_node(&trans, iter, i, POS_MIN, 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)) { if (test_bit(BCH_FS_STOPPING, &c->flags)) {
bch2_trans_exit(&trans); bch2_trans_exit(&trans);
return; return;
...@@ -262,7 +262,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work) ...@@ -262,7 +262,7 @@ void bch2_blacklist_entries_gc(struct work_struct *work)
bch2_trans_iter_exit(&trans, &iter); bch2_trans_iter_exit(&trans, &iter);
} }
ret = bch2_trans_exit(&trans); bch2_trans_exit(&trans);
if (ret) if (ret)
return; return;
......
...@@ -135,9 +135,10 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) ...@@ -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++) { for (id = 0; id < BTREE_ID_NR; id++) {
bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0, bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
BTREE_ITER_PREFETCH); BTREE_ITER_PREFETCH);
retry:
while (bch2_trans_begin(&trans), 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), if (!bch2_bkey_has_device(bkey_i_to_s_c(&b->key),
dev_idx)) dev_idx))
goto next; goto next;
...@@ -164,6 +165,9 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags) ...@@ -164,6 +165,9 @@ static int bch2_dev_metadata_drop(struct bch_fs *c, unsigned dev_idx, int flags)
next: next:
bch2_btree_iter_next_node(&iter); bch2_btree_iter_next_node(&iter);
} }
if (ret == -EINTR)
goto retry;
bch2_trans_iter_exit(&trans, &iter); bch2_trans_iter_exit(&trans, &iter);
if (ret) if (ret)
......
...@@ -885,9 +885,10 @@ static int bch2_move_btree(struct bch_fs *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, bch2_trans_node_iter_init(&trans, &iter, id, POS_MIN, 0, 0,
BTREE_ITER_PREFETCH); BTREE_ITER_PREFETCH);
retry:
while (bch2_trans_begin(&trans), 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()) if (kthread && kthread_should_stop())
break; break;
...@@ -915,6 +916,9 @@ static int bch2_move_btree(struct bch_fs *c, ...@@ -915,6 +916,9 @@ static int bch2_move_btree(struct bch_fs *c,
bch2_trans_cond_resched(&trans); bch2_trans_cond_resched(&trans);
bch2_btree_iter_next_node(&iter); bch2_btree_iter_next_node(&iter);
} }
if (ret == -EINTR)
goto retry;
bch2_trans_iter_exit(&trans, &iter); bch2_trans_iter_exit(&trans, &iter);
if (kthread && kthread_should_stop()) if (kthread && kthread_should_stop())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment