From: Kent Overstreet Date: Wed, 6 Apr 2022 18:35:10 +0000 (-0400) Subject: bcachefs: fsck: Work around transaction restarts X-Git-Tag: v6.7-rc1~201^2~1005 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=292dea86dfc974e96a4b4972f4268611c2470d28;p=thirdparty%2Fkernel%2Flinux.git bcachefs: fsck: Work around transaction restarts In check_extents() and check_dirents(), we're working towards only handling transaction restarts in one place, at the top level - but we're not there yet. check_i_sectors() and check_subdir_count() handle transaction restarts locally, which means the iterator for the dirent/extent is left unlocked (should_be_locked == 0), leading to asserts popping when we go to do updates. This patch hacks around this for now, until we can delete the offending code. Signed-off-by: Kent Overstreet --- diff --git a/fs/bcachefs/fsck.c b/fs/bcachefs/fsck.c index 10754b13ec15f..6a89b0694e500 100644 --- a/fs/bcachefs/fsck.c +++ b/fs/bcachefs/fsck.c @@ -1146,7 +1146,7 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, struct inode_walker_entry *i; struct printbuf buf = PRINTBUF; int ret = 0; - +peek: k = bch2_btree_iter_peek(iter); if (!k.k) goto out; @@ -1173,6 +1173,15 @@ static int check_extent(struct btree_trans *trans, struct btree_iter *iter, if (ret) goto err; } + + if (!iter->path->should_be_locked) { + /* + * hack: check_i_sectors may have handled a transaction restart, + * it shouldn't be but we need to fix the new i_sectors check + * code and delete the old bch2_count_inode_sectors() first + */ + goto peek; + } #if 0 if (bkey_cmp(prev.k->k.p, bkey_start_pos(k.k)) > 0) { char buf1[200]; @@ -1464,7 +1473,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, struct inode_walker_entry *i; struct printbuf buf = PRINTBUF; int ret = 0; - +peek: k = bch2_btree_iter_peek(iter); if (!k.k) goto out; @@ -1492,6 +1501,11 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter, goto err; } + if (!iter->path->should_be_locked) { + /* hack: see check_extent() */ + goto peek; + } + ret = __walk_inode(trans, dir, k.k->p); if (ret < 0) goto err;