Commit ba51e2a1 authored by Josef Bacik's avatar Josef Bacik Committed by David Sterba

btrfs: change handle_fs_error in recover_log_trees to aborts

During inspection of the return path for replay I noticed that we don't
actually abort the transaction if we get a failure during replay.  This
isn't a problem necessarily, as we properly return the error and will
fail to mount.  However we still leave this dangling transaction that
could conceivably be committed without thinking there was an error.

We were using btrfs_handle_fs_error() here, but that pre-dates the
transaction abort code.  Simply replace the btrfs_handle_fs_error()
calls with transaction aborts, so we still know where exactly things
went wrong, and add a few in some other un-handled error cases.
Reviewed-by: default avatarNikolay Borisov <nborisov@suse.com>
Reviewed-by: default avatarJohannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 64259baa
...@@ -6548,8 +6548,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6548,8 +6548,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
ret = walk_log_tree(trans, log_root_tree, &wc); ret = walk_log_tree(trans, log_root_tree, &wc);
if (ret) { if (ret) {
btrfs_handle_fs_error(fs_info, ret, btrfs_abort_transaction(trans, ret);
"Failed to pin buffers while recovering log root tree.");
goto error; goto error;
} }
...@@ -6562,8 +6561,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6562,8 +6561,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0); ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
if (ret < 0) { if (ret < 0) {
btrfs_handle_fs_error(fs_info, ret, btrfs_abort_transaction(trans, ret);
"Couldn't find tree log root.");
goto error; goto error;
} }
if (ret > 0) { if (ret > 0) {
...@@ -6580,8 +6578,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6580,8 +6578,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
log = btrfs_read_tree_root(log_root_tree, &found_key); log = btrfs_read_tree_root(log_root_tree, &found_key);
if (IS_ERR(log)) { if (IS_ERR(log)) {
ret = PTR_ERR(log); ret = PTR_ERR(log);
btrfs_handle_fs_error(fs_info, ret, btrfs_abort_transaction(trans, ret);
"Couldn't read tree log root.");
goto error; goto error;
} }
...@@ -6609,8 +6606,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6609,8 +6606,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
if (!ret) if (!ret)
goto next; goto next;
btrfs_handle_fs_error(fs_info, ret, btrfs_abort_transaction(trans, ret);
"Couldn't read target root for tree log recovery.");
goto error; goto error;
} }
...@@ -6618,14 +6614,15 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6618,14 +6614,15 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
ret = btrfs_record_root_in_trans(trans, wc.replay_dest); ret = btrfs_record_root_in_trans(trans, wc.replay_dest);
if (ret) if (ret)
/* The loop needs to continue due to the root refs */ /* The loop needs to continue due to the root refs */
btrfs_handle_fs_error(fs_info, ret, btrfs_abort_transaction(trans, ret);
"failed to record the log root in transaction");
else else
ret = walk_log_tree(trans, log, &wc); ret = walk_log_tree(trans, log, &wc);
if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) { if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
ret = fixup_inode_link_counts(trans, wc.replay_dest, ret = fixup_inode_link_counts(trans, wc.replay_dest,
path); path);
if (ret)
btrfs_abort_transaction(trans, ret);
} }
if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) { if (!ret && wc.stage == LOG_WALK_REPLAY_ALL) {
...@@ -6642,6 +6639,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree) ...@@ -6642,6 +6639,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
* could only happen during mount. * could only happen during mount.
*/ */
ret = btrfs_init_root_free_objectid(root); ret = btrfs_init_root_free_objectid(root);
if (ret)
btrfs_abort_transaction(trans, ret);
} }
wc.replay_dest->log_root = NULL; wc.replay_dest->log_root = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment