aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-10-15 16:15:19 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:56 -0400
commit96b5179d0d9b6368c203856f2ad6e8e12a8b2a2c (patch)
tree58b22f106bb06902c280c66af661d9e9d6a65597 /fs/btrfs/extent-tree.c
parentf510cfecfc98759d75283823cfccf0cc0d59a4c6 (diff)
Btrfs: Stop using radix trees for the block group cache
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c362
1 files changed, 148 insertions, 214 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 74cfbee2ff33..4bc639565d1c 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -22,6 +22,10 @@
22#include "print-tree.h" 22#include "print-tree.h"
23#include "transaction.h" 23#include "transaction.h"
24 24
25#define BLOCK_GROUP_DATA EXTENT_WRITEBACK
26#define BLOCK_GROUP_METADATA EXTENT_UPTODATE
27#define BLOCK_GROUP_DIRTY EXTENT_DIRTY
28
25static int finish_current_insert(struct btrfs_trans_handle *trans, struct 29static int finish_current_insert(struct btrfs_trans_handle *trans, struct
26 btrfs_root *extent_root); 30 btrfs_root *extent_root);
27static int del_pending_extents(struct btrfs_trans_handle *trans, struct 31static int del_pending_extents(struct btrfs_trans_handle *trans, struct
@@ -127,25 +131,31 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct
127 btrfs_fs_info *info, 131 btrfs_fs_info *info,
128 u64 blocknr) 132 u64 blocknr)
129{ 133{
130 struct btrfs_block_group_cache *block_group; 134 struct extent_map_tree *block_group_cache;
135 struct btrfs_block_group_cache *block_group = NULL;
136 u64 ptr;
137 u64 start;
138 u64 end;
131 int ret; 139 int ret;
132 140
133 ret = radix_tree_gang_lookup(&info->block_group_radix, 141 block_group_cache = &info->block_group_cache;
134 (void **)&block_group, 142 ret = find_first_extent_bit(block_group_cache,
135 blocknr, 1); 143 blocknr, &start, &end,
144 BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA);
136 if (ret) { 145 if (ret) {
137 if (block_group->key.objectid <= blocknr && blocknr <= 146 return NULL;
138 block_group->key.objectid + block_group->key.offset)
139 return block_group;
140 }
141 ret = radix_tree_gang_lookup(&info->block_group_data_radix,
142 (void **)&block_group,
143 blocknr, 1);
144 if (ret) {
145 if (block_group->key.objectid <= blocknr && blocknr <=
146 block_group->key.objectid + block_group->key.offset)
147 return block_group;
148 } 147 }
148 ret = get_state_private(block_group_cache, start, &ptr);
149 if (ret)
150 return NULL;
151
152 block_group = (struct btrfs_block_group_cache *)ptr;
153
154
155 if (block_group->key.objectid <= blocknr && blocknr <=
156 block_group->key.objectid + block_group->key.offset)
157 return block_group;
158
149 return NULL; 159 return NULL;
150} 160}
151 161
@@ -173,7 +183,7 @@ again:
173 last = end + 1; 183 last = end + 1;
174 if (end + 1 - start < num) 184 if (end + 1 - start < num)
175 continue; 185 continue;
176 if (start + num > cache->key.objectid + cache->key.offset) 186 if (start + num >= cache->key.objectid + cache->key.offset)
177 goto new_group; 187 goto new_group;
178 return start; 188 return start;
179 } 189 }
@@ -189,6 +199,7 @@ new_group:
189 cache = btrfs_find_block_group(root, cache, 199 cache = btrfs_find_block_group(root, cache,
190 last + cache->key.offset - 1, data, 0); 200 last + cache->key.offset - 1, data, 0);
191 *cache_ret = cache; 201 *cache_ret = cache;
202 last = min(cache->key.objectid, last);
192 goto again; 203 goto again;
193} 204}
194 205
@@ -204,30 +215,32 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
204 *hint, u64 search_start, 215 *hint, u64 search_start,
205 int data, int owner) 216 int data, int owner)
206{ 217{
207 struct btrfs_block_group_cache *cache[8]; 218 struct btrfs_block_group_cache *cache;
219 struct extent_map_tree *block_group_cache;
208 struct btrfs_block_group_cache *found_group = NULL; 220 struct btrfs_block_group_cache *found_group = NULL;
209 struct btrfs_fs_info *info = root->fs_info; 221 struct btrfs_fs_info *info = root->fs_info;
210 struct radix_tree_root *radix;
211 struct radix_tree_root *swap_radix;
212 u64 used; 222 u64 used;
213 u64 last = 0; 223 u64 last = 0;
214 u64 hint_last; 224 u64 hint_last;
215 int i; 225 u64 start;
226 u64 end;
227 u64 free_check;
228 u64 ptr;
229 int bit;
216 int ret; 230 int ret;
217 int full_search = 0; 231 int full_search = 0;
218 int factor = 8; 232 int factor = 8;
219 int data_swap = 0; 233 int data_swap = 0;
220 234
235 block_group_cache = &info->block_group_cache;
236
221 if (!owner) 237 if (!owner)
222 factor = 5; 238 factor = 5;
223 239
224 if (data) { 240 if (data)
225 radix = &info->block_group_data_radix; 241 bit = BLOCK_GROUP_DATA;
226 swap_radix = &info->block_group_radix; 242 else
227 } else { 243 bit = BLOCK_GROUP_METADATA;
228 radix = &info->block_group_radix;
229 swap_radix = &info->block_group_data_radix;
230 }
231 244
232 if (search_start) { 245 if (search_start) {
233 struct btrfs_block_group_cache *shint; 246 struct btrfs_block_group_cache *shint;
@@ -246,12 +259,6 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
246 div_factor(hint->key.offset, factor)) { 259 div_factor(hint->key.offset, factor)) {
247 return hint; 260 return hint;
248 } 261 }
249 if (used >= div_factor(hint->key.offset, 8)) {
250 radix_tree_tag_clear(radix,
251 hint->key.objectid +
252 hint->key.offset - 1,
253 BTRFS_BLOCK_GROUP_AVAIL);
254 }
255 last = hint->key.offset * 3; 262 last = hint->key.offset * 3;
256 if (hint->key.objectid >= last) 263 if (hint->key.objectid >= last)
257 last = max(search_start + hint->key.offset - 1, 264 last = max(search_start + hint->key.offset - 1,
@@ -267,51 +274,29 @@ struct btrfs_block_group_cache *btrfs_find_block_group(struct btrfs_root *root,
267 274
268 last = hint_last; 275 last = hint_last;
269 } 276 }
270 while(1) {
271 ret = radix_tree_gang_lookup_tag(radix, (void **)cache,
272 last, ARRAY_SIZE(cache),
273 BTRFS_BLOCK_GROUP_AVAIL);
274 if (!ret)
275 break;
276 for (i = 0; i < ret; i++) {
277 last = cache[i]->key.objectid +
278 cache[i]->key.offset;
279 used = btrfs_block_group_used(&cache[i]->item);
280 if (used + cache[i]->pinned <
281 div_factor(cache[i]->key.offset, factor)) {
282 found_group = cache[i];
283 goto found;
284 }
285 if (used >= div_factor(cache[i]->key.offset, 8)) {
286 radix_tree_tag_clear(radix,
287 cache[i]->key.objectid +
288 cache[i]->key.offset - 1,
289 BTRFS_BLOCK_GROUP_AVAIL);
290 }
291 }
292 cond_resched();
293 }
294 last = hint_last;
295again: 277again:
296 while(1) { 278 while(1) {
297 ret = radix_tree_gang_lookup(radix, (void **)cache, 279 ret = find_first_extent_bit(block_group_cache, last,
298 last, ARRAY_SIZE(cache)); 280 &start, &end, bit);
299 if (!ret) 281 if (ret)
300 break; 282 break;
301 for (i = 0; i < ret; i++) { 283
302 last = cache[i]->key.objectid + 284 ret = get_state_private(block_group_cache, start, &ptr);
303 cache[i]->key.offset; 285 if (ret)
304 used = btrfs_block_group_used(&cache[i]->item); 286 break;
305 if (used + cache[i]->pinned < cache[i]->key.offset) { 287
306 found_group = cache[i]; 288 cache = (struct btrfs_block_group_cache *)ptr;
307 goto found; 289 last = cache->key.objectid + cache->key.offset;
308 } 290 used = btrfs_block_group_used(&cache->item);
309 if (used >= cache[i]->key.offset) { 291
310 radix_tree_tag_clear(radix, 292 if (full_search)
311 cache[i]->key.objectid + 293 free_check = cache->key.offset;
312 cache[i]->key.offset - 1, 294 else
313 BTRFS_BLOCK_GROUP_AVAIL); 295 free_check = div_factor(cache->key.offset, factor);
314 } 296
297 if (used + cache->pinned < free_check) {
298 found_group = cache;
299 goto found;
315 } 300 }
316 cond_resched(); 301 cond_resched();
317 } 302 }
@@ -321,23 +306,11 @@ again:
321 goto again; 306 goto again;
322 } 307 }
323 if (!data_swap) { 308 if (!data_swap) {
324 struct radix_tree_root *tmp = radix;
325 data_swap = 1; 309 data_swap = 1;
326 radix = swap_radix; 310 bit = BLOCK_GROUP_DATA | BLOCK_GROUP_METADATA;
327 swap_radix = tmp;
328 last = search_start; 311 last = search_start;
329 goto again; 312 goto again;
330 } 313 }
331 if (!found_group) {
332 ret = radix_tree_gang_lookup(radix,
333 (void **)&found_group, 0, 1);
334 if (ret == 0) {
335 ret = radix_tree_gang_lookup(swap_radix,
336 (void **)&found_group,
337 0, 1);
338 }
339 BUG_ON(ret != 1);
340 }
341found: 314found:
342 return found_group; 315 return found_group;
343} 316}
@@ -538,68 +511,55 @@ fail:
538 511
539} 512}
540 513
541static int write_dirty_block_radix(struct btrfs_trans_handle *trans, 514int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
542 struct btrfs_root *root, 515 struct btrfs_root *root)
543 struct radix_tree_root *radix)
544{ 516{
545 struct btrfs_block_group_cache *cache[8]; 517 struct extent_map_tree *block_group_cache;
518 struct btrfs_block_group_cache *cache;
546 int ret; 519 int ret;
547 int err = 0; 520 int err = 0;
548 int werr = 0; 521 int werr = 0;
549 int i;
550 struct btrfs_path *path; 522 struct btrfs_path *path;
551 unsigned long off = 0; 523 u64 last = 0;
524 u64 start;
525 u64 end;
526 u64 ptr;
552 527
528 block_group_cache = &root->fs_info->block_group_cache;
553 path = btrfs_alloc_path(); 529 path = btrfs_alloc_path();
554 if (!path) 530 if (!path)
555 return -ENOMEM; 531 return -ENOMEM;
556 532
557 while(1) { 533 while(1) {
558 ret = radix_tree_gang_lookup_tag(radix, (void **)cache, 534 ret = find_first_extent_bit(block_group_cache, last,
559 off, ARRAY_SIZE(cache), 535 &start, &end, BLOCK_GROUP_DIRTY);
560 BTRFS_BLOCK_GROUP_DIRTY); 536 if (ret)
561 if (!ret)
562 break; 537 break;
563 for (i = 0; i < ret; i++) {
564 err = write_one_cache_group(trans, root,
565 path, cache[i]);
566 /*
567 * if we fail to write the cache group, we want
568 * to keep it marked dirty in hopes that a later
569 * write will work
570 */
571 if (err) {
572 werr = err;
573 off = cache[i]->key.objectid +
574 cache[i]->key.offset;
575 continue;
576 }
577 538
578 radix_tree_tag_clear(radix, cache[i]->key.objectid + 539 last = end + 1;
579 cache[i]->key.offset - 1, 540 ret = get_state_private(block_group_cache, start, &ptr);
580 BTRFS_BLOCK_GROUP_DIRTY); 541 if (ret)
542 break;
543
544 cache = (struct btrfs_block_group_cache *)ptr;
545 err = write_one_cache_group(trans, root,
546 path, cache);
547 /*
548 * if we fail to write the cache group, we want
549 * to keep it marked dirty in hopes that a later
550 * write will work
551 */
552 if (err) {
553 werr = err;
554 continue;
581 } 555 }
556 clear_extent_bits(block_group_cache, start, end,
557 BLOCK_GROUP_DIRTY, GFP_NOFS);
582 } 558 }
583 btrfs_free_path(path); 559 btrfs_free_path(path);
584 return werr; 560 return werr;
585} 561}
586 562
587int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans,
588 struct btrfs_root *root)
589{
590 int ret;
591 int ret2;
592 ret = write_dirty_block_radix(trans, root,
593 &root->fs_info->block_group_radix);
594 ret2 = write_dirty_block_radix(trans, root,
595 &root->fs_info->block_group_data_radix);
596 if (ret)
597 return ret;
598 if (ret2)
599 return ret2;
600 return 0;
601}
602
603static int update_block_group(struct btrfs_trans_handle *trans, 563static int update_block_group(struct btrfs_trans_handle *trans,
604 struct btrfs_root *root, 564 struct btrfs_root *root,
605 u64 blocknr, u64 num, int alloc, int mark_free, 565 u64 blocknr, u64 num, int alloc, int mark_free,
@@ -610,7 +570,8 @@ static int update_block_group(struct btrfs_trans_handle *trans,
610 u64 total = num; 570 u64 total = num;
611 u64 old_val; 571 u64 old_val;
612 u64 block_in_group; 572 u64 block_in_group;
613 int ret; 573 u64 start;
574 u64 end;
614 575
615 while(total) { 576 while(total) {
616 cache = btrfs_lookup_block_group(info, blocknr); 577 cache = btrfs_lookup_block_group(info, blocknr);
@@ -619,9 +580,10 @@ static int update_block_group(struct btrfs_trans_handle *trans,
619 } 580 }
620 block_in_group = blocknr - cache->key.objectid; 581 block_in_group = blocknr - cache->key.objectid;
621 WARN_ON(block_in_group > cache->key.offset); 582 WARN_ON(block_in_group > cache->key.offset);
622 radix_tree_tag_set(cache->radix, cache->key.objectid + 583 start = cache->key.objectid;
623 cache->key.offset - 1, 584 end = start + cache->key.offset - 1;
624 BTRFS_BLOCK_GROUP_DIRTY); 585 set_extent_bits(&info->block_group_cache, start, end,
586 BLOCK_GROUP_DIRTY, GFP_NOFS);
625 587
626 old_val = btrfs_block_group_used(&cache->item); 588 old_val = btrfs_block_group_used(&cache->item);
627 num = min(total, cache->key.offset - block_in_group); 589 num = min(total, cache->key.offset - block_in_group);
@@ -630,25 +592,27 @@ static int update_block_group(struct btrfs_trans_handle *trans,
630 cache->last_alloc = blocknr; 592 cache->last_alloc = blocknr;
631 if (cache->data != data && 593 if (cache->data != data &&
632 old_val < (cache->key.offset >> 1)) { 594 old_val < (cache->key.offset >> 1)) {
633 cache->data = data; 595 int bit_to_clear;
634 radix_tree_delete(cache->radix, 596 int bit_to_set;
635 cache->key.objectid +
636 cache->key.offset - 1);
637 597
598 cache->data = data;
638 if (data) { 599 if (data) {
639 cache->radix = 600 bit_to_clear = BLOCK_GROUP_DATA;
640 &info->block_group_data_radix; 601 bit_to_set = BLOCK_GROUP_METADATA;
641 cache->item.flags |= 602 cache->item.flags |=
642 BTRFS_BLOCK_GROUP_DATA; 603 BTRFS_BLOCK_GROUP_DATA;
643 } else { 604 } else {
644 cache->radix = &info->block_group_radix; 605 bit_to_clear = BLOCK_GROUP_METADATA;
606 bit_to_set = BLOCK_GROUP_DATA;
645 cache->item.flags &= 607 cache->item.flags &=
646 ~BTRFS_BLOCK_GROUP_DATA; 608 ~BTRFS_BLOCK_GROUP_DATA;
647 } 609 }
648 ret = radix_tree_insert(cache->radix, 610 clear_extent_bits(&info->block_group_cache,
649 cache->key.objectid + 611 start, end, bit_to_clear,
650 cache->key.offset - 1, 612 GFP_NOFS);
651 (void *)cache); 613 set_extent_bits(&info->block_group_cache,
614 start, end, bit_to_set,
615 GFP_NOFS);
652 } 616 }
653 old_val += num; 617 old_val += num;
654 } else { 618 } else {
@@ -660,13 +624,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
660 blocknr, blocknr + num - 1, 624 blocknr, blocknr + num - 1,
661 GFP_NOFS); 625 GFP_NOFS);
662 } 626 }
663 if (old_val < (cache->key.offset >> 1) &&
664 old_val + num >= (cache->key.offset >> 1)) {
665 radix_tree_tag_set(cache->radix,
666 cache->key.objectid +
667 cache->key.offset - 1,
668 BTRFS_BLOCK_GROUP_AVAIL);
669 }
670 } 627 }
671 btrfs_set_block_group_used(&cache->item, old_val); 628 btrfs_set_block_group_used(&cache->item, old_val);
672 total -= num; 629 total -= num;
@@ -730,11 +687,8 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
730 block_group->pinned--; 687 block_group->pinned--;
731 if (gang[i] < block_group->last_alloc) 688 if (gang[i] < block_group->last_alloc)
732 block_group->last_alloc = gang[i]; 689 block_group->last_alloc = gang[i];
733 if (!block_group->data) { 690 set_extent_dirty(free_space_cache,
734 set_extent_dirty(free_space_cache, 691 gang[i], gang[i], GFP_NOFS);
735 gang[i], gang[i],
736 GFP_NOFS);
737 }
738 } 692 }
739 } 693 }
740 } 694 }
@@ -1059,8 +1013,8 @@ check_failed:
1059 ins->offset = search_end - ins->objectid; 1013 ins->offset = search_end - ins->objectid;
1060 goto check_pending; 1014 goto check_pending;
1061 } 1015 }
1062
1063 btrfs_item_key_to_cpu(l, &key, slot); 1016 btrfs_item_key_to_cpu(l, &key, slot);
1017
1064 if (key.objectid >= search_start && key.objectid > last_block && 1018 if (key.objectid >= search_start && key.objectid > last_block &&
1065 start_found) { 1019 start_found) {
1066 if (last_block < search_start) 1020 if (last_block < search_start)
@@ -1072,9 +1026,14 @@ check_failed:
1072 goto check_pending; 1026 goto check_pending;
1073 } 1027 }
1074 } 1028 }
1075 1029 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) {
1076 if (btrfs_key_type(&key) != BTRFS_EXTENT_ITEM_KEY) 1030 if (!start_found) {
1031 last_block = key.objectid;
1032 start_found = 1;
1033 }
1077 goto next; 1034 goto next;
1035 }
1036
1078 1037
1079 start_found = 1; 1038 start_found = 1;
1080 last_block = key.objectid + key.offset; 1039 last_block = key.objectid + key.offset;
@@ -1120,9 +1079,6 @@ check_pending:
1120 } 1079 }
1121 ins->offset = num_blocks; 1080 ins->offset = num_blocks;
1122 btrfs_free_path(path); 1081 btrfs_free_path(path);
1123 if (0 && ins->objectid != cached_search_start) {
1124printk("\tcached was %Lu found %Lu\n", cached_search_start, ins->objectid);
1125 }
1126 return 0; 1082 return 0;
1127 1083
1128new_group: 1084new_group:
@@ -1529,40 +1485,20 @@ out:
1529 return ret; 1485 return ret;
1530} 1486}
1531 1487
1532static int free_block_group_radix(struct radix_tree_root *radix) 1488int btrfs_free_block_groups(struct btrfs_fs_info *info)
1533{ 1489{
1490 u64 start;
1491 u64 end;
1534 int ret; 1492 int ret;
1535 struct btrfs_block_group_cache *cache[8];
1536 int i;
1537 1493
1538 while(1) { 1494 while(1) {
1539 ret = radix_tree_gang_lookup(radix, (void **)cache, 0, 1495 ret = find_first_extent_bit(&info->block_group_cache, 0,
1540 ARRAY_SIZE(cache)); 1496 &start, &end, (unsigned int)-1);
1541 if (!ret) 1497 if (ret)
1542 break; 1498 break;
1543 for (i = 0; i < ret; i++) { 1499 clear_extent_bits(&info->block_group_cache, start,
1544 radix_tree_delete(radix, cache[i]->key.objectid + 1500 end, (unsigned int)-1, GFP_NOFS);
1545 cache[i]->key.offset - 1);
1546 kfree(cache[i]);
1547 }
1548 } 1501 }
1549 return 0;
1550}
1551
1552int btrfs_free_block_groups(struct btrfs_fs_info *info)
1553{
1554 int ret;
1555 int ret2;
1556 u64 start;
1557 u64 end;
1558
1559 ret = free_block_group_radix(&info->block_group_radix);
1560 ret2 = free_block_group_radix(&info->block_group_data_radix);
1561 if (ret)
1562 return ret;
1563 if (ret2)
1564 return ret2;
1565
1566 while(1) { 1502 while(1) {
1567 ret = find_first_extent_bit(&info->free_space_cache, 0, 1503 ret = find_first_extent_bit(&info->free_space_cache, 0,
1568 &start, &end, EXTENT_DIRTY); 1504 &start, &end, EXTENT_DIRTY);
@@ -1579,17 +1515,20 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1579 struct btrfs_path *path; 1515 struct btrfs_path *path;
1580 int ret; 1516 int ret;
1581 int err = 0; 1517 int err = 0;
1518 int bit;
1582 struct btrfs_block_group_cache *cache; 1519 struct btrfs_block_group_cache *cache;
1583 struct btrfs_fs_info *info = root->fs_info; 1520 struct btrfs_fs_info *info = root->fs_info;
1584 struct radix_tree_root *radix; 1521 struct extent_map_tree *block_group_cache;
1585 struct btrfs_key key; 1522 struct btrfs_key key;
1586 struct btrfs_key found_key; 1523 struct btrfs_key found_key;
1587 struct extent_buffer *leaf; 1524 struct extent_buffer *leaf;
1588 u64 group_size_blocks; 1525 u64 group_size_blocks;
1589 u64 used; 1526
1527 block_group_cache = &info->block_group_cache;
1590 1528
1591 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >> 1529 group_size_blocks = BTRFS_BLOCK_GROUP_SIZE >>
1592 root->fs_info->sb->s_blocksize_bits; 1530 info->sb->s_blocksize_bits;
1531
1593 root = info->extent_root; 1532 root = info->extent_root;
1594 key.objectid = 0; 1533 key.objectid = 0;
1595 key.offset = group_size_blocks; 1534 key.offset = group_size_blocks;
@@ -1617,35 +1556,30 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1617 read_extent_buffer(leaf, &cache->item, 1556 read_extent_buffer(leaf, &cache->item,
1618 btrfs_item_ptr_offset(leaf, path->slots[0]), 1557 btrfs_item_ptr_offset(leaf, path->slots[0]),
1619 sizeof(cache->item)); 1558 sizeof(cache->item));
1620 if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) {
1621 radix = &info->block_group_data_radix;
1622 cache->data = 1;
1623 } else {
1624 radix = &info->block_group_radix;
1625 cache->data = 0;
1626 }
1627
1628 memcpy(&cache->key, &found_key, sizeof(found_key)); 1559 memcpy(&cache->key, &found_key, sizeof(found_key));
1629 cache->last_alloc = cache->key.objectid; 1560 cache->last_alloc = cache->key.objectid;
1630 cache->first_free = cache->key.objectid; 1561 cache->first_free = cache->key.objectid;
1631 cache->pinned = 0; 1562 cache->pinned = 0;
1632 cache->cached = 0; 1563 cache->cached = 0;
1633 1564
1634 cache->radix = radix;
1635
1636 key.objectid = found_key.objectid + found_key.offset; 1565 key.objectid = found_key.objectid + found_key.offset;
1637 btrfs_release_path(root, path); 1566 btrfs_release_path(root, path);
1638 1567
1639 ret = radix_tree_insert(radix, found_key.objectid + 1568 if (cache->item.flags & BTRFS_BLOCK_GROUP_DATA) {
1640 found_key.offset - 1, 1569 bit = BLOCK_GROUP_DATA;
1641 (void *)cache); 1570 cache->data = 1;
1642 BUG_ON(ret); 1571 } else {
1643 used = btrfs_block_group_used(&cache->item); 1572 bit = BLOCK_GROUP_METADATA;
1644 if (used < div_factor(key.offset, 8)) { 1573 cache->data = 0;
1645 radix_tree_tag_set(radix, found_key.objectid +
1646 found_key.offset - 1,
1647 BTRFS_BLOCK_GROUP_AVAIL);
1648 } 1574 }
1575
1576 /* use EXTENT_LOCKED to prevent merging */
1577 set_extent_bits(block_group_cache, found_key.objectid,
1578 found_key.objectid + found_key.offset - 1,
1579 bit | EXTENT_LOCKED, GFP_NOFS);
1580 set_state_private(block_group_cache, found_key.objectid,
1581 (u64)cache);
1582
1649 if (key.objectid >= 1583 if (key.objectid >=
1650 btrfs_super_total_blocks(&info->super_copy)) 1584 btrfs_super_total_blocks(&info->super_copy))
1651 break; 1585 break;