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