diff options
Diffstat (limited to 'fs/btrfs/ctree.c')
| -rw-r--r-- | fs/btrfs/ctree.c | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 7114faafa9d..579124043d9 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
| @@ -60,7 +60,7 @@ void btrfs_free_path(struct btrfs_path *p) | |||
| 60 | kmem_cache_free(btrfs_path_cachep, p); | 60 | kmem_cache_free(btrfs_path_cachep, p); |
| 61 | } | 61 | } |
| 62 | 62 | ||
| 63 | void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) | 63 | void noinline btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p) |
| 64 | { | 64 | { |
| 65 | int i; | 65 | int i; |
| 66 | 66 | ||
| @@ -176,7 +176,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
| 176 | return 0; | 176 | return 0; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | int __btrfs_cow_block(struct btrfs_trans_handle *trans, | 179 | int noinline __btrfs_cow_block(struct btrfs_trans_handle *trans, |
| 180 | struct btrfs_root *root, | 180 | struct btrfs_root *root, |
| 181 | struct extent_buffer *buf, | 181 | struct extent_buffer *buf, |
| 182 | struct extent_buffer *parent, int parent_slot, | 182 | struct extent_buffer *parent, int parent_slot, |
| @@ -294,7 +294,7 @@ int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
| 294 | return 0; | 294 | return 0; |
| 295 | } | 295 | } |
| 296 | 296 | ||
| 297 | int btrfs_cow_block(struct btrfs_trans_handle *trans, | 297 | int noinline btrfs_cow_block(struct btrfs_trans_handle *trans, |
| 298 | struct btrfs_root *root, struct extent_buffer *buf, | 298 | struct btrfs_root *root, struct extent_buffer *buf, |
| 299 | struct extent_buffer *parent, int parent_slot, | 299 | struct extent_buffer *parent, int parent_slot, |
| 300 | struct extent_buffer **cow_ret, u64 prealloc_dest) | 300 | struct extent_buffer **cow_ret, u64 prealloc_dest) |
| @@ -677,9 +677,10 @@ static int noinline check_block(struct btrfs_root *root, | |||
| 677 | * | 677 | * |
| 678 | * slot may point to max if the key is bigger than all of the keys | 678 | * slot may point to max if the key is bigger than all of the keys |
| 679 | */ | 679 | */ |
| 680 | static int generic_bin_search(struct extent_buffer *eb, unsigned long p, | 680 | static noinline int generic_bin_search(struct extent_buffer *eb, |
| 681 | int item_size, struct btrfs_key *key, | 681 | unsigned long p, |
| 682 | int max, int *slot) | 682 | int item_size, struct btrfs_key *key, |
| 683 | int max, int *slot) | ||
| 683 | { | 684 | { |
| 684 | int low = 0; | 685 | int low = 0; |
| 685 | int high = max; | 686 | int high = max; |
| @@ -765,7 +766,7 @@ static int bin_search(struct extent_buffer *eb, struct btrfs_key *key, | |||
| 765 | return -1; | 766 | return -1; |
| 766 | } | 767 | } |
| 767 | 768 | ||
| 768 | static struct extent_buffer *read_node_slot(struct btrfs_root *root, | 769 | static noinline struct extent_buffer *read_node_slot(struct btrfs_root *root, |
| 769 | struct extent_buffer *parent, int slot) | 770 | struct extent_buffer *parent, int slot) |
| 770 | { | 771 | { |
| 771 | int level = btrfs_header_level(parent); | 772 | int level = btrfs_header_level(parent); |
| @@ -781,7 +782,7 @@ static struct extent_buffer *read_node_slot(struct btrfs_root *root, | |||
| 781 | btrfs_node_ptr_generation(parent, slot)); | 782 | btrfs_node_ptr_generation(parent, slot)); |
| 782 | } | 783 | } |
| 783 | 784 | ||
| 784 | static int balance_level(struct btrfs_trans_handle *trans, | 785 | static noinline int balance_level(struct btrfs_trans_handle *trans, |
| 785 | struct btrfs_root *root, | 786 | struct btrfs_root *root, |
| 786 | struct btrfs_path *path, int level) | 787 | struct btrfs_path *path, int level) |
| 787 | { | 788 | { |
| @@ -1128,8 +1129,9 @@ static int noinline push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
| 1128 | /* | 1129 | /* |
| 1129 | * readahead one full node of leaves | 1130 | * readahead one full node of leaves |
| 1130 | */ | 1131 | */ |
| 1131 | static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | 1132 | static noinline void reada_for_search(struct btrfs_root *root, |
| 1132 | int level, int slot, u64 objectid) | 1133 | struct btrfs_path *path, |
| 1134 | int level, int slot, u64 objectid) | ||
| 1133 | { | 1135 | { |
| 1134 | struct extent_buffer *node; | 1136 | struct extent_buffer *node; |
| 1135 | struct btrfs_disk_key disk_key; | 1137 | struct btrfs_disk_key disk_key; |
| @@ -1201,7 +1203,8 @@ static void reada_for_search(struct btrfs_root *root, struct btrfs_path *path, | |||
| 1201 | } | 1203 | } |
| 1202 | } | 1204 | } |
| 1203 | 1205 | ||
| 1204 | static void unlock_up(struct btrfs_path *path, int level, int lowest_unlock) | 1206 | static noinline void unlock_up(struct btrfs_path *path, int level, |
| 1207 | int lowest_unlock) | ||
| 1205 | { | 1208 | { |
| 1206 | int i; | 1209 | int i; |
| 1207 | int skip_level = level; | 1210 | int skip_level = level; |
| @@ -1759,8 +1762,9 @@ static int insert_ptr(struct btrfs_trans_handle *trans, struct btrfs_root | |||
| 1759 | * | 1762 | * |
| 1760 | * returns 0 on success and < 0 on failure | 1763 | * returns 0 on success and < 0 on failure |
| 1761 | */ | 1764 | */ |
| 1762 | static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root | 1765 | static noinline int split_node(struct btrfs_trans_handle *trans, |
| 1763 | *root, struct btrfs_path *path, int level) | 1766 | struct btrfs_root *root, |
| 1767 | struct btrfs_path *path, int level) | ||
| 1764 | { | 1768 | { |
| 1765 | u64 root_gen; | 1769 | u64 root_gen; |
| 1766 | struct extent_buffer *c; | 1770 | struct extent_buffer *c; |
| @@ -1874,7 +1878,8 @@ static int leaf_space_used(struct extent_buffer *l, int start, int nr) | |||
| 1874 | * the start of the leaf data. IOW, how much room | 1878 | * the start of the leaf data. IOW, how much room |
| 1875 | * the leaf has left for both items and data | 1879 | * the leaf has left for both items and data |
| 1876 | */ | 1880 | */ |
| 1877 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf) | 1881 | int noinline btrfs_leaf_free_space(struct btrfs_root *root, |
| 1882 | struct extent_buffer *leaf) | ||
| 1878 | { | 1883 | { |
| 1879 | int nritems = btrfs_header_nritems(leaf); | 1884 | int nritems = btrfs_header_nritems(leaf); |
| 1880 | int ret; | 1885 | int ret; |
| @@ -2283,9 +2288,11 @@ out: | |||
| 2283 | * | 2288 | * |
| 2284 | * returns 0 if all went well and < 0 on failure. | 2289 | * returns 0 if all went well and < 0 on failure. |
| 2285 | */ | 2290 | */ |
| 2286 | static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root | 2291 | static noinline int split_leaf(struct btrfs_trans_handle *trans, |
| 2287 | *root, struct btrfs_key *ins_key, | 2292 | struct btrfs_root *root, |
| 2288 | struct btrfs_path *path, int data_size, int extend) | 2293 | struct btrfs_key *ins_key, |
| 2294 | struct btrfs_path *path, int data_size, | ||
| 2295 | int extend) | ||
| 2289 | { | 2296 | { |
| 2290 | u64 root_gen; | 2297 | u64 root_gen; |
| 2291 | struct extent_buffer *l; | 2298 | struct extent_buffer *l; |
| @@ -3079,6 +3086,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path) | |||
| 3079 | * was nothing in the tree that matched the search criteria. | 3086 | * was nothing in the tree that matched the search criteria. |
| 3080 | */ | 3087 | */ |
| 3081 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | 3088 | int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, |
| 3089 | struct btrfs_key *max_key, | ||
| 3082 | struct btrfs_path *path, int cache_only, | 3090 | struct btrfs_path *path, int cache_only, |
| 3083 | u64 min_trans) | 3091 | u64 min_trans) |
| 3084 | { | 3092 | { |
| @@ -3093,6 +3101,7 @@ int btrfs_search_forward(struct btrfs_root *root, struct btrfs_key *min_key, | |||
| 3093 | again: | 3101 | again: |
| 3094 | cur = btrfs_lock_root_node(root); | 3102 | cur = btrfs_lock_root_node(root); |
| 3095 | level = btrfs_header_level(cur); | 3103 | level = btrfs_header_level(cur); |
| 3104 | WARN_ON(path->nodes[level]); | ||
| 3096 | path->nodes[level] = cur; | 3105 | path->nodes[level] = cur; |
| 3097 | path->locks[level] = 1; | 3106 | path->locks[level] = 1; |
| 3098 | 3107 | ||
| @@ -3107,6 +3116,8 @@ again: | |||
| 3107 | 3116 | ||
| 3108 | /* at level = 0, we're done, setup the path and exit */ | 3117 | /* at level = 0, we're done, setup the path and exit */ |
| 3109 | if (level == 0) { | 3118 | if (level == 0) { |
| 3119 | if (slot >= nritems) | ||
| 3120 | goto find_next_key; | ||
| 3110 | ret = 0; | 3121 | ret = 0; |
| 3111 | path->slots[level] = slot; | 3122 | path->slots[level] = slot; |
| 3112 | btrfs_item_key_to_cpu(cur, &found_key, slot); | 3123 | btrfs_item_key_to_cpu(cur, &found_key, slot); |
| @@ -3123,6 +3134,8 @@ again: | |||
| 3123 | u64 blockptr; | 3134 | u64 blockptr; |
| 3124 | u64 gen; | 3135 | u64 gen; |
| 3125 | struct extent_buffer *tmp; | 3136 | struct extent_buffer *tmp; |
| 3137 | struct btrfs_disk_key disk_key; | ||
| 3138 | |||
| 3126 | blockptr = btrfs_node_blockptr(cur, slot); | 3139 | blockptr = btrfs_node_blockptr(cur, slot); |
| 3127 | gen = btrfs_node_ptr_generation(cur, slot); | 3140 | gen = btrfs_node_ptr_generation(cur, slot); |
| 3128 | if (gen < min_trans) { | 3141 | if (gen < min_trans) { |
| @@ -3132,6 +3145,14 @@ again: | |||
| 3132 | if (!cache_only) | 3145 | if (!cache_only) |
| 3133 | break; | 3146 | break; |
| 3134 | 3147 | ||
| 3148 | if (max_key) { | ||
| 3149 | btrfs_node_key(cur, &disk_key, slot); | ||
| 3150 | if (comp_keys(&disk_key, max_key) >= 0) { | ||
| 3151 | ret = 1; | ||
| 3152 | goto out; | ||
| 3153 | } | ||
| 3154 | } | ||
| 3155 | |||
| 3135 | tmp = btrfs_find_tree_block(root, blockptr, | 3156 | tmp = btrfs_find_tree_block(root, blockptr, |
| 3136 | btrfs_level_size(root, level - 1)); | 3157 | btrfs_level_size(root, level - 1)); |
| 3137 | 3158 | ||
| @@ -3143,14 +3164,16 @@ again: | |||
| 3143 | free_extent_buffer(tmp); | 3164 | free_extent_buffer(tmp); |
| 3144 | slot++; | 3165 | slot++; |
| 3145 | } | 3166 | } |
| 3167 | find_next_key: | ||
| 3146 | /* | 3168 | /* |
| 3147 | * we didn't find a candidate key in this node, walk forward | 3169 | * we didn't find a candidate key in this node, walk forward |
| 3148 | * and find another one | 3170 | * and find another one |
| 3149 | */ | 3171 | */ |
| 3150 | if (slot >= nritems) { | 3172 | if (slot >= nritems) { |
| 3151 | ret = btrfs_find_next_key(root, path, min_key, level, | 3173 | path->slots[level] = slot; |
| 3174 | sret = btrfs_find_next_key(root, path, min_key, level, | ||
| 3152 | cache_only, min_trans); | 3175 | cache_only, min_trans); |
| 3153 | if (ret == 0) { | 3176 | if (sret == 0) { |
| 3154 | btrfs_release_path(root, path); | 3177 | btrfs_release_path(root, path); |
| 3155 | goto again; | 3178 | goto again; |
| 3156 | } else { | 3179 | } else { |
| @@ -3351,6 +3374,7 @@ int btrfs_previous_item(struct btrfs_root *root, | |||
| 3351 | { | 3374 | { |
| 3352 | struct btrfs_key found_key; | 3375 | struct btrfs_key found_key; |
| 3353 | struct extent_buffer *leaf; | 3376 | struct extent_buffer *leaf; |
| 3377 | u32 nritems; | ||
| 3354 | int ret; | 3378 | int ret; |
| 3355 | 3379 | ||
| 3356 | while(1) { | 3380 | while(1) { |
| @@ -3362,9 +3386,20 @@ int btrfs_previous_item(struct btrfs_root *root, | |||
| 3362 | path->slots[0]--; | 3386 | path->slots[0]--; |
| 3363 | } | 3387 | } |
| 3364 | leaf = path->nodes[0]; | 3388 | leaf = path->nodes[0]; |
| 3389 | nritems = btrfs_header_nritems(leaf); | ||
| 3390 | if (nritems == 0) | ||
| 3391 | return 1; | ||
| 3392 | if (path->slots[0] == nritems) | ||
| 3393 | path->slots[0]--; | ||
| 3394 | |||
| 3365 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 3395 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
| 3366 | if (found_key.type == type) | 3396 | if (found_key.type == type) |
| 3367 | return 0; | 3397 | return 0; |
| 3398 | if (found_key.objectid < min_objectid) | ||
| 3399 | break; | ||
| 3400 | if (found_key.objectid == min_objectid && | ||
| 3401 | found_key.type < type) | ||
| 3402 | break; | ||
| 3368 | } | 3403 | } |
| 3369 | return 1; | 3404 | return 1; |
| 3370 | } | 3405 | } |
