Message ID | 9980464fc9f02392f0dab60c5564495c811ed256.1686219923.git.fdmanana@suse.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: some fixes and updates around handling errors for tree mod log operations | expand |
On 2023/6/8 18:27, fdmanana@kernel.org wrote: > From: Filipe Manana <fdmanana@suse.com> > > At update_ref_for_cow() we are calling btrfs_handle_fs_error() if we find > that the extent buffer has an unexpected ref count of zero, however we can > simply use btrfs_abort_transaction(), which achieves the same purposes: to > turn the fs to error state, abort the current transaction and turn the fs > to RO mode as well. Besides that, btrfs_abort_transaction() also prints a > stack trace which makes it more useful. > > Also, as this is a very unexpected situation, indicating a serious > corruption/inconsistency, tag the if branch as 'unlikely', set the error > code to -EUCLEAN instead of -EROFS, and log an explicit message. > > Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: Qu Wenruo <wqu@suse.com> Thanks, Qu > --- > fs/btrfs/ctree.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c > index 00eea2925d1d..0449b3d819a9 100644 > --- a/fs/btrfs/ctree.c > +++ b/fs/btrfs/ctree.c > @@ -421,9 +421,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, > &refs, &flags); > if (ret) > return ret; > - if (refs == 0) { > - ret = -EROFS; > - btrfs_handle_fs_error(fs_info, ret, NULL); > + if (unlikely(refs == 0)) { > + btrfs_crit(fs_info, > + "found 0 references for tree block at bytenr %llu level %d root %llu", > + buf->start, btrfs_header_level(buf), > + btrfs_root_id(root)); > + ret = -EUCLEAN; > + btrfs_abort_transaction(trans, ret); > return ret; > } > } else {
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 00eea2925d1d..0449b3d819a9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -421,9 +421,13 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, &refs, &flags); if (ret) return ret; - if (refs == 0) { - ret = -EROFS; - btrfs_handle_fs_error(fs_info, ret, NULL); + if (unlikely(refs == 0)) { + btrfs_crit(fs_info, + "found 0 references for tree block at bytenr %llu level %d root %llu", + buf->start, btrfs_header_level(buf), + btrfs_root_id(root)); + ret = -EUCLEAN; + btrfs_abort_transaction(trans, ret); return ret; } } else {