From d355c6f4f73060c8f3eba95b9ae72929669f7516 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Tue, 19 Oct 2021 14:20:50 -0400 Subject: [PATCH] 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 --- fs/bcachefs/btree_gc.c | 4 ++-- fs/bcachefs/btree_iter.c | 20 +++++++++++++------- fs/bcachefs/btree_iter.h | 10 +++++----- fs/bcachefs/btree_update_interior.c | 4 ++++ fs/bcachefs/debug.c | 2 +- fs/bcachefs/journal_seq_blacklist.c | 4 ++-- fs/bcachefs/migrate.c | 8 ++++++-- fs/bcachefs/move.c | 8 ++++++-- 8 files changed, 39 insertions(+), 21 deletions(-) diff --git a/fs/bcachefs/btree_gc.c b/fs/bcachefs/btree_gc.c index ea3f7339ba585..315a78b5ba8ba 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 dd0cd4aecc942..339b3657683a5 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 @@ out: 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 @@ out: 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 feb2fcff14854..1cb4261bd66e6 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 4ca2de360b226..14ecd3f863de5 100644 --- a/fs/bcachefs/btree_update_interior.c +++ b/fs/bcachefs/btree_update_interior.c @@ -1736,6 +1736,10 @@ retry: 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 5ffb7f0a3bf6a..8b25ef9e1e05a 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 68fb2ebd91ac1..f84a63ac15af9 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 94d5d99ffd2a4..111a41159eb2c 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 0db0ce503cd5a..2f608631cc439 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 @@ next: 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()) -- 2.30.2