Commit ded980eb authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

btrfs: add and use helper to commit the current transaction

We have several places that attach to the current transaction with
btrfs_attach_transaction_barrier() and then commit the transaction if
there is one. Add a helper and use it to deduplicate this pattern.
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 1f8aee29
...@@ -4144,9 +4144,6 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, ...@@ -4144,9 +4144,6 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info,
int btrfs_commit_super(struct btrfs_fs_info *fs_info) int btrfs_commit_super(struct btrfs_fs_info *fs_info)
{ {
struct btrfs_root *root = fs_info->tree_root;
struct btrfs_trans_handle *trans;
mutex_lock(&fs_info->cleaner_mutex); mutex_lock(&fs_info->cleaner_mutex);
btrfs_run_delayed_iputs(fs_info); btrfs_run_delayed_iputs(fs_info);
mutex_unlock(&fs_info->cleaner_mutex); mutex_unlock(&fs_info->cleaner_mutex);
...@@ -4156,14 +4153,7 @@ int btrfs_commit_super(struct btrfs_fs_info *fs_info) ...@@ -4156,14 +4153,7 @@ int btrfs_commit_super(struct btrfs_fs_info *fs_info)
down_write(&fs_info->cleanup_work_sem); down_write(&fs_info->cleanup_work_sem);
up_write(&fs_info->cleanup_work_sem); up_write(&fs_info->cleanup_work_sem);
trans = btrfs_attach_transaction_barrier(root); return btrfs_commit_current_transaction(fs_info->tree_root);
if (IS_ERR(trans)) {
int ret = PTR_ERR(trans);
return (ret == -ENOENT) ? 0 : ret;
}
return btrfs_commit_transaction(trans);
} }
static void warn_about_uncommitted_trans(struct btrfs_fs_info *fs_info) static void warn_about_uncommitted_trans(struct btrfs_fs_info *fs_info)
......
...@@ -1334,7 +1334,6 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info, ...@@ -1334,7 +1334,6 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info,
*/ */
static int flush_reservations(struct btrfs_fs_info *fs_info) static int flush_reservations(struct btrfs_fs_info *fs_info)
{ {
struct btrfs_trans_handle *trans;
int ret; int ret;
ret = btrfs_start_delalloc_roots(fs_info, LONG_MAX, false); ret = btrfs_start_delalloc_roots(fs_info, LONG_MAX, false);
...@@ -1342,13 +1341,7 @@ static int flush_reservations(struct btrfs_fs_info *fs_info) ...@@ -1342,13 +1341,7 @@ static int flush_reservations(struct btrfs_fs_info *fs_info)
return ret; return ret;
btrfs_wait_ordered_roots(fs_info, U64_MAX, NULL); btrfs_wait_ordered_roots(fs_info, U64_MAX, NULL);
trans = btrfs_attach_transaction_barrier(fs_info->tree_root); return btrfs_commit_current_transaction(fs_info->tree_root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
return (ret == -ENOENT) ? 0 : ret;
}
return btrfs_commit_transaction(trans);
} }
int btrfs_quota_disable(struct btrfs_fs_info *fs_info) int btrfs_quota_disable(struct btrfs_fs_info *fs_info)
...@@ -4027,7 +4020,6 @@ int ...@@ -4027,7 +4020,6 @@ int
btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info) btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
{ {
int ret = 0; int ret = 0;
struct btrfs_trans_handle *trans;
ret = qgroup_rescan_init(fs_info, 0, 1); ret = qgroup_rescan_init(fs_info, 0, 1);
if (ret) if (ret)
...@@ -4044,16 +4036,10 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info) ...@@ -4044,16 +4036,10 @@ btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info)
* going to clear all tracking information for a clean start. * going to clear all tracking information for a clean start.
*/ */
trans = btrfs_attach_transaction_barrier(fs_info->fs_root); ret = btrfs_commit_current_transaction(fs_info->fs_root);
if (IS_ERR(trans) && trans != ERR_PTR(-ENOENT)) { if (ret) {
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN; fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
return PTR_ERR(trans); return ret;
} else if (trans != ERR_PTR(-ENOENT)) {
ret = btrfs_commit_transaction(trans);
if (ret) {
fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN;
return ret;
}
} }
qgroup_rescan_zero_tracking(fs_info); qgroup_rescan_zero_tracking(fs_info);
...@@ -4189,7 +4175,6 @@ static int qgroup_unreserve_range(struct btrfs_inode *inode, ...@@ -4189,7 +4175,6 @@ static int qgroup_unreserve_range(struct btrfs_inode *inode,
*/ */
static int try_flush_qgroup(struct btrfs_root *root) static int try_flush_qgroup(struct btrfs_root *root)
{ {
struct btrfs_trans_handle *trans;
int ret; int ret;
/* Can't hold an open transaction or we run the risk of deadlocking. */ /* Can't hold an open transaction or we run the risk of deadlocking. */
...@@ -4212,15 +4197,7 @@ static int try_flush_qgroup(struct btrfs_root *root) ...@@ -4212,15 +4197,7 @@ static int try_flush_qgroup(struct btrfs_root *root)
goto out; goto out;
btrfs_wait_ordered_extents(root, U64_MAX, NULL); btrfs_wait_ordered_extents(root, U64_MAX, NULL);
trans = btrfs_attach_transaction_barrier(root); ret = btrfs_commit_current_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
if (ret == -ENOENT)
ret = 0;
goto out;
}
ret = btrfs_commit_transaction(trans);
out: out:
clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state); clear_bit(BTRFS_ROOT_QGROUP_FLUSHING, &root->state);
wake_up(&root->qgroup_flush_wait); wake_up(&root->qgroup_flush_wait);
......
...@@ -2441,7 +2441,6 @@ static int finish_extent_writes_for_zoned(struct btrfs_root *root, ...@@ -2441,7 +2441,6 @@ static int finish_extent_writes_for_zoned(struct btrfs_root *root,
struct btrfs_block_group *cache) struct btrfs_block_group *cache)
{ {
struct btrfs_fs_info *fs_info = cache->fs_info; struct btrfs_fs_info *fs_info = cache->fs_info;
struct btrfs_trans_handle *trans;
if (!btrfs_is_zoned(fs_info)) if (!btrfs_is_zoned(fs_info))
return 0; return 0;
...@@ -2450,14 +2449,7 @@ static int finish_extent_writes_for_zoned(struct btrfs_root *root, ...@@ -2450,14 +2449,7 @@ static int finish_extent_writes_for_zoned(struct btrfs_root *root,
btrfs_wait_nocow_writers(cache); btrfs_wait_nocow_writers(cache);
btrfs_wait_ordered_roots(fs_info, U64_MAX, cache); btrfs_wait_ordered_roots(fs_info, U64_MAX, cache);
trans = btrfs_attach_transaction_barrier(root); return btrfs_commit_current_transaction(root);
if (IS_ERR(trans)) {
int ret = PTR_ERR(trans);
return (ret == -ENOENT) ? 0 : ret;
}
return btrfs_commit_transaction(trans);
} }
static noinline_for_stack static noinline_for_stack
......
...@@ -7998,7 +7998,6 @@ static int send_subvol(struct send_ctx *sctx) ...@@ -7998,7 +7998,6 @@ static int send_subvol(struct send_ctx *sctx)
*/ */
static int ensure_commit_roots_uptodate(struct send_ctx *sctx) static int ensure_commit_roots_uptodate(struct send_ctx *sctx)
{ {
struct btrfs_trans_handle *trans;
struct btrfs_root *root = sctx->parent_root; struct btrfs_root *root = sctx->parent_root;
if (root && root->node != root->commit_root) if (root && root->node != root->commit_root)
...@@ -8018,14 +8017,7 @@ static int ensure_commit_roots_uptodate(struct send_ctx *sctx) ...@@ -8018,14 +8017,7 @@ static int ensure_commit_roots_uptodate(struct send_ctx *sctx)
* an unnecessary update of the root's item in the root tree when * an unnecessary update of the root's item in the root tree when
* committing the transaction if that root wasn't changed before. * committing the transaction if that root wasn't changed before.
*/ */
trans = btrfs_attach_transaction_barrier(root); return btrfs_commit_current_transaction(root);
if (IS_ERR(trans)) {
int ret = PTR_ERR(trans);
return (ret == -ENOENT) ? 0 : ret;
}
return btrfs_commit_transaction(trans);
} }
/* /*
......
...@@ -823,14 +823,7 @@ static void flush_space(struct btrfs_fs_info *fs_info, ...@@ -823,14 +823,7 @@ static void flush_space(struct btrfs_fs_info *fs_info,
* because that does not wait for a transaction to fully commit * because that does not wait for a transaction to fully commit
* (only for it to be unblocked, state TRANS_STATE_UNBLOCKED). * (only for it to be unblocked, state TRANS_STATE_UNBLOCKED).
*/ */
trans = btrfs_attach_transaction_barrier(root); ret = btrfs_commit_current_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
if (ret == -ENOENT)
ret = 0;
break;
}
ret = btrfs_commit_transaction(trans);
break; break;
default: default:
ret = -ENOSPC; ret = -ENOSPC;
......
...@@ -2257,9 +2257,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -2257,9 +2257,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
static int btrfs_freeze(struct super_block *sb) static int btrfs_freeze(struct super_block *sb)
{ {
struct btrfs_trans_handle *trans;
struct btrfs_fs_info *fs_info = btrfs_sb(sb); struct btrfs_fs_info *fs_info = btrfs_sb(sb);
struct btrfs_root *root = fs_info->tree_root;
set_bit(BTRFS_FS_FROZEN, &fs_info->flags); set_bit(BTRFS_FS_FROZEN, &fs_info->flags);
/* /*
...@@ -2268,14 +2266,7 @@ static int btrfs_freeze(struct super_block *sb) ...@@ -2268,14 +2266,7 @@ static int btrfs_freeze(struct super_block *sb)
* we want to avoid on a frozen filesystem), or do the commit * we want to avoid on a frozen filesystem), or do the commit
* ourselves. * ourselves.
*/ */
trans = btrfs_attach_transaction_barrier(root); return btrfs_commit_current_transaction(fs_info->tree_root);
if (IS_ERR(trans)) {
/* no transaction, don't bother */
if (PTR_ERR(trans) == -ENOENT)
return 0;
return PTR_ERR(trans);
}
return btrfs_commit_transaction(trans);
} }
static int check_dev_super(struct btrfs_device *dev) static int check_dev_super(struct btrfs_device *dev)
......
...@@ -1989,6 +1989,25 @@ void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans) ...@@ -1989,6 +1989,25 @@ void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans)
btrfs_put_transaction(cur_trans); btrfs_put_transaction(cur_trans);
} }
/*
* If there is a running transaction commit it or if it's already committing,
* wait for its commit to complete. Does not start and commit a new transaction
* if there isn't any running.
*/
int btrfs_commit_current_transaction(struct btrfs_root *root)
{
struct btrfs_trans_handle *trans;
trans = btrfs_attach_transaction_barrier(root);
if (IS_ERR(trans)) {
int ret = PTR_ERR(trans);
return (ret == -ENOENT) ? 0 : ret;
}
return btrfs_commit_transaction(trans);
}
static void cleanup_transaction(struct btrfs_trans_handle *trans, int err) static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
{ {
struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_fs_info *fs_info = trans->fs_info;
......
...@@ -268,6 +268,7 @@ void btrfs_maybe_wake_unfinished_drop(struct btrfs_fs_info *fs_info); ...@@ -268,6 +268,7 @@ void btrfs_maybe_wake_unfinished_drop(struct btrfs_fs_info *fs_info);
int btrfs_clean_one_deleted_snapshot(struct btrfs_fs_info *fs_info); int btrfs_clean_one_deleted_snapshot(struct btrfs_fs_info *fs_info);
int btrfs_commit_transaction(struct btrfs_trans_handle *trans); int btrfs_commit_transaction(struct btrfs_trans_handle *trans);
void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans); void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans);
int btrfs_commit_current_transaction(struct btrfs_root *root);
int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans); int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans);
bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans); bool btrfs_should_end_transaction(struct btrfs_trans_handle *trans);
void btrfs_throttle(struct btrfs_fs_info *fs_info); void btrfs_throttle(struct btrfs_fs_info *fs_info);
......
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