From 3db6ec44c5c7c39cb0067a6b02ef22090ecbaa98 Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Wed, 20 Oct 2021 12:33:59 -0400 Subject: Update bcachefs sources to d9d1235f3c bcachefs: Handle transaction restarts in bch2_blacklist_entries_gc() --- .bcachefs_revision | 2 +- cmd_debug.c | 30 +++++++++++++++++++++++++----- libbcachefs/btree_gc.c | 4 ++-- libbcachefs/btree_iter.c | 28 +++++++++++++++------------- libbcachefs/btree_iter.h | 12 ++++++------ libbcachefs/btree_types.h | 1 - libbcachefs/btree_update.h | 6 +++--- libbcachefs/btree_update_interior.c | 4 ++++ libbcachefs/debug.c | 2 +- libbcachefs/dirent.c | 2 +- libbcachefs/ec.c | 5 +++-- libbcachefs/fs-io.c | 7 ++++--- libbcachefs/fs.c | 2 +- libbcachefs/fsck.c | 9 ++++++--- libbcachefs/journal_seq_blacklist.c | 23 ++++++++++++++++------- libbcachefs/migrate.c | 13 +++++++++---- libbcachefs/move.c | 11 ++++++++--- libbcachefs/quota.c | 6 ++++-- libbcachefs/reflink.c | 2 +- libbcachefs/sysfs.c | 2 +- libbcachefs/xattr.c | 2 +- 21 files changed, 112 insertions(+), 61 deletions(-) diff --git a/.bcachefs_revision b/.bcachefs_revision index 7ae58f9..cd1097b 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -720f644e63e0f5b24bb69f2ffb70cdc2dd162810 +d9d1235f3c568a47b3547c0b0adad0d7948f18aa diff --git a/cmd_debug.c b/cmd_debug.c index aee19fb..7cbeb90 100644 --- a/cmd_debug.c +++ b/cmd_debug.c @@ -37,6 +37,7 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd) struct bch_sb *sb = ca->disk_sb.sb; ranges data; unsigned i; + int ret; darray_init(data); @@ -69,7 +70,7 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd) bch2_trans_init(&trans, c, 0, 0); - __for_each_btree_node(&trans, iter, i, POS_MIN, 0, 1, 0, b) { + __for_each_btree_node(&trans, iter, i, POS_MIN, 0, 1, 0, b, ret) { struct btree_node_iter iter; struct bkey u; struct bkey_s_c k; @@ -85,6 +86,9 @@ static void dump_one_device(struct bch_fs *c, struct bch_dev *ca, int fd) } } + if (ret) + die("error %s walking btree nodes", strerror(-ret)); + b = c->btree_roots[i].b; if (!btree_node_fake(b)) { ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(&b->key)); @@ -211,10 +215,11 @@ static void list_btree_formats(struct bch_fs *c, enum btree_id btree_id, unsigne struct btree_iter iter; struct btree *b; char buf[4096]; + int ret; bch2_trans_init(&trans, c, 0, 0); - __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) { + __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) { if (bkey_cmp(b->key.k.p, end) > 0) break; @@ -223,6 +228,9 @@ static void list_btree_formats(struct bch_fs *c, enum btree_id btree_id, unsigne } bch2_trans_iter_exit(&trans, &iter); + if (ret) + die("error %s walking btree nodes", strerror(-ret)); + bch2_trans_exit(&trans); } @@ -233,10 +241,11 @@ static void list_nodes(struct bch_fs *c, enum btree_id btree_id, unsigned level, struct btree_iter iter; struct btree *b; char buf[4096]; + int ret; bch2_trans_init(&trans, c, 0, 0); - __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) { + __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) { if (bkey_cmp(b->key.k.p, end) > 0) break; @@ -246,6 +255,9 @@ static void list_nodes(struct bch_fs *c, enum btree_id btree_id, unsigned level, } bch2_trans_iter_exit(&trans, &iter); + if (ret) + die("error %s walking btree nodes", strerror(-ret)); + bch2_trans_exit(&trans); } @@ -352,10 +364,11 @@ static void list_nodes_ondisk(struct bch_fs *c, enum btree_id btree_id, unsigned struct btree_iter iter; struct btree *b; char buf[4096]; + int ret; bch2_trans_init(&trans, c, 0, 0); - __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) { + __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) { if (bkey_cmp(b->key.k.p, end) > 0) break; @@ -367,6 +380,9 @@ static void list_nodes_ondisk(struct bch_fs *c, enum btree_id btree_id, unsigned } bch2_trans_iter_exit(&trans, &iter); + if (ret) + die("error %s walking btree nodes", strerror(-ret)); + bch2_trans_exit(&trans); } @@ -380,10 +396,11 @@ static void list_nodes_keys(struct bch_fs *c, enum btree_id btree_id, unsigned l struct bkey_s_c k; struct btree *b; char buf[4096]; + int ret; bch2_trans_init(&trans, c, 0, 0); - __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b) { + __for_each_btree_node(&trans, iter, btree_id, start, 0, level, 0, b, ret) { if (bkey_cmp(b->key.k.p, end) > 0) break; @@ -398,6 +415,9 @@ static void list_nodes_keys(struct bch_fs *c, enum btree_id btree_id, unsigned l } bch2_trans_iter_exit(&trans, &iter); + if (ret) + die("error %s walking btree nodes", strerror(-ret)); + bch2_trans_exit(&trans); } diff --git a/libbcachefs/btree_gc.c b/libbcachefs/btree_gc.c index 8f6e73b..dcbde49 100644 --- a/libbcachefs/btree_gc.c +++ b/libbcachefs/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/libbcachefs/btree_iter.c b/libbcachefs/btree_iter.c index 14fb1ad..343587e 100644 --- a/libbcachefs/btree_iter.c +++ b/libbcachefs/btree_iter.c @@ -1341,10 +1341,8 @@ retry_all: } while (ret); } - if (unlikely(ret == -EIO)) { - trans->error = true; + if (unlikely(ret == -EIO)) goto out; - } BUG_ON(ret && ret != -EINTR); @@ -1891,7 +1889,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) @@ -1911,6 +1909,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) @@ -1927,7 +1928,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; @@ -1936,7 +1939,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); @@ -1960,10 +1963,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; } @@ -1980,6 +1981,9 @@ out: bch2_btree_iter_verify(iter); return b; +err: + b = ERR_PTR(ret); + goto out; } /* Iterate across keys (in leaf nodes only) */ @@ -2727,7 +2731,7 @@ leaked: #endif } -int bch2_trans_exit(struct btree_trans *trans) +void bch2_trans_exit(struct btree_trans *trans) __releases(&c->btree_trans_barrier) { struct btree_insert_entry *i; @@ -2777,8 +2781,6 @@ int bch2_trans_exit(struct btree_trans *trans) trans->mem = (void *) 0x1; trans->paths = (void *) 0x1; - - return trans->error ? -EIO : 0; } static void __maybe_unused diff --git a/libbcachefs/btree_iter.h b/libbcachefs/btree_iter.h index 19ca73f..72aff95 100644 --- a/libbcachefs/btree_iter.h +++ b/libbcachefs/btree_iter.h @@ -258,18 +258,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) @@ -325,7 +325,7 @@ static inline void set_btree_iter_dontneed(struct btree_iter *iter) void *bch2_trans_kmalloc(struct btree_trans *, size_t); void bch2_trans_begin(struct btree_trans *); void bch2_trans_init(struct btree_trans *, struct bch_fs *, unsigned, size_t); -int bch2_trans_exit(struct btree_trans *); +void bch2_trans_exit(struct btree_trans *); void bch2_btree_trans_to_text(struct printbuf *, struct bch_fs *); diff --git a/libbcachefs/btree_types.h b/libbcachefs/btree_types.h index 7fcd2ce..26aa3cd 100644 --- a/libbcachefs/btree_types.h +++ b/libbcachefs/btree_types.h @@ -377,7 +377,6 @@ struct btree_trans { u8 nr_sorted; u8 nr_updates; bool used_mempool:1; - bool error:1; bool in_traverse_all:1; bool restarted:1; /* diff --git a/libbcachefs/btree_update.h b/libbcachefs/btree_update.h index 4d0ece3..155643d 100644 --- a/libbcachefs/btree_update.h +++ b/libbcachefs/btree_update.h @@ -120,14 +120,14 @@ static inline int bch2_trans_commit(struct btree_trans *trans, #define bch2_trans_do(_c, _disk_res, _journal_seq, _flags, _do) \ ({ \ struct btree_trans trans; \ - int _ret, _ret2; \ + int _ret; \ \ bch2_trans_init(&trans, (_c), 0, 0); \ _ret = __bch2_trans_do(&trans, _disk_res, _journal_seq, _flags, \ _do); \ - _ret2 = bch2_trans_exit(&trans); \ + bch2_trans_exit(&trans); \ \ - _ret ?: _ret2; \ + _ret; \ }) #define trans_for_each_update(_trans, _i) \ diff --git a/libbcachefs/btree_update_interior.c b/libbcachefs/btree_update_interior.c index 98c05bb..591a2fe 100644 --- a/libbcachefs/btree_update_interior.c +++ b/libbcachefs/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/libbcachefs/debug.c b/libbcachefs/debug.c index 9f14bf4..294e4ba 100644 --- a/libbcachefs/debug.c +++ b/libbcachefs/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/libbcachefs/dirent.c b/libbcachefs/dirent.c index cd5468b..26df20a 100644 --- a/libbcachefs/dirent.c +++ b/libbcachefs/dirent.c @@ -491,7 +491,7 @@ err: if (ret == -EINTR) goto retry; - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); return ret; } diff --git a/libbcachefs/ec.c b/libbcachefs/ec.c index f0bdbdb..9f87e2b 100644 --- a/libbcachefs/ec.c +++ b/libbcachefs/ec.c @@ -1670,11 +1670,12 @@ int bch2_ec_mem_alloc(struct bch_fs *c, bool gc) bch2_trans_iter_init(&trans, &iter, BTREE_ID_stripes, POS(0, U64_MAX), 0); k = bch2_btree_iter_prev(&iter); - if (!IS_ERR_OR_NULL(k.k)) + ret = bkey_err(k); + if (!ret && k.k) idx = k.k->p.offset + 1; bch2_trans_iter_exit(&trans, &iter); - ret = bch2_trans_exit(&trans); + bch2_trans_exit(&trans); if (ret) return ret; diff --git a/libbcachefs/fs-io.c b/libbcachefs/fs-io.c index c07755c..900a0c3 100644 --- a/libbcachefs/fs-io.c +++ b/libbcachefs/fs-io.c @@ -2228,7 +2228,8 @@ err: if (ret == -EINTR) goto retry; - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } static int __bch2_truncate_page(struct bch_inode_info *inode, @@ -3132,7 +3133,7 @@ err: if (ret == -EINTR) goto retry; - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); if (ret) return ret; @@ -3247,7 +3248,7 @@ err: if (ret == -EINTR) goto retry; - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); if (ret) return ret; diff --git a/libbcachefs/fs.c b/libbcachefs/fs.c index 2094c18..45a2af3 100644 --- a/libbcachefs/fs.c +++ b/libbcachefs/fs.c @@ -1014,7 +1014,7 @@ err: ret = bch2_fill_extent(c, info, bkey_i_to_s_c(prev.k), FIEMAP_EXTENT_LAST); - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); bch2_bkey_buf_exit(&cur, c); bch2_bkey_buf_exit(&prev, c); return ret < 0 ? ret : 0; diff --git a/libbcachefs/fsck.c b/libbcachefs/fsck.c index 826a357..a36bc84 100644 --- a/libbcachefs/fsck.c +++ b/libbcachefs/fsck.c @@ -981,7 +981,8 @@ static int check_inodes(struct bch_fs *c, bool full) BUG_ON(ret == -EINTR); - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } noinline_for_stack @@ -1659,7 +1660,8 @@ fsck_err: goto retry; bch2_trans_iter_exit(&trans, &iter); - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } /* Get root directory, create if it doesn't exist: */ @@ -1876,7 +1878,8 @@ static int check_directory_structure(struct bch_fs *c) kfree(path.entries); - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } struct nlink_table { diff --git a/libbcachefs/journal_seq_blacklist.c b/libbcachefs/journal_seq_blacklist.c index 68fb2eb..79bc0e4 100644 --- a/libbcachefs/journal_seq_blacklist.c +++ b/libbcachefs/journal_seq_blacklist.c @@ -253,16 +253,25 @@ void bch2_blacklist_entries_gc(struct work_struct *work) struct btree_iter iter; struct btree *b; - for_each_btree_node(&trans, iter, i, POS_MIN, - BTREE_ITER_PREFETCH, b) - if (test_bit(BCH_FS_STOPPING, &c->flags)) { - bch2_trans_exit(&trans); - return; - } + bch2_trans_node_iter_init(&trans, &iter, i, POS_MIN, + 0, 0, BTREE_ITER_PREFETCH); +retry: + bch2_trans_begin(&trans); + + b = bch2_btree_iter_peek_node(&iter); + + while (!(ret = PTR_ERR_OR_ZERO(b)) && + b && + !test_bit(BCH_FS_STOPPING, &c->flags)) + b = bch2_btree_iter_next_node(&iter); + + if (ret == -EINTR) + goto retry; + bch2_trans_iter_exit(&trans, &iter); } - ret = bch2_trans_exit(&trans); + bch2_trans_exit(&trans); if (ret) return; diff --git a/libbcachefs/migrate.c b/libbcachefs/migrate.c index 94d5d99..6defc33 100644 --- a/libbcachefs/migrate.c +++ b/libbcachefs/migrate.c @@ -100,7 +100,7 @@ static int __bch2_dev_usrdata_drop(struct bch_fs *c, unsigned dev_idx, int flags } bch2_trans_iter_exit(&trans, &iter); - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); bch2_bkey_buf_exit(&sk, c); BUG_ON(ret == -EINTR); @@ -135,9 +135,11 @@ 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: + ret = 0; 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 +166,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) @@ -176,7 +181,7 @@ next: ret = 0; err: - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); bch2_bkey_buf_exit(&k, c); BUG_ON(ret == -EINTR); diff --git a/libbcachefs/move.c b/libbcachefs/move.c index 790389d..2039682 100644 --- a/libbcachefs/move.c +++ b/libbcachefs/move.c @@ -773,7 +773,7 @@ next_nondata: out: bch2_trans_iter_exit(&trans, &iter); - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); bch2_bkey_buf_exit(&sk, c); return ret; @@ -885,9 +885,11 @@ 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: + ret = 0; 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 +917,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()) diff --git a/libbcachefs/quota.c b/libbcachefs/quota.c index 9b0f4d3..17fd5bf 100644 --- a/libbcachefs/quota.c +++ b/libbcachefs/quota.c @@ -374,7 +374,8 @@ static int bch2_quota_init_type(struct bch_fs *c, enum quota_types type) } bch2_trans_iter_exit(&trans, &iter); - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } void bch2_fs_quota_exit(struct bch_fs *c) @@ -452,7 +453,8 @@ int bch2_fs_quota_read(struct bch_fs *c) } bch2_trans_iter_exit(&trans, &iter); - return bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); + return ret; } /* Enable/disable/delete quotas for an entire filesystem: */ diff --git a/libbcachefs/reflink.c b/libbcachefs/reflink.c index c63c95f..9bcf421 100644 --- a/libbcachefs/reflink.c +++ b/libbcachefs/reflink.c @@ -349,7 +349,7 @@ s64 bch2_remap_range(struct bch_fs *c, bch2_trans_iter_exit(&trans, &inode_iter); } while (ret2 == -EINTR); - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); bch2_bkey_buf_exit(&new_src, c); bch2_bkey_buf_exit(&new_dst, c); diff --git a/libbcachefs/sysfs.c b/libbcachefs/sysfs.c index 92e58f5..51eb19b 100644 --- a/libbcachefs/sysfs.c +++ b/libbcachefs/sysfs.c @@ -327,7 +327,7 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c } bch2_trans_iter_exit(&trans, &iter); - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); if (ret) return ret; diff --git a/libbcachefs/xattr.c b/libbcachefs/xattr.c index a182e24..fe572b2 100644 --- a/libbcachefs/xattr.c +++ b/libbcachefs/xattr.c @@ -316,7 +316,7 @@ err: if (ret == -EINTR) goto retry; - ret = bch2_trans_exit(&trans) ?: ret; + bch2_trans_exit(&trans); if (ret) return ret; -- cgit v1.2.3