|
@@ -247,6 +247,7 @@ loop:
|
|
|
INIT_LIST_HEAD(&cur_trans->pending_snapshots);
|
|
|
INIT_LIST_HEAD(&cur_trans->pending_chunks);
|
|
|
INIT_LIST_HEAD(&cur_trans->switch_commits);
|
|
|
+ INIT_LIST_HEAD(&cur_trans->pending_ordered);
|
|
|
list_add_tail(&cur_trans->list, &fs_info->trans_list);
|
|
|
extent_io_tree_init(&cur_trans->dirty_pages,
|
|
|
fs_info->btree_inode->i_mapping);
|
|
@@ -515,6 +516,7 @@ again:
|
|
|
h->sync = false;
|
|
|
INIT_LIST_HEAD(&h->qgroup_ref_list);
|
|
|
INIT_LIST_HEAD(&h->new_bgs);
|
|
|
+ INIT_LIST_HEAD(&h->ordered);
|
|
|
|
|
|
smp_mb();
|
|
|
if (cur_trans->state >= TRANS_STATE_BLOCKED &&
|
|
@@ -746,6 +748,12 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
|
|
|
if (!list_empty(&trans->new_bgs))
|
|
|
btrfs_create_pending_block_groups(trans, root);
|
|
|
|
|
|
+ if (!list_empty(&trans->ordered)) {
|
|
|
+ spin_lock(&info->trans_lock);
|
|
|
+ list_splice(&trans->ordered, &cur_trans->pending_ordered);
|
|
|
+ spin_unlock(&info->trans_lock);
|
|
|
+ }
|
|
|
+
|
|
|
trans->delayed_ref_updates = 0;
|
|
|
if (!trans->sync) {
|
|
|
must_run_delayed_refs =
|
|
@@ -1715,6 +1723,28 @@ static inline void btrfs_wait_delalloc_flush(struct btrfs_fs_info *fs_info)
|
|
|
btrfs_wait_ordered_roots(fs_info, -1);
|
|
|
}
|
|
|
|
|
|
+static inline void
|
|
|
+btrfs_wait_pending_ordered(struct btrfs_transaction *cur_trans,
|
|
|
+ struct btrfs_fs_info *fs_info)
|
|
|
+{
|
|
|
+ struct btrfs_ordered_extent *ordered;
|
|
|
+
|
|
|
+ spin_lock(&fs_info->trans_lock);
|
|
|
+ while (!list_empty(&cur_trans->pending_ordered)) {
|
|
|
+ ordered = list_first_entry(&cur_trans->pending_ordered,
|
|
|
+ struct btrfs_ordered_extent,
|
|
|
+ trans_list);
|
|
|
+ list_del_init(&ordered->trans_list);
|
|
|
+ spin_unlock(&fs_info->trans_lock);
|
|
|
+
|
|
|
+ wait_event(ordered->wait, test_bit(BTRFS_ORDERED_COMPLETE,
|
|
|
+ &ordered->flags));
|
|
|
+ btrfs_put_ordered_extent(ordered);
|
|
|
+ spin_lock(&fs_info->trans_lock);
|
|
|
+ }
|
|
|
+ spin_unlock(&fs_info->trans_lock);
|
|
|
+}
|
|
|
+
|
|
|
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
|
|
struct btrfs_root *root)
|
|
|
{
|
|
@@ -1765,6 +1795,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
|
|
}
|
|
|
|
|
|
spin_lock(&root->fs_info->trans_lock);
|
|
|
+ list_splice(&trans->ordered, &cur_trans->pending_ordered);
|
|
|
if (cur_trans->state >= TRANS_STATE_COMMIT_START) {
|
|
|
spin_unlock(&root->fs_info->trans_lock);
|
|
|
atomic_inc(&cur_trans->use_count);
|
|
@@ -1817,6 +1848,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
btrfs_wait_delalloc_flush(root->fs_info);
|
|
|
|
|
|
+ btrfs_wait_pending_ordered(cur_trans, root->fs_info);
|
|
|
+
|
|
|
btrfs_scrub_pause(root);
|
|
|
/*
|
|
|
* Ok now we need to make sure to block out any other joins while we
|