Commit 6cf7f77e6ba55cc1469aaf795507d274402892e9
Committed by
Josef Bacik
1 parent
886322e8e7
Exists in
master
and in
13 other branches
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>
Showing 1 changed file with 11 additions and 11 deletions Side-by-side Diff
fs/btrfs/transaction.c
... | ... | @@ -1578,8 +1578,6 @@ |
1578 | 1578 | |
1579 | 1579 | trace_btrfs_transaction_commit(root); |
1580 | 1580 | |
1581 | - btrfs_scrub_continue(root); | |
1582 | - | |
1583 | 1581 | if (current->journal_info == trans) |
1584 | 1582 | current->journal_info = NULL; |
1585 | 1583 | |
... | ... | @@ -1754,7 +1752,7 @@ |
1754 | 1752 | /* ->aborted might be set after the previous check, so check it */ |
1755 | 1753 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { |
1756 | 1754 | ret = cur_trans->aborted; |
1757 | - goto cleanup_transaction; | |
1755 | + goto scrub_continue; | |
1758 | 1756 | } |
1759 | 1757 | /* |
1760 | 1758 | * the reloc mutex makes sure that we stop |
... | ... | @@ -1771,7 +1769,7 @@ |
1771 | 1769 | ret = create_pending_snapshots(trans, root->fs_info); |
1772 | 1770 | if (ret) { |
1773 | 1771 | mutex_unlock(&root->fs_info->reloc_mutex); |
1774 | - goto cleanup_transaction; | |
1772 | + goto scrub_continue; | |
1775 | 1773 | } |
1776 | 1774 | |
1777 | 1775 | /* |
1778 | 1776 | |
... | ... | @@ -1787,13 +1785,13 @@ |
1787 | 1785 | ret = btrfs_run_delayed_items(trans, root); |
1788 | 1786 | if (ret) { |
1789 | 1787 | mutex_unlock(&root->fs_info->reloc_mutex); |
1790 | - goto cleanup_transaction; | |
1788 | + goto scrub_continue; | |
1791 | 1789 | } |
1792 | 1790 | |
1793 | 1791 | ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); |
1794 | 1792 | if (ret) { |
1795 | 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 @@ |
1823 | 1821 | if (ret) { |
1824 | 1822 | mutex_unlock(&root->fs_info->tree_log_mutex); |
1825 | 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 @@ |
1844 | 1842 | if (ret) { |
1845 | 1843 | mutex_unlock(&root->fs_info->tree_log_mutex); |
1846 | 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 @@ |
1855 | 1853 | ret = cur_trans->aborted; |
1856 | 1854 | mutex_unlock(&root->fs_info->tree_log_mutex); |
1857 | 1855 | mutex_unlock(&root->fs_info->reloc_mutex); |
1858 | - goto cleanup_transaction; | |
1856 | + goto scrub_continue; | |
1859 | 1857 | } |
1860 | 1858 | |
1861 | 1859 | btrfs_prepare_extent_commit(trans, root); |
1862 | 1860 | |
... | ... | @@ -1891,13 +1889,13 @@ |
1891 | 1889 | btrfs_error(root->fs_info, ret, |
1892 | 1890 | "Error while writing out transaction"); |
1893 | 1891 | mutex_unlock(&root->fs_info->tree_log_mutex); |
1894 | - goto cleanup_transaction; | |
1892 | + goto scrub_continue; | |
1895 | 1893 | } |
1896 | 1894 | |
1897 | 1895 | ret = write_ctree_super(trans, root, 0); |
1898 | 1896 | if (ret) { |
1899 | 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 @@ |
1940 | 1938 | |
1941 | 1939 | return ret; |
1942 | 1940 | |
1941 | +scrub_continue: | |
1942 | + btrfs_scrub_continue(root); | |
1943 | 1943 | cleanup_transaction: |
1944 | 1944 | btrfs_trans_release_metadata(trans, root); |
1945 | 1945 | trans->block_rsv = NULL; |