aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-08-24 14:53:03 -0400
committerChris Mason <chris.mason@oracle.com>2012-08-28 16:53:40 -0400
commitbd7de2c9a449e26a5493d918618eb20ae60d56bd (patch)
tree939b10227537908c96bb339a1655a0c25413057b /fs
parent5ee0844d6427e7338e0aba748f62b62d07ea2ed0 (diff)
Btrfs: fix deadlock with freeze and sync V2
We can deadlock with freeze right now because we unconditionally start a transaction in our ->sync_fs() call. To fix this just check and see if we have a running transaction to commit. This saves us from the deadlock because at this point we'll have the umount sem for the sb so we're safe from freezes coming in after we've done our check. With this patch the freeze xfstests no longer deadlocks. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/super.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 2e06f124f284..073c2368f459 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -813,7 +813,6 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
813 struct btrfs_trans_handle *trans; 813 struct btrfs_trans_handle *trans;
814 struct btrfs_fs_info *fs_info = btrfs_sb(sb); 814 struct btrfs_fs_info *fs_info = btrfs_sb(sb);
815 struct btrfs_root *root = fs_info->tree_root; 815 struct btrfs_root *root = fs_info->tree_root;
816 int ret;
817 816
818 trace_btrfs_sync_fs(wait); 817 trace_btrfs_sync_fs(wait);
819 818
@@ -824,11 +823,17 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
824 823
825 btrfs_wait_ordered_extents(root, 0, 0); 824 btrfs_wait_ordered_extents(root, 0, 0);
826 825
827 trans = btrfs_start_transaction(root, 0); 826 spin_lock(&fs_info->trans_lock);
827 if (!fs_info->running_transaction) {
828 spin_unlock(&fs_info->trans_lock);
829 return 0;
830 }
831 spin_unlock(&fs_info->trans_lock);
832
833 trans = btrfs_join_transaction(root);
828 if (IS_ERR(trans)) 834 if (IS_ERR(trans))
829 return PTR_ERR(trans); 835 return PTR_ERR(trans);
830 ret = btrfs_commit_transaction(trans, root); 836 return btrfs_commit_transaction(trans, root);
831 return ret;
832} 837}
833 838
834static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry) 839static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)