diff options
-rw-r--r-- | fs/btrfs/ctree.c | 23 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 1 |
2 files changed, 14 insertions, 10 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 062438d38985..9e9de68eb813 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -2731,6 +2731,7 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root | |||
2731 | lowest_level = p->lowest_level; | 2731 | lowest_level = p->lowest_level; |
2732 | WARN_ON(lowest_level && ins_len > 0); | 2732 | WARN_ON(lowest_level && ins_len > 0); |
2733 | WARN_ON(p->nodes[0] != NULL); | 2733 | WARN_ON(p->nodes[0] != NULL); |
2734 | BUG_ON(!cow && ins_len); | ||
2734 | 2735 | ||
2735 | if (ins_len < 0) { | 2736 | if (ins_len < 0) { |
2736 | lowest_unlock = 2; | 2737 | lowest_unlock = 2; |
@@ -2839,8 +2840,6 @@ again: | |||
2839 | } | 2840 | } |
2840 | } | 2841 | } |
2841 | cow_done: | 2842 | cow_done: |
2842 | BUG_ON(!cow && ins_len); | ||
2843 | |||
2844 | p->nodes[level] = b; | 2843 | p->nodes[level] = b; |
2845 | btrfs_clear_path_blocking(p, NULL, 0); | 2844 | btrfs_clear_path_blocking(p, NULL, 0); |
2846 | 2845 | ||
@@ -2850,13 +2849,19 @@ cow_done: | |||
2850 | * It is safe to drop the lock on our parent before we | 2849 | * It is safe to drop the lock on our parent before we |
2851 | * go through the expensive btree search on b. | 2850 | * go through the expensive btree search on b. |
2852 | * | 2851 | * |
2853 | * If cow is true, then we might be changing slot zero, | 2852 | * If we're inserting or deleting (ins_len != 0), then we might |
2854 | * which may require changing the parent. So, we can't | 2853 | * be changing slot zero, which may require changing the parent. |
2855 | * drop the lock until after we know which slot we're | 2854 | * So, we can't drop the lock until after we know which slot |
2856 | * operating on. | 2855 | * we're operating on. |
2857 | */ | 2856 | */ |
2858 | if (!cow) | 2857 | if (!ins_len && !p->keep_locks) { |
2859 | btrfs_unlock_up_safe(p, level + 1); | 2858 | int u = level + 1; |
2859 | |||
2860 | if (u < BTRFS_MAX_LEVEL && p->locks[u]) { | ||
2861 | btrfs_tree_unlock_rw(p->nodes[u], p->locks[u]); | ||
2862 | p->locks[u] = 0; | ||
2863 | } | ||
2864 | } | ||
2860 | 2865 | ||
2861 | ret = key_search(b, key, level, &prev_cmp, &slot); | 2866 | ret = key_search(b, key, level, &prev_cmp, &slot); |
2862 | 2867 | ||
@@ -2884,7 +2889,7 @@ cow_done: | |||
2884 | * which means we must have a write lock | 2889 | * which means we must have a write lock |
2885 | * on the parent | 2890 | * on the parent |
2886 | */ | 2891 | */ |
2887 | if (slot == 0 && cow && | 2892 | if (slot == 0 && ins_len && |
2888 | write_lock_level < level + 1) { | 2893 | write_lock_level < level + 1) { |
2889 | write_lock_level = level + 1; | 2894 | write_lock_level = level + 1; |
2890 | btrfs_release_path(p); | 2895 | btrfs_release_path(p); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9eaa1c8ed385..8e45fdcdbd8e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3515,7 +3515,6 @@ static noinline int btrfs_update_inode_item(struct btrfs_trans_handle *trans, | |||
3515 | goto failed; | 3515 | goto failed; |
3516 | } | 3516 | } |
3517 | 3517 | ||
3518 | btrfs_unlock_up_safe(path, 1); | ||
3519 | leaf = path->nodes[0]; | 3518 | leaf = path->nodes[0]; |
3520 | inode_item = btrfs_item_ptr(leaf, path->slots[0], | 3519 | inode_item = btrfs_item_ptr(leaf, path->slots[0], |
3521 | struct btrfs_inode_item); | 3520 | struct btrfs_inode_item); |