aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.c23
-rw-r--r--fs/btrfs/inode.c1
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 }
2841cow_done: 2842cow_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);