diff options
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 135 |
1 files changed, 75 insertions, 60 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4a40282b45f7..c29b92d440e0 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5,12 +5,15 @@ | |||
5 | #include "ctree.h" | 5 | #include "ctree.h" |
6 | #include "disk-io.h" | 6 | #include "disk-io.h" |
7 | #include "print-tree.h" | 7 | #include "print-tree.h" |
8 | #include "transaction.h" | ||
8 | 9 | ||
9 | static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, | 10 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
10 | u64 search_start, u64 search_end, | 11 | *orig_root, u64 num_blocks, u64 search_start, u64 |
11 | struct btrfs_key *ins); | 12 | search_end, struct btrfs_key *ins); |
12 | static int finish_current_insert(struct btrfs_root *extent_root); | 13 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
13 | static int run_pending(struct btrfs_root *extent_root); | 14 | btrfs_root *extent_root); |
15 | static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root | ||
16 | *extent_root); | ||
14 | 17 | ||
15 | /* | 18 | /* |
16 | * pending extents are blocks that we're trying to allocate in the extent | 19 | * pending extents are blocks that we're trying to allocate in the extent |
@@ -21,7 +24,8 @@ static int run_pending(struct btrfs_root *extent_root); | |||
21 | */ | 24 | */ |
22 | #define CTREE_EXTENT_PENDING_DEL 0 | 25 | #define CTREE_EXTENT_PENDING_DEL 0 |
23 | 26 | ||
24 | static int inc_block_ref(struct btrfs_root *root, u64 blocknr) | 27 | static int inc_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root |
28 | *root, u64 blocknr) | ||
25 | { | 29 | { |
26 | struct btrfs_path path; | 30 | struct btrfs_path path; |
27 | int ret; | 31 | int ret; |
@@ -31,13 +35,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr) | |||
31 | struct btrfs_key ins; | 35 | struct btrfs_key ins; |
32 | u32 refs; | 36 | u32 refs; |
33 | 37 | ||
34 | find_free_extent(root->extent_root, 0, 0, (u64)-1, &ins); | 38 | find_free_extent(trans, root->extent_root, 0, 0, (u64)-1, &ins); |
35 | btrfs_init_path(&path); | 39 | btrfs_init_path(&path); |
36 | key.objectid = blocknr; | 40 | key.objectid = blocknr; |
37 | key.flags = 0; | 41 | key.flags = 0; |
38 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 42 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
39 | key.offset = 1; | 43 | key.offset = 1; |
40 | ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 1); | 44 | ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 1); |
41 | if (ret != 0) | 45 | if (ret != 0) |
42 | BUG(); | 46 | BUG(); |
43 | BUG_ON(ret != 0); | 47 | BUG_ON(ret != 0); |
@@ -48,12 +52,13 @@ static int inc_block_ref(struct btrfs_root *root, u64 blocknr) | |||
48 | 52 | ||
49 | BUG_ON(list_empty(&path.nodes[0]->dirty)); | 53 | BUG_ON(list_empty(&path.nodes[0]->dirty)); |
50 | btrfs_release_path(root->extent_root, &path); | 54 | btrfs_release_path(root->extent_root, &path); |
51 | finish_current_insert(root->extent_root); | 55 | finish_current_insert(trans, root->extent_root); |
52 | run_pending(root->extent_root); | 56 | run_pending(trans, root->extent_root); |
53 | return 0; | 57 | return 0; |
54 | } | 58 | } |
55 | 59 | ||
56 | static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs) | 60 | static int lookup_block_ref(struct btrfs_trans_handle *trans, struct btrfs_root |
61 | *root, u64 blocknr, u32 *refs) | ||
57 | { | 62 | { |
58 | struct btrfs_path path; | 63 | struct btrfs_path path; |
59 | int ret; | 64 | int ret; |
@@ -65,7 +70,7 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs) | |||
65 | key.offset = 1; | 70 | key.offset = 1; |
66 | key.flags = 0; | 71 | key.flags = 0; |
67 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 72 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
68 | ret = btrfs_search_slot(root->extent_root, &key, &path, 0, 0); | 73 | ret = btrfs_search_slot(trans, root->extent_root, &key, &path, 0, 0); |
69 | if (ret != 0) | 74 | if (ret != 0) |
70 | BUG(); | 75 | BUG(); |
71 | l = &path.nodes[0]->leaf; | 76 | l = &path.nodes[0]->leaf; |
@@ -75,7 +80,8 @@ static int lookup_block_ref(struct btrfs_root *root, u64 blocknr, u32 *refs) | |||
75 | return 0; | 80 | return 0; |
76 | } | 81 | } |
77 | 82 | ||
78 | int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf) | 83 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
84 | struct btrfs_buffer *buf) | ||
79 | { | 85 | { |
80 | u64 blocknr; | 86 | u64 blocknr; |
81 | int i; | 87 | int i; |
@@ -87,12 +93,13 @@ int btrfs_inc_ref(struct btrfs_root *root, struct btrfs_buffer *buf) | |||
87 | 93 | ||
88 | for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) { | 94 | for (i = 0; i < btrfs_header_nritems(&buf->node.header); i++) { |
89 | blocknr = btrfs_node_blockptr(&buf->node, i); | 95 | blocknr = btrfs_node_blockptr(&buf->node, i); |
90 | inc_block_ref(root, blocknr); | 96 | inc_block_ref(trans, root, blocknr); |
91 | } | 97 | } |
92 | return 0; | 98 | return 0; |
93 | } | 99 | } |
94 | 100 | ||
95 | int btrfs_finish_extent_commit(struct btrfs_root *root) | 101 | int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, struct |
102 | btrfs_root *root) | ||
96 | { | 103 | { |
97 | unsigned long gang[8]; | 104 | unsigned long gang[8]; |
98 | u64 first = 0; | 105 | u64 first = 0; |
@@ -116,7 +123,8 @@ int btrfs_finish_extent_commit(struct btrfs_root *root) | |||
116 | return 0; | 123 | return 0; |
117 | } | 124 | } |
118 | 125 | ||
119 | static int finish_current_insert(struct btrfs_root *extent_root) | 126 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
127 | btrfs_root *extent_root) | ||
120 | { | 128 | { |
121 | struct btrfs_key ins; | 129 | struct btrfs_key ins; |
122 | struct btrfs_extent_item extent_item; | 130 | struct btrfs_extent_item extent_item; |
@@ -132,8 +140,8 @@ static int finish_current_insert(struct btrfs_root *extent_root) | |||
132 | 140 | ||
133 | for (i = 0; i < extent_root->current_insert.flags; i++) { | 141 | for (i = 0; i < extent_root->current_insert.flags; i++) { |
134 | ins.objectid = extent_root->current_insert.objectid + i; | 142 | ins.objectid = extent_root->current_insert.objectid + i; |
135 | ret = btrfs_insert_item(extent_root, &ins, &extent_item, | 143 | ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item, |
136 | sizeof(extent_item)); | 144 | sizeof(extent_item)); |
137 | BUG_ON(ret); | 145 | BUG_ON(ret); |
138 | } | 146 | } |
139 | extent_root->current_insert.offset = 0; | 147 | extent_root->current_insert.offset = 0; |
@@ -143,8 +151,8 @@ static int finish_current_insert(struct btrfs_root *extent_root) | |||
143 | /* | 151 | /* |
144 | * remove an extent from the root, returns 0 on success | 152 | * remove an extent from the root, returns 0 on success |
145 | */ | 153 | */ |
146 | static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | 154 | static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
147 | int pin) | 155 | *root, u64 blocknr, u64 num_blocks, int pin) |
148 | { | 156 | { |
149 | struct btrfs_path path; | 157 | struct btrfs_path path; |
150 | struct btrfs_key key; | 158 | struct btrfs_key key; |
@@ -160,9 +168,9 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | |||
160 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 168 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
161 | key.offset = num_blocks; | 169 | key.offset = num_blocks; |
162 | 170 | ||
163 | find_free_extent(root, 0, 0, (u64)-1, &ins); | 171 | find_free_extent(trans, root, 0, 0, (u64)-1, &ins); |
164 | btrfs_init_path(&path); | 172 | btrfs_init_path(&path); |
165 | ret = btrfs_search_slot(extent_root, &key, &path, -1, 1); | 173 | ret = btrfs_search_slot(trans, extent_root, &key, &path, -1, 1); |
166 | if (ret) { | 174 | if (ret) { |
167 | printf("failed to find %Lu\n", key.objectid); | 175 | printf("failed to find %Lu\n", key.objectid); |
168 | btrfs_print_tree(extent_root, extent_root->node); | 176 | btrfs_print_tree(extent_root, extent_root->node); |
@@ -183,14 +191,14 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | |||
183 | BUG_ON(err); | 191 | BUG_ON(err); |
184 | radix_tree_preload_end(); | 192 | radix_tree_preload_end(); |
185 | } | 193 | } |
186 | ret = btrfs_del_item(extent_root, &path); | 194 | ret = btrfs_del_item(trans, extent_root, &path); |
187 | if (!pin && extent_root->last_insert.objectid > blocknr) | 195 | if (!pin && extent_root->last_insert.objectid > blocknr) |
188 | extent_root->last_insert.objectid = blocknr; | 196 | extent_root->last_insert.objectid = blocknr; |
189 | if (ret) | 197 | if (ret) |
190 | BUG(); | 198 | BUG(); |
191 | } | 199 | } |
192 | btrfs_release_path(extent_root, &path); | 200 | btrfs_release_path(extent_root, &path); |
193 | finish_current_insert(extent_root); | 201 | finish_current_insert(trans, extent_root); |
194 | return ret; | 202 | return ret; |
195 | } | 203 | } |
196 | 204 | ||
@@ -198,7 +206,8 @@ static int __free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | |||
198 | * find all the blocks marked as pending in the radix tree and remove | 206 | * find all the blocks marked as pending in the radix tree and remove |
199 | * them from the extent map | 207 | * them from the extent map |
200 | */ | 208 | */ |
201 | static int del_pending_extents(struct btrfs_root *extent_root) | 209 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct |
210 | btrfs_root *extent_root) | ||
202 | { | 211 | { |
203 | int ret; | 212 | int ret; |
204 | struct btrfs_buffer *gang[4]; | 213 | struct btrfs_buffer *gang[4]; |
@@ -212,7 +221,7 @@ static int del_pending_extents(struct btrfs_root *extent_root) | |||
212 | if (!ret) | 221 | if (!ret) |
213 | break; | 222 | break; |
214 | for (i = 0; i < ret; i++) { | 223 | for (i = 0; i < ret; i++) { |
215 | ret = __free_extent(extent_root, | 224 | ret = __free_extent(trans, extent_root, |
216 | gang[i]->blocknr, 1, 1); | 225 | gang[i]->blocknr, 1, 1); |
217 | radix_tree_tag_clear(&extent_root->cache_radix, | 226 | radix_tree_tag_clear(&extent_root->cache_radix, |
218 | gang[i]->blocknr, | 227 | gang[i]->blocknr, |
@@ -223,11 +232,12 @@ static int del_pending_extents(struct btrfs_root *extent_root) | |||
223 | return 0; | 232 | return 0; |
224 | } | 233 | } |
225 | 234 | ||
226 | static int run_pending(struct btrfs_root *extent_root) | 235 | static int run_pending(struct btrfs_trans_handle *trans, struct btrfs_root |
236 | *extent_root) | ||
227 | { | 237 | { |
228 | while(radix_tree_tagged(&extent_root->cache_radix, | 238 | while(radix_tree_tagged(&extent_root->cache_radix, |
229 | CTREE_EXTENT_PENDING_DEL)) | 239 | CTREE_EXTENT_PENDING_DEL)) |
230 | del_pending_extents(extent_root); | 240 | del_pending_extents(trans, extent_root); |
231 | return 0; | 241 | return 0; |
232 | } | 242 | } |
233 | 243 | ||
@@ -235,8 +245,8 @@ static int run_pending(struct btrfs_root *extent_root) | |||
235 | /* | 245 | /* |
236 | * remove an extent from the root, returns 0 on success | 246 | * remove an extent from the root, returns 0 on success |
237 | */ | 247 | */ |
238 | int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | 248 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
239 | int pin) | 249 | *root, u64 blocknr, u64 num_blocks, int pin) |
240 | { | 250 | { |
241 | struct btrfs_root *extent_root = root->extent_root; | 251 | struct btrfs_root *extent_root = root->extent_root; |
242 | struct btrfs_buffer *t; | 252 | struct btrfs_buffer *t; |
@@ -249,8 +259,8 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | |||
249 | CTREE_EXTENT_PENDING_DEL); | 259 | CTREE_EXTENT_PENDING_DEL); |
250 | return 0; | 260 | return 0; |
251 | } | 261 | } |
252 | ret = __free_extent(root, blocknr, num_blocks, pin); | 262 | ret = __free_extent(trans, root, blocknr, num_blocks, pin); |
253 | pending_ret = run_pending(root->extent_root); | 263 | pending_ret = run_pending(trans, root->extent_root); |
254 | return ret ? ret : pending_ret; | 264 | return ret ? ret : pending_ret; |
255 | } | 265 | } |
256 | 266 | ||
@@ -262,9 +272,9 @@ int btrfs_free_extent(struct btrfs_root *root, u64 blocknr, u64 num_blocks, | |||
262 | * ins->offset == number of blocks | 272 | * ins->offset == number of blocks |
263 | * Any available blocks before search_start are skipped. | 273 | * Any available blocks before search_start are skipped. |
264 | */ | 274 | */ |
265 | static int find_free_extent(struct btrfs_root *orig_root, u64 num_blocks, | 275 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
266 | u64 search_start, u64 search_end, | 276 | *orig_root, u64 num_blocks, u64 search_start, u64 |
267 | struct btrfs_key *ins) | 277 | search_end, struct btrfs_key *ins) |
268 | { | 278 | { |
269 | struct btrfs_path path; | 279 | struct btrfs_path path; |
270 | struct btrfs_key key; | 280 | struct btrfs_key key; |
@@ -290,7 +300,7 @@ check_failed: | |||
290 | ins->objectid = search_start; | 300 | ins->objectid = search_start; |
291 | ins->offset = 0; | 301 | ins->offset = 0; |
292 | start_found = 0; | 302 | start_found = 0; |
293 | ret = btrfs_search_slot(root, ins, &path, 0, 0); | 303 | ret = btrfs_search_slot(trans, root, ins, &path, 0, 0); |
294 | if (ret < 0) | 304 | if (ret < 0) |
295 | goto error; | 305 | goto error; |
296 | 306 | ||
@@ -367,9 +377,9 @@ error: | |||
367 | * | 377 | * |
368 | * returns 0 if everything worked, non-zero otherwise. | 378 | * returns 0 if everything worked, non-zero otherwise. |
369 | */ | 379 | */ |
370 | static int alloc_extent(struct btrfs_root *root, u64 num_blocks, | 380 | static int alloc_extent(struct btrfs_trans_handle *trans, struct btrfs_root |
371 | u64 search_start, u64 search_end, u64 owner, | 381 | *root, u64 num_blocks, u64 search_start, u64 |
372 | struct btrfs_key *ins) | 382 | search_end, u64 owner, struct btrfs_key *ins) |
373 | { | 383 | { |
374 | int ret; | 384 | int ret; |
375 | int pending_ret; | 385 | int pending_ret; |
@@ -389,16 +399,16 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks, | |||
389 | extent_root->current_insert.flags++; | 399 | extent_root->current_insert.flags++; |
390 | return 0; | 400 | return 0; |
391 | } | 401 | } |
392 | ret = find_free_extent(root, num_blocks, search_start, | 402 | ret = find_free_extent(trans, root, num_blocks, search_start, |
393 | search_end, ins); | 403 | search_end, ins); |
394 | if (ret) | 404 | if (ret) |
395 | return ret; | 405 | return ret; |
396 | 406 | ||
397 | ret = btrfs_insert_item(extent_root, ins, &extent_item, | 407 | ret = btrfs_insert_item(trans, extent_root, ins, &extent_item, |
398 | sizeof(extent_item)); | 408 | sizeof(extent_item)); |
399 | 409 | ||
400 | finish_current_insert(extent_root); | 410 | finish_current_insert(trans, extent_root); |
401 | pending_ret = run_pending(extent_root); | 411 | pending_ret = run_pending(trans, extent_root); |
402 | if (ret) | 412 | if (ret) |
403 | return ret; | 413 | return ret; |
404 | if (pending_ret) | 414 | if (pending_ret) |
@@ -410,13 +420,14 @@ static int alloc_extent(struct btrfs_root *root, u64 num_blocks, | |||
410 | * helper function to allocate a block for a given tree | 420 | * helper function to allocate a block for a given tree |
411 | * returns the tree buffer or NULL. | 421 | * returns the tree buffer or NULL. |
412 | */ | 422 | */ |
413 | struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root) | 423 | struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, |
424 | struct btrfs_root *root) | ||
414 | { | 425 | { |
415 | struct btrfs_key ins; | 426 | struct btrfs_key ins; |
416 | int ret; | 427 | int ret; |
417 | struct btrfs_buffer *buf; | 428 | struct btrfs_buffer *buf; |
418 | 429 | ||
419 | ret = alloc_extent(root, 1, 0, (unsigned long)-1, | 430 | ret = alloc_extent(trans, root, 1, 0, (unsigned long)-1, |
420 | btrfs_header_parentid(&root->node->node.header), | 431 | btrfs_header_parentid(&root->node->node.header), |
421 | &ins); | 432 | &ins); |
422 | if (ret) { | 433 | if (ret) { |
@@ -424,7 +435,7 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root) | |||
424 | return NULL; | 435 | return NULL; |
425 | } | 436 | } |
426 | buf = find_tree_block(root, ins.objectid); | 437 | buf = find_tree_block(root, ins.objectid); |
427 | dirty_tree_block(root, buf); | 438 | dirty_tree_block(trans, root, buf); |
428 | return buf; | 439 | return buf; |
429 | } | 440 | } |
430 | 441 | ||
@@ -432,8 +443,8 @@ struct btrfs_buffer *btrfs_alloc_free_block(struct btrfs_root *root) | |||
432 | * helper function for drop_snapshot, this walks down the tree dropping ref | 443 | * helper function for drop_snapshot, this walks down the tree dropping ref |
433 | * counts as it goes. | 444 | * counts as it goes. |
434 | */ | 445 | */ |
435 | static int walk_down_tree(struct btrfs_root *root, | 446 | static int walk_down_tree(struct btrfs_trans_handle *trans, struct btrfs_root |
436 | struct btrfs_path *path, int *level) | 447 | *root, struct btrfs_path *path, int *level) |
437 | { | 448 | { |
438 | struct btrfs_buffer *next; | 449 | struct btrfs_buffer *next; |
439 | struct btrfs_buffer *cur; | 450 | struct btrfs_buffer *cur; |
@@ -441,7 +452,8 @@ static int walk_down_tree(struct btrfs_root *root, | |||
441 | int ret; | 452 | int ret; |
442 | u32 refs; | 453 | u32 refs; |
443 | 454 | ||
444 | ret = lookup_block_ref(root, path->nodes[*level]->blocknr, &refs); | 455 | ret = lookup_block_ref(trans, root, path->nodes[*level]->blocknr, |
456 | &refs); | ||
445 | BUG_ON(ret); | 457 | BUG_ON(ret); |
446 | if (refs > 1) | 458 | if (refs > 1) |
447 | goto out; | 459 | goto out; |
@@ -454,10 +466,10 @@ static int walk_down_tree(struct btrfs_root *root, | |||
454 | btrfs_header_nritems(&cur->node.header)) | 466 | btrfs_header_nritems(&cur->node.header)) |
455 | break; | 467 | break; |
456 | blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]); | 468 | blocknr = btrfs_node_blockptr(&cur->node, path->slots[*level]); |
457 | ret = lookup_block_ref(root, blocknr, &refs); | 469 | ret = lookup_block_ref(trans, root, blocknr, &refs); |
458 | if (refs != 1 || *level == 1) { | 470 | if (refs != 1 || *level == 1) { |
459 | path->slots[*level]++; | 471 | path->slots[*level]++; |
460 | ret = btrfs_free_extent(root, blocknr, 1, 1); | 472 | ret = btrfs_free_extent(trans, root, blocknr, 1, 1); |
461 | BUG_ON(ret); | 473 | BUG_ON(ret); |
462 | continue; | 474 | continue; |
463 | } | 475 | } |
@@ -470,7 +482,8 @@ static int walk_down_tree(struct btrfs_root *root, | |||
470 | path->slots[*level] = 0; | 482 | path->slots[*level] = 0; |
471 | } | 483 | } |
472 | out: | 484 | out: |
473 | ret = btrfs_free_extent(root, path->nodes[*level]->blocknr, 1, 1); | 485 | ret = btrfs_free_extent(trans, root, path->nodes[*level]->blocknr, 1, |
486 | 1); | ||
474 | btrfs_block_release(root, path->nodes[*level]); | 487 | btrfs_block_release(root, path->nodes[*level]); |
475 | path->nodes[*level] = NULL; | 488 | path->nodes[*level] = NULL; |
476 | *level += 1; | 489 | *level += 1; |
@@ -483,8 +496,8 @@ out: | |||
483 | * to find the first node higher up where we haven't yet gone through | 496 | * to find the first node higher up where we haven't yet gone through |
484 | * all the slots | 497 | * all the slots |
485 | */ | 498 | */ |
486 | static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, | 499 | static int walk_up_tree(struct btrfs_trans_handle *trans, struct btrfs_root |
487 | int *level) | 500 | *root, struct btrfs_path *path, int *level) |
488 | { | 501 | { |
489 | int i; | 502 | int i; |
490 | int slot; | 503 | int slot; |
@@ -497,8 +510,9 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, | |||
497 | *level = i; | 510 | *level = i; |
498 | return 0; | 511 | return 0; |
499 | } else { | 512 | } else { |
500 | ret = btrfs_free_extent(root, | 513 | ret = btrfs_free_extent(trans, root, |
501 | path->nodes[*level]->blocknr, 1, 1); | 514 | path->nodes[*level]->blocknr, |
515 | 1, 1); | ||
502 | btrfs_block_release(root, path->nodes[*level]); | 516 | btrfs_block_release(root, path->nodes[*level]); |
503 | path->nodes[*level] = NULL; | 517 | path->nodes[*level] = NULL; |
504 | *level = i + 1; | 518 | *level = i + 1; |
@@ -513,7 +527,8 @@ static int walk_up_tree(struct btrfs_root *root, struct btrfs_path *path, | |||
513 | * the tree freeing any blocks that have a ref count of zero after being | 527 | * the tree freeing any blocks that have a ref count of zero after being |
514 | * decremented. | 528 | * decremented. |
515 | */ | 529 | */ |
516 | int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap) | 530 | int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root |
531 | *root, struct btrfs_buffer *snap) | ||
517 | { | 532 | { |
518 | int ret = 0; | 533 | int ret = 0; |
519 | int wret; | 534 | int wret; |
@@ -529,13 +544,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, struct btrfs_buffer *snap) | |||
529 | path.nodes[level] = snap; | 544 | path.nodes[level] = snap; |
530 | path.slots[level] = 0; | 545 | path.slots[level] = 0; |
531 | while(1) { | 546 | while(1) { |
532 | wret = walk_down_tree(root, &path, &level); | 547 | wret = walk_down_tree(trans, root, &path, &level); |
533 | if (wret > 0) | 548 | if (wret > 0) |
534 | break; | 549 | break; |
535 | if (wret < 0) | 550 | if (wret < 0) |
536 | ret = wret; | 551 | ret = wret; |
537 | 552 | ||
538 | wret = walk_up_tree(root, &path, &level); | 553 | wret = walk_up_tree(trans, root, &path, &level); |
539 | if (wret > 0) | 554 | if (wret > 0) |
540 | break; | 555 | break; |
541 | if (wret < 0) | 556 | if (wret < 0) |