aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
authorWang Shilong <wangsl.fnst@cn.fujitsu.com>2014-02-19 06:24:16 -0500
committerJosef Bacik <jbacik@fb.com>2014-03-10 15:16:52 -0400
commit6cf7f77e6ba55cc1469aaf795507d274402892e9 (patch)
tree28066f51e6443d9468a11e28c13dab155e239e2c /fs/btrfs/transaction.c
parent886322e8e787604731e782d36c34327a8970bda9 (diff)
Btrfs: fix a possible deadlock between scrub and transaction committing
btrfs_scrub_continue() will be called when cleaning up transaction.However, this can only be called if btrfs_scrub_pause() is called before. Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com>
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c22
1 files changed, 11 insertions, 11 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 34cd83184c4a..84da6669f384 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1578,8 +1578,6 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
1578 1578
1579 trace_btrfs_transaction_commit(root); 1579 trace_btrfs_transaction_commit(root);
1580 1580
1581 btrfs_scrub_continue(root);
1582
1583 if (current->journal_info == trans) 1581 if (current->journal_info == trans)
1584 current->journal_info = NULL; 1582 current->journal_info = NULL;
1585 1583
@@ -1754,7 +1752,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1754 /* ->aborted might be set after the previous check, so check it */ 1752 /* ->aborted might be set after the previous check, so check it */
1755 if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { 1753 if (unlikely(ACCESS_ONCE(cur_trans->aborted))) {
1756 ret = cur_trans->aborted; 1754 ret = cur_trans->aborted;
1757 goto cleanup_transaction; 1755 goto scrub_continue;
1758 } 1756 }
1759 /* 1757 /*
1760 * the reloc mutex makes sure that we stop 1758 * the reloc mutex makes sure that we stop
@@ -1771,7 +1769,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1771 ret = create_pending_snapshots(trans, root->fs_info); 1769 ret = create_pending_snapshots(trans, root->fs_info);
1772 if (ret) { 1770 if (ret) {
1773 mutex_unlock(&root->fs_info->reloc_mutex); 1771 mutex_unlock(&root->fs_info->reloc_mutex);
1774 goto cleanup_transaction; 1772 goto scrub_continue;
1775 } 1773 }
1776 1774
1777 /* 1775 /*
@@ -1787,13 +1785,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1787 ret = btrfs_run_delayed_items(trans, root); 1785 ret = btrfs_run_delayed_items(trans, root);
1788 if (ret) { 1786 if (ret) {
1789 mutex_unlock(&root->fs_info->reloc_mutex); 1787 mutex_unlock(&root->fs_info->reloc_mutex);
1790 goto cleanup_transaction; 1788 goto scrub_continue;
1791 } 1789 }
1792 1790
1793 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 1791 ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1);
1794 if (ret) { 1792 if (ret) {
1795 mutex_unlock(&root->fs_info->reloc_mutex); 1793 mutex_unlock(&root->fs_info->reloc_mutex);
1796 goto cleanup_transaction; 1794 goto scrub_continue;
1797 } 1795 }
1798 1796
1799 /* 1797 /*
@@ -1823,7 +1821,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1823 if (ret) { 1821 if (ret) {
1824 mutex_unlock(&root->fs_info->tree_log_mutex); 1822 mutex_unlock(&root->fs_info->tree_log_mutex);
1825 mutex_unlock(&root->fs_info->reloc_mutex); 1823 mutex_unlock(&root->fs_info->reloc_mutex);
1826 goto cleanup_transaction; 1824 goto scrub_continue;
1827 } 1825 }
1828 1826
1829 /* 1827 /*
@@ -1844,7 +1842,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1844 if (ret) { 1842 if (ret) {
1845 mutex_unlock(&root->fs_info->tree_log_mutex); 1843 mutex_unlock(&root->fs_info->tree_log_mutex);
1846 mutex_unlock(&root->fs_info->reloc_mutex); 1844 mutex_unlock(&root->fs_info->reloc_mutex);
1847 goto cleanup_transaction; 1845 goto scrub_continue;
1848 } 1846 }
1849 1847
1850 /* 1848 /*
@@ -1855,7 +1853,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1855 ret = cur_trans->aborted; 1853 ret = cur_trans->aborted;
1856 mutex_unlock(&root->fs_info->tree_log_mutex); 1854 mutex_unlock(&root->fs_info->tree_log_mutex);
1857 mutex_unlock(&root->fs_info->reloc_mutex); 1855 mutex_unlock(&root->fs_info->reloc_mutex);
1858 goto cleanup_transaction; 1856 goto scrub_continue;
1859 } 1857 }
1860 1858
1861 btrfs_prepare_extent_commit(trans, root); 1859 btrfs_prepare_extent_commit(trans, root);
@@ -1891,13 +1889,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1891 btrfs_error(root->fs_info, ret, 1889 btrfs_error(root->fs_info, ret,
1892 "Error while writing out transaction"); 1890 "Error while writing out transaction");
1893 mutex_unlock(&root->fs_info->tree_log_mutex); 1891 mutex_unlock(&root->fs_info->tree_log_mutex);
1894 goto cleanup_transaction; 1892 goto scrub_continue;
1895 } 1893 }
1896 1894
1897 ret = write_ctree_super(trans, root, 0); 1895 ret = write_ctree_super(trans, root, 0);
1898 if (ret) { 1896 if (ret) {
1899 mutex_unlock(&root->fs_info->tree_log_mutex); 1897 mutex_unlock(&root->fs_info->tree_log_mutex);
1900 goto cleanup_transaction; 1898 goto scrub_continue;
1901 } 1899 }
1902 1900
1903 /* 1901 /*
@@ -1940,6 +1938,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1940 1938
1941 return ret; 1939 return ret;
1942 1940
1941scrub_continue:
1942 btrfs_scrub_continue(root);
1943cleanup_transaction: 1943cleanup_transaction:
1944 btrfs_trans_release_metadata(trans, root); 1944 btrfs_trans_release_metadata(trans, root);
1945 trans->block_rsv = NULL; 1945 trans->block_rsv = NULL;