aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-02-04 09:31:28 -0500
committerChris Mason <chris.mason@oracle.com>2009-02-04 09:31:28 -0500
commit4d081c41a4f98aecb5e86ef7d3e644cc7b52131f (patch)
tree441e557a52e85a71e60da81d578bcb22fd4760d7 /fs
parent06d9a8d7c24fe22836bf0b0f82db59d6f98e271e (diff)
Btrfs: change btrfs_del_leaf to drop locks earlier
btrfs_del_leaf does two things. First it removes the pointer in the parent, and then it frees the block that has the leaf. It has the parent node locked for both operations. But, it only needs the parent locked while it is deleting the pointer. After that it can safely free the block without the parent locked. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/ctree.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 3af777357acb..f6916ceb3920 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -3630,15 +3630,22 @@ noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans,
3630{ 3630{
3631 int ret; 3631 int ret;
3632 u64 root_gen = btrfs_header_generation(path->nodes[1]); 3632 u64 root_gen = btrfs_header_generation(path->nodes[1]);
3633 u64 parent_start = path->nodes[1]->start;
3634 u64 parent_owner = btrfs_header_owner(path->nodes[1]);
3633 3635
3634 ret = del_ptr(trans, root, path, 1, path->slots[1]); 3636 ret = del_ptr(trans, root, path, 1, path->slots[1]);
3635 if (ret) 3637 if (ret)
3636 return ret; 3638 return ret;
3637 3639
3640 /*
3641 * btrfs_free_extent is expensive, we want to make sure we
3642 * aren't holding any locks when we call it
3643 */
3644 btrfs_unlock_up_safe(path, 0);
3645
3638 ret = btrfs_free_extent(trans, root, bytenr, 3646 ret = btrfs_free_extent(trans, root, bytenr,
3639 btrfs_level_size(root, 0), 3647 btrfs_level_size(root, 0),
3640 path->nodes[1]->start, 3648 parent_start, parent_owner,
3641 btrfs_header_owner(path->nodes[1]),
3642 root_gen, 0, 1); 3649 root_gen, 0, 1);
3643 return ret; 3650 return ret;
3644} 3651}