aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2009-01-06 09:58:06 -0500
committerChris Mason <chris.mason@oracle.com>2009-01-06 09:58:06 -0500
commit180591bcfed1a2cec048abb21d3dab840625caab (patch)
tree9bd247570ef8f3ed33afcb25bb365ccd707c8a73 /fs
parent9ca03b997f71787e345951e6267fbd8eba14d49f (diff)
Btrfs: Use btrfs_join_transaction to avoid deadlocks during snapshot creation
Snapshot creation happens at a specific time during transaction commit. We need to make sure the code called by snapshot creation doesn't wait for the running transaction to commit. This changes btrfs_delete_inode and finish_pending_snaps to use btrfs_join_transaction instead of btrfs_start_transaction to avoid deadlocks. It would be better if btrfs_delete_inode didn't use the join, but the call path that triggers it is: btrfs_commit_transaction->create_pending_snapshots-> create_pending_snapshot->btrfs_lookup_dentry-> fixup_tree_root_location->btrfs_read_fs_root-> btrfs_read_fs_root_no_name->btrfs_orphan_cleanup->iput This will be fixed in a later patch by moving the orphan cleanup to the cleaner thread. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/inode.c2
-rw-r--r--fs/btrfs/transaction.c2
2 files changed, 2 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1b35ea63b6ce..c0ca9c3723c0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2886,7 +2886,7 @@ void btrfs_delete_inode(struct inode *inode)
2886 btrfs_wait_ordered_range(inode, 0, (u64)-1); 2886 btrfs_wait_ordered_range(inode, 0, (u64)-1);
2887 2887
2888 btrfs_i_size_write(inode, 0); 2888 btrfs_i_size_write(inode, 0);
2889 trans = btrfs_start_transaction(root, 1); 2889 trans = btrfs_join_transaction(root, 1);
2890 2890
2891 btrfs_set_trans_block_group(trans, inode); 2891 btrfs_set_trans_block_group(trans, inode);
2892 ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0); 2892 ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 56ab1f5ea11b..8a08f9443340 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -800,7 +800,7 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info,
800 800
801 parent_inode = pending->dentry->d_parent->d_inode; 801 parent_inode = pending->dentry->d_parent->d_inode;
802 parent_root = BTRFS_I(parent_inode)->root; 802 parent_root = BTRFS_I(parent_inode)->root;
803 trans = btrfs_start_transaction(parent_root, 1); 803 trans = btrfs_join_transaction(parent_root, 1);
804 804
805 /* 805 /*
806 * insert the directory item 806 * insert the directory item