Commit 50471a38 authored by Miao Xie's avatar Miao Xie Committed by Josef Bacik

Btrfs: stop joining the log transaction if sync log fails

If the log sync fails, there is something wrong in the log tree, we
should not continue to join the log transaction and log the metadata.
What we should do is to do a full commit.

This patch fixes this problem by setting ->last_trans_log_full_commit
to the current transaction id, it will tell the tasks not to join
the log transaction, and do a full commit.
Signed-off-by: default avatarMiao Xie <miaox@cn.fujitsu.com>
Signed-off-by: default avatarJosef Bacik <jbacik@fb.com>
parent d1433deb
...@@ -144,6 +144,12 @@ static int start_log_trans(struct btrfs_trans_handle *trans, ...@@ -144,6 +144,12 @@ static int start_log_trans(struct btrfs_trans_handle *trans,
mutex_lock(&root->log_mutex); mutex_lock(&root->log_mutex);
if (root->log_root) { if (root->log_root) {
if (ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) ==
trans->transid) {
ret = -EAGAIN;
goto out;
}
if (!root->log_start_pid) { if (!root->log_start_pid) {
root->log_start_pid = current->pid; root->log_start_pid = current->pid;
root->log_multiple_pids = false; root->log_multiple_pids = false;
...@@ -2527,6 +2533,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2527,6 +2533,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
blk_finish_plug(&plug); blk_finish_plug(&plug);
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
trans->transid;
mutex_unlock(&root->log_mutex); mutex_unlock(&root->log_mutex);
goto out; goto out;
} }
...@@ -2569,13 +2577,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2569,13 +2577,13 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
list_del_init(&root_log_ctx.list); list_del_init(&root_log_ctx.list);
blk_finish_plug(&plug); blk_finish_plug(&plug);
ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
trans->transid;
if (ret != -ENOSPC) { if (ret != -ENOSPC) {
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
goto out; goto out;
} }
ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
trans->transid;
btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
...@@ -2629,6 +2637,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2629,6 +2637,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
EXTENT_DIRTY | EXTENT_NEW); EXTENT_DIRTY | EXTENT_NEW);
blk_finish_plug(&plug); blk_finish_plug(&plug);
if (ret) { if (ret) {
ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
trans->transid;
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
btrfs_free_logged_extents(log, log_transid); btrfs_free_logged_extents(log, log_transid);
mutex_unlock(&log_root_tree->log_mutex); mutex_unlock(&log_root_tree->log_mutex);
...@@ -2657,6 +2667,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2657,6 +2667,8 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
*/ */
ret = write_ctree_super(trans, root->fs_info->tree_root, 1); ret = write_ctree_super(trans, root->fs_info->tree_root, 1);
if (ret) { if (ret) {
ACCESS_ONCE(root->fs_info->last_trans_log_full_commit) =
trans->transid;
btrfs_abort_transaction(trans, root, ret); btrfs_abort_transaction(trans, root, ret);
goto out_wake_log_root; goto out_wake_log_root;
} }
......
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