diff options
-rw-r--r-- | fs/bcachefs/alloc_background.c | 5 | ||||
-rw-r--r-- | fs/bcachefs/btree_trans_commit.c | 10 | ||||
-rw-r--r-- | fs/bcachefs/btree_types.h | 12 | ||||
-rw-r--r-- | fs/bcachefs/dirent.c | 6 | ||||
-rw-r--r-- | fs/bcachefs/fsck.c | 11 | ||||
-rw-r--r-- | fs/bcachefs/journal.c | 3 | ||||
-rw-r--r-- | fs/bcachefs/snapshot.c | 5 |
7 files changed, 34 insertions, 18 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c index afc0ab75abf6..55c21e9b4c52 100644 --- a/fs/bcachefs/alloc_background.c +++ b/fs/bcachefs/alloc_background.c @@ -1554,6 +1554,9 @@ int bch2_check_alloc_info(struct bch_fs *c) struct bkey_s_c k; int ret = 0; + struct progress_indicator_state progress; + bch2_progress_init(&progress, c, BIT_ULL(BTREE_ID_alloc)); + CLASS(btree_trans, trans)(c); bch2_trans_iter_init(trans, &iter, BTREE_ID_alloc, POS_MIN, BTREE_ITER_prefetch); @@ -1577,6 +1580,8 @@ int bch2_check_alloc_info(struct bch_fs *c) if (!k.k) break; + progress_update_iter(trans, &progress, &iter); + if (k.k->type) { next = bpos_nosnap_successor(k.k->p); diff --git a/fs/bcachefs/btree_trans_commit.c b/fs/bcachefs/btree_trans_commit.c index 58590ccc26bd..8b94a8156fbf 100644 --- a/fs/bcachefs/btree_trans_commit.c +++ b/fs/bcachefs/btree_trans_commit.c @@ -969,7 +969,7 @@ do_bch2_trans_commit_to_journal_replay(struct btree_trans *trans, BUG_ON(current != c->recovery_task); struct bkey_i *accounting; - +retry: percpu_down_read(&c->mark_lock); for (accounting = btree_trans_subbuf_base(trans, &trans->accounting); accounting != btree_trans_subbuf_top(trans, &trans->accounting); @@ -1025,13 +1025,17 @@ fatal_err: bch2_fs_fatal_error(c, "fatal error in transaction commit: %s", bch2_err_str(ret)); percpu_down_read(&c->mark_lock); revert_fs_usage: - BUG(); - /* error path not handled by __bch2_trans_commit() */ for (struct bkey_i *i = btree_trans_subbuf_base(trans, &trans->accounting); i != accounting; i = bkey_next(i)) bch2_accounting_trans_commit_revert(trans, bkey_i_to_accounting(i), flags); percpu_up_read(&c->mark_lock); + + if (bch2_err_matches(ret, BCH_ERR_btree_insert_need_mark_replicas)) { + ret = drop_locks_do(trans, bch2_accounting_update_sb(trans)); + if (!ret) + goto retry; + } return ret; } diff --git a/fs/bcachefs/btree_types.h b/fs/bcachefs/btree_types.h index 76adf75617aa..e6177b747216 100644 --- a/fs/bcachefs/btree_types.h +++ b/fs/bcachefs/btree_types.h @@ -854,15 +854,15 @@ static inline bool btree_node_type_is_extents(enum btree_node_type type) return type != BKEY_TYPE_btree && btree_id_is_extents(type - 1); } -static inline bool btree_type_has_snapshots(enum btree_id btree) -{ - const u64 mask = 0 +static const u64 btree_has_snapshots_mask = 0 #define x(name, nr, flags, ...) |((!!((flags) & BTREE_IS_snapshots)) << nr) - BCH_BTREE_IDS() +BCH_BTREE_IDS() #undef x - ; +; - return BIT_ULL(btree) & mask; +static inline bool btree_type_has_snapshots(enum btree_id btree) +{ + return BIT_ULL(btree) & btree_has_snapshots_mask; } static inline bool btree_type_has_snapshot_field(enum btree_id btree) diff --git a/fs/bcachefs/dirent.c b/fs/bcachefs/dirent.c index dd60c47528da..1b891ac43053 100644 --- a/fs/bcachefs/dirent.c +++ b/fs/bcachefs/dirent.c @@ -214,11 +214,13 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k); struct qstr d_name = bch2_dirent_get_name(d); - prt_printf(out, "%.*s", d_name.len, d_name.name); + prt_bytes(out, d_name.name, d_name.len); if (d.v->d_casefold) { + prt_str(out, " (casefold "); struct qstr d_name = bch2_dirent_get_lookup_name(d); - prt_printf(out, " (casefold %.*s)", d_name.len, d_name.name); + prt_bytes(out, d_name.name, d_name.len); + prt_char(out, ')'); } prt_str(out, " ->"); diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 40fc3c4e3c43..f5a9da40c647 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1972,11 +1972,12 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, "extent type past end of inode %llu:%u, i_size %llu\n%s", i->inode.bi_inum, i->inode.bi_snapshot, i->inode.bi_size, (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) { - ret = bch2_fpunch_snapshot(trans, - SPOS(i->inode.bi_inum, - last_block, - i->inode.bi_snapshot), - POS(i->inode.bi_inum, U64_MAX)); + ret = snapshots_seen_add_inorder(c, s, i->inode.bi_snapshot) ?: + bch2_fpunch_snapshot(trans, + SPOS(i->inode.bi_inum, + last_block, + i->inode.bi_snapshot), + POS(i->inode.bi_inum, U64_MAX)); if (ret) goto err; diff --git a/fs/bcachefs/journal.c b/fs/bcachefs/journal.c index f9e2e1a4e415..a4f43c550ad7 100644 --- a/fs/bcachefs/journal.c +++ b/fs/bcachefs/journal.c @@ -1060,14 +1060,13 @@ static struct journal_buf *__bch2_next_write_buffer_flush_journal_buf(struct jou if (open && !*blocked) { __bch2_journal_block(j); + s.v = atomic64_read_acquire(&j->reservations.counter); *blocked = true; } ret = journal_state_count(s, idx & JOURNAL_STATE_BUF_MASK) > open ? ERR_PTR(-EAGAIN) : buf; - if (!IS_ERR(ret)) - smp_mb(); break; } } diff --git a/fs/bcachefs/snapshot.c b/fs/bcachefs/snapshot.c index af3fae33b5ba..c1419afe4239 100644 --- a/fs/bcachefs/snapshot.c +++ b/fs/bcachefs/snapshot.c @@ -11,6 +11,7 @@ #include "errcode.h" #include "error.h" #include "fs.h" +#include "progress.h" #include "recovery_passes.h" #include "snapshot.h" @@ -973,12 +974,16 @@ int bch2_reconstruct_snapshots(struct bch_fs *c) struct snapshot_tree_reconstruct r = {}; int ret = 0; + struct progress_indicator_state progress; + bch2_progress_init(&progress, c, btree_has_snapshots_mask); + for (unsigned btree = 0; btree < BTREE_ID_NR; btree++) { if (btree_type_has_snapshots(btree)) { r.btree = btree; ret = for_each_btree_key(trans, iter, btree, POS_MIN, BTREE_ITER_all_snapshots|BTREE_ITER_prefetch, k, ({ + progress_update_iter(trans, &progress, &iter); get_snapshot_trees(c, &r, k.k->p); })); if (ret) |