diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r-- | fs/btrfs/ctree.c | 229 |
1 files changed, 153 insertions, 76 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index ec96f3a6d536..c4bc570a396e 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -37,6 +37,11 @@ static int balance_node_right(struct btrfs_trans_handle *trans, | |||
37 | struct extent_buffer *src_buf); | 37 | struct extent_buffer *src_buf); |
38 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 38 | static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
39 | struct btrfs_path *path, int level, int slot); | 39 | struct btrfs_path *path, int level, int slot); |
40 | static int setup_items_for_insert(struct btrfs_trans_handle *trans, | ||
41 | struct btrfs_root *root, struct btrfs_path *path, | ||
42 | struct btrfs_key *cpu_key, u32 *data_size, | ||
43 | u32 total_data, u32 total_size, int nr); | ||
44 | |||
40 | 45 | ||
41 | struct btrfs_path *btrfs_alloc_path(void) | 46 | struct btrfs_path *btrfs_alloc_path(void) |
42 | { | 47 | { |
@@ -451,9 +456,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
451 | extent_buffer_get(cow); | 456 | extent_buffer_get(cow); |
452 | spin_unlock(&root->node_lock); | 457 | spin_unlock(&root->node_lock); |
453 | 458 | ||
454 | btrfs_free_extent(trans, root, buf->start, buf->len, | 459 | btrfs_free_tree_block(trans, root, buf->start, buf->len, |
455 | parent_start, root->root_key.objectid, | 460 | parent_start, root->root_key.objectid, level); |
456 | level, 0); | ||
457 | free_extent_buffer(buf); | 461 | free_extent_buffer(buf); |
458 | add_root_to_dirty_list(root); | 462 | add_root_to_dirty_list(root); |
459 | } else { | 463 | } else { |
@@ -468,9 +472,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
468 | btrfs_set_node_ptr_generation(parent, parent_slot, | 472 | btrfs_set_node_ptr_generation(parent, parent_slot, |
469 | trans->transid); | 473 | trans->transid); |
470 | btrfs_mark_buffer_dirty(parent); | 474 | btrfs_mark_buffer_dirty(parent); |
471 | btrfs_free_extent(trans, root, buf->start, buf->len, | 475 | btrfs_free_tree_block(trans, root, buf->start, buf->len, |
472 | parent_start, root->root_key.objectid, | 476 | parent_start, root->root_key.objectid, level); |
473 | level, 0); | ||
474 | } | 477 | } |
475 | if (unlock_orig) | 478 | if (unlock_orig) |
476 | btrfs_tree_unlock(buf); | 479 | btrfs_tree_unlock(buf); |
@@ -1030,8 +1033,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1030 | btrfs_tree_unlock(mid); | 1033 | btrfs_tree_unlock(mid); |
1031 | /* once for the path */ | 1034 | /* once for the path */ |
1032 | free_extent_buffer(mid); | 1035 | free_extent_buffer(mid); |
1033 | ret = btrfs_free_extent(trans, root, mid->start, mid->len, | 1036 | ret = btrfs_free_tree_block(trans, root, mid->start, mid->len, |
1034 | 0, root->root_key.objectid, level, 1); | 1037 | 0, root->root_key.objectid, level); |
1035 | /* once for the root ptr */ | 1038 | /* once for the root ptr */ |
1036 | free_extent_buffer(mid); | 1039 | free_extent_buffer(mid); |
1037 | return ret; | 1040 | return ret; |
@@ -1095,10 +1098,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1095 | 1); | 1098 | 1); |
1096 | if (wret) | 1099 | if (wret) |
1097 | ret = wret; | 1100 | ret = wret; |
1098 | wret = btrfs_free_extent(trans, root, bytenr, | 1101 | wret = btrfs_free_tree_block(trans, root, |
1099 | blocksize, 0, | 1102 | bytenr, blocksize, 0, |
1100 | root->root_key.objectid, | 1103 | root->root_key.objectid, |
1101 | level, 0); | 1104 | level); |
1102 | if (wret) | 1105 | if (wret) |
1103 | ret = wret; | 1106 | ret = wret; |
1104 | } else { | 1107 | } else { |
@@ -1143,9 +1146,8 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1143 | wret = del_ptr(trans, root, path, level + 1, pslot); | 1146 | wret = del_ptr(trans, root, path, level + 1, pslot); |
1144 | if (wret) | 1147 | if (wret) |
1145 | ret = wret; | 1148 | ret = wret; |
1146 | wret = btrfs_free_extent(trans, root, bytenr, blocksize, | 1149 | wret = btrfs_free_tree_block(trans, root, bytenr, blocksize, |
1147 | 0, root->root_key.objectid, | 1150 | 0, root->root_key.objectid, level); |
1148 | level, 0); | ||
1149 | if (wret) | 1151 | if (wret) |
1150 | ret = wret; | 1152 | ret = wret; |
1151 | } else { | 1153 | } else { |
@@ -2997,75 +2999,85 @@ again: | |||
2997 | return ret; | 2999 | return ret; |
2998 | } | 3000 | } |
2999 | 3001 | ||
3000 | /* | 3002 | static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans, |
3001 | * This function splits a single item into two items, | 3003 | struct btrfs_root *root, |
3002 | * giving 'new_key' to the new item and splitting the | 3004 | struct btrfs_path *path, int ins_len) |
3003 | * old one at split_offset (from the start of the item). | ||
3004 | * | ||
3005 | * The path may be released by this operation. After | ||
3006 | * the split, the path is pointing to the old item. The | ||
3007 | * new item is going to be in the same node as the old one. | ||
3008 | * | ||
3009 | * Note, the item being split must be smaller enough to live alone on | ||
3010 | * a tree block with room for one extra struct btrfs_item | ||
3011 | * | ||
3012 | * This allows us to split the item in place, keeping a lock on the | ||
3013 | * leaf the entire time. | ||
3014 | */ | ||
3015 | int btrfs_split_item(struct btrfs_trans_handle *trans, | ||
3016 | struct btrfs_root *root, | ||
3017 | struct btrfs_path *path, | ||
3018 | struct btrfs_key *new_key, | ||
3019 | unsigned long split_offset) | ||
3020 | { | 3005 | { |
3021 | u32 item_size; | 3006 | struct btrfs_key key; |
3022 | struct extent_buffer *leaf; | 3007 | struct extent_buffer *leaf; |
3023 | struct btrfs_key orig_key; | 3008 | struct btrfs_file_extent_item *fi; |
3024 | struct btrfs_item *item; | 3009 | u64 extent_len = 0; |
3025 | struct btrfs_item *new_item; | 3010 | u32 item_size; |
3026 | int ret = 0; | 3011 | int ret; |
3027 | int slot; | ||
3028 | u32 nritems; | ||
3029 | u32 orig_offset; | ||
3030 | struct btrfs_disk_key disk_key; | ||
3031 | char *buf; | ||
3032 | 3012 | ||
3033 | leaf = path->nodes[0]; | 3013 | leaf = path->nodes[0]; |
3034 | btrfs_item_key_to_cpu(leaf, &orig_key, path->slots[0]); | 3014 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); |
3035 | if (btrfs_leaf_free_space(root, leaf) >= sizeof(struct btrfs_item)) | 3015 | |
3036 | goto split; | 3016 | BUG_ON(key.type != BTRFS_EXTENT_DATA_KEY && |
3017 | key.type != BTRFS_EXTENT_CSUM_KEY); | ||
3018 | |||
3019 | if (btrfs_leaf_free_space(root, leaf) >= ins_len) | ||
3020 | return 0; | ||
3037 | 3021 | ||
3038 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | 3022 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); |
3023 | if (key.type == BTRFS_EXTENT_DATA_KEY) { | ||
3024 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
3025 | struct btrfs_file_extent_item); | ||
3026 | extent_len = btrfs_file_extent_num_bytes(leaf, fi); | ||
3027 | } | ||
3039 | btrfs_release_path(root, path); | 3028 | btrfs_release_path(root, path); |
3040 | 3029 | ||
3041 | path->search_for_split = 1; | ||
3042 | path->keep_locks = 1; | 3030 | path->keep_locks = 1; |
3043 | 3031 | path->search_for_split = 1; | |
3044 | ret = btrfs_search_slot(trans, root, &orig_key, path, 0, 1); | 3032 | ret = btrfs_search_slot(trans, root, &key, path, 0, 1); |
3045 | path->search_for_split = 0; | 3033 | path->search_for_split = 0; |
3034 | if (ret < 0) | ||
3035 | goto err; | ||
3046 | 3036 | ||
3037 | ret = -EAGAIN; | ||
3038 | leaf = path->nodes[0]; | ||
3047 | /* if our item isn't there or got smaller, return now */ | 3039 | /* if our item isn't there or got smaller, return now */ |
3048 | if (ret != 0 || item_size != btrfs_item_size_nr(path->nodes[0], | 3040 | if (ret > 0 || item_size != btrfs_item_size_nr(leaf, path->slots[0])) |
3049 | path->slots[0])) { | 3041 | goto err; |
3050 | path->keep_locks = 0; | 3042 | |
3051 | return -EAGAIN; | 3043 | if (key.type == BTRFS_EXTENT_DATA_KEY) { |
3044 | fi = btrfs_item_ptr(leaf, path->slots[0], | ||
3045 | struct btrfs_file_extent_item); | ||
3046 | if (extent_len != btrfs_file_extent_num_bytes(leaf, fi)) | ||
3047 | goto err; | ||
3052 | } | 3048 | } |
3053 | 3049 | ||
3054 | btrfs_set_path_blocking(path); | 3050 | btrfs_set_path_blocking(path); |
3055 | ret = split_leaf(trans, root, &orig_key, path, | 3051 | ret = split_leaf(trans, root, &key, path, ins_len, 1); |
3056 | sizeof(struct btrfs_item), 1); | ||
3057 | path->keep_locks = 0; | ||
3058 | BUG_ON(ret); | 3052 | BUG_ON(ret); |
3059 | 3053 | ||
3054 | path->keep_locks = 0; | ||
3060 | btrfs_unlock_up_safe(path, 1); | 3055 | btrfs_unlock_up_safe(path, 1); |
3056 | return 0; | ||
3057 | err: | ||
3058 | path->keep_locks = 0; | ||
3059 | return ret; | ||
3060 | } | ||
3061 | |||
3062 | static noinline int split_item(struct btrfs_trans_handle *trans, | ||
3063 | struct btrfs_root *root, | ||
3064 | struct btrfs_path *path, | ||
3065 | struct btrfs_key *new_key, | ||
3066 | unsigned long split_offset) | ||
3067 | { | ||
3068 | struct extent_buffer *leaf; | ||
3069 | struct btrfs_item *item; | ||
3070 | struct btrfs_item *new_item; | ||
3071 | int slot; | ||
3072 | char *buf; | ||
3073 | u32 nritems; | ||
3074 | u32 item_size; | ||
3075 | u32 orig_offset; | ||
3076 | struct btrfs_disk_key disk_key; | ||
3077 | |||
3061 | leaf = path->nodes[0]; | 3078 | leaf = path->nodes[0]; |
3062 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); | 3079 | BUG_ON(btrfs_leaf_free_space(root, leaf) < sizeof(struct btrfs_item)); |
3063 | 3080 | ||
3064 | split: | ||
3065 | /* | ||
3066 | * make sure any changes to the path from split_leaf leave it | ||
3067 | * in a blocking state | ||
3068 | */ | ||
3069 | btrfs_set_path_blocking(path); | 3081 | btrfs_set_path_blocking(path); |
3070 | 3082 | ||
3071 | item = btrfs_item_nr(leaf, path->slots[0]); | 3083 | item = btrfs_item_nr(leaf, path->slots[0]); |
@@ -3073,19 +3085,19 @@ split: | |||
3073 | item_size = btrfs_item_size(leaf, item); | 3085 | item_size = btrfs_item_size(leaf, item); |
3074 | 3086 | ||
3075 | buf = kmalloc(item_size, GFP_NOFS); | 3087 | buf = kmalloc(item_size, GFP_NOFS); |
3088 | if (!buf) | ||
3089 | return -ENOMEM; | ||
3090 | |||
3076 | read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, | 3091 | read_extent_buffer(leaf, buf, btrfs_item_ptr_offset(leaf, |
3077 | path->slots[0]), item_size); | 3092 | path->slots[0]), item_size); |
3078 | slot = path->slots[0] + 1; | ||
3079 | leaf = path->nodes[0]; | ||
3080 | 3093 | ||
3094 | slot = path->slots[0] + 1; | ||
3081 | nritems = btrfs_header_nritems(leaf); | 3095 | nritems = btrfs_header_nritems(leaf); |
3082 | |||
3083 | if (slot != nritems) { | 3096 | if (slot != nritems) { |
3084 | /* shift the items */ | 3097 | /* shift the items */ |
3085 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), | 3098 | memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + 1), |
3086 | btrfs_item_nr_offset(slot), | 3099 | btrfs_item_nr_offset(slot), |
3087 | (nritems - slot) * sizeof(struct btrfs_item)); | 3100 | (nritems - slot) * sizeof(struct btrfs_item)); |
3088 | |||
3089 | } | 3101 | } |
3090 | 3102 | ||
3091 | btrfs_cpu_key_to_disk(&disk_key, new_key); | 3103 | btrfs_cpu_key_to_disk(&disk_key, new_key); |
@@ -3113,16 +3125,81 @@ split: | |||
3113 | item_size - split_offset); | 3125 | item_size - split_offset); |
3114 | btrfs_mark_buffer_dirty(leaf); | 3126 | btrfs_mark_buffer_dirty(leaf); |
3115 | 3127 | ||
3116 | ret = 0; | 3128 | BUG_ON(btrfs_leaf_free_space(root, leaf) < 0); |
3117 | if (btrfs_leaf_free_space(root, leaf) < 0) { | ||
3118 | btrfs_print_leaf(root, leaf); | ||
3119 | BUG(); | ||
3120 | } | ||
3121 | kfree(buf); | 3129 | kfree(buf); |
3130 | return 0; | ||
3131 | } | ||
3132 | |||
3133 | /* | ||
3134 | * This function splits a single item into two items, | ||
3135 | * giving 'new_key' to the new item and splitting the | ||
3136 | * old one at split_offset (from the start of the item). | ||
3137 | * | ||
3138 | * The path may be released by this operation. After | ||
3139 | * the split, the path is pointing to the old item. The | ||
3140 | * new item is going to be in the same node as the old one. | ||
3141 | * | ||
3142 | * Note, the item being split must be smaller enough to live alone on | ||
3143 | * a tree block with room for one extra struct btrfs_item | ||
3144 | * | ||
3145 | * This allows us to split the item in place, keeping a lock on the | ||
3146 | * leaf the entire time. | ||
3147 | */ | ||
3148 | int btrfs_split_item(struct btrfs_trans_handle *trans, | ||
3149 | struct btrfs_root *root, | ||
3150 | struct btrfs_path *path, | ||
3151 | struct btrfs_key *new_key, | ||
3152 | unsigned long split_offset) | ||
3153 | { | ||
3154 | int ret; | ||
3155 | ret = setup_leaf_for_split(trans, root, path, | ||
3156 | sizeof(struct btrfs_item)); | ||
3157 | if (ret) | ||
3158 | return ret; | ||
3159 | |||
3160 | ret = split_item(trans, root, path, new_key, split_offset); | ||
3122 | return ret; | 3161 | return ret; |
3123 | } | 3162 | } |
3124 | 3163 | ||
3125 | /* | 3164 | /* |
3165 | * This function duplicate a item, giving 'new_key' to the new item. | ||
3166 | * It guarantees both items live in the same tree leaf and the new item | ||
3167 | * is contiguous with the original item. | ||
3168 | * | ||
3169 | * This allows us to split file extent in place, keeping a lock on the | ||
3170 | * leaf the entire time. | ||
3171 | */ | ||
3172 | int btrfs_duplicate_item(struct btrfs_trans_handle *trans, | ||
3173 | struct btrfs_root *root, | ||
3174 | struct btrfs_path *path, | ||
3175 | struct btrfs_key *new_key) | ||
3176 | { | ||
3177 | struct extent_buffer *leaf; | ||
3178 | int ret; | ||
3179 | u32 item_size; | ||
3180 | |||
3181 | leaf = path->nodes[0]; | ||
3182 | item_size = btrfs_item_size_nr(leaf, path->slots[0]); | ||
3183 | ret = setup_leaf_for_split(trans, root, path, | ||
3184 | item_size + sizeof(struct btrfs_item)); | ||
3185 | if (ret) | ||
3186 | return ret; | ||
3187 | |||
3188 | path->slots[0]++; | ||
3189 | ret = setup_items_for_insert(trans, root, path, new_key, &item_size, | ||
3190 | item_size, item_size + | ||
3191 | sizeof(struct btrfs_item), 1); | ||
3192 | BUG_ON(ret); | ||
3193 | |||
3194 | leaf = path->nodes[0]; | ||
3195 | memcpy_extent_buffer(leaf, | ||
3196 | btrfs_item_ptr_offset(leaf, path->slots[0]), | ||
3197 | btrfs_item_ptr_offset(leaf, path->slots[0] - 1), | ||
3198 | item_size); | ||
3199 | return 0; | ||
3200 | } | ||
3201 | |||
3202 | /* | ||
3126 | * make the item pointed to by the path smaller. new_size indicates | 3203 | * make the item pointed to by the path smaller. new_size indicates |
3127 | * how small to make it, and from_end tells us if we just chop bytes | 3204 | * how small to make it, and from_end tells us if we just chop bytes |
3128 | * off the end of the item or if we shift the item to chop bytes off | 3205 | * off the end of the item or if we shift the item to chop bytes off |
@@ -3714,8 +3791,8 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, | |||
3714 | */ | 3791 | */ |
3715 | btrfs_unlock_up_safe(path, 0); | 3792 | btrfs_unlock_up_safe(path, 0); |
3716 | 3793 | ||
3717 | ret = btrfs_free_extent(trans, root, leaf->start, leaf->len, | 3794 | ret = btrfs_free_tree_block(trans, root, leaf->start, leaf->len, |
3718 | 0, root->root_key.objectid, 0, 0); | 3795 | 0, root->root_key.objectid, 0); |
3719 | return ret; | 3796 | return ret; |
3720 | } | 3797 | } |
3721 | /* | 3798 | /* |