aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ctree.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ctree.c')
-rw-r--r--fs/btrfs/ctree.c234
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);
38static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root, 39static 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);
41static 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
41struct btrfs_path *btrfs_alloc_path(void) 47struct 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/* 3003static 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 */
3015int 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;
3062err:
3063 path->keep_locks = 0;
3064 return ret;
3065}
3066
3067static 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
3064split:
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 */
3153int 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 */
3177int 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/*