aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-05-07 20:03:49 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-05-07 20:03:49 -0400
commit3e1ad54fe2839319c1aa66b954da0753f5b1f906 (patch)
tree1e9d98508e9d4d569e73c51617b5167ef0910541 /fs/btrfs/extent-tree.c
parentbe74417553f4b2ee46be2088007a674ef2f02330 (diff)
Btrfs: allocator and tuning
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c75
1 files changed, 33 insertions, 42 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 2937fd9aba74..3edfc300289f 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -23,7 +23,7 @@ static struct btrfs_block_group_cache *lookup_block_group(struct
23 (void **)&block_group, 23 (void **)&block_group,
24 blocknr, 1); 24 blocknr, 1);
25 if (ret) { 25 if (ret) {
26 if (block_group->key.objectid <= blocknr && blocknr < 26 if (block_group->key.objectid <= blocknr && blocknr <=
27 block_group->key.objectid + block_group->key.offset) 27 block_group->key.objectid + block_group->key.offset)
28 return block_group; 28 return block_group;
29 } 29 }
@@ -31,11 +31,16 @@ static struct btrfs_block_group_cache *lookup_block_group(struct
31 (void **)&block_group, 31 (void **)&block_group,
32 blocknr, 1); 32 blocknr, 1);
33 if (ret) { 33 if (ret) {
34 if (block_group->key.objectid <= blocknr && blocknr < 34 if (block_group->key.objectid <= blocknr && blocknr <=
35 block_group->key.objectid + block_group->key.offset) 35 block_group->key.objectid + block_group->key.offset)
36 return block_group; 36 return block_group;
37 } 37 }
38printk("lookup_block_group fails for blocknr %Lu\n", blocknr); 38 WARN_ON(1);
39 printk("lookup_block_group fails for blocknr %Lu\n", blocknr);
40 printk("last ret was %d\n", ret);
41 if (ret) {
42 printk("last block group was %Lu %Lu\n", block_group->key.objectid, block_group->key.offset);
43 }
39 return NULL; 44 return NULL;
40} 45}
41 46
@@ -356,45 +361,20 @@ static int update_block_group(struct btrfs_trans_handle *trans,
356{ 361{
357 struct btrfs_block_group_cache *cache; 362 struct btrfs_block_group_cache *cache;
358 struct btrfs_fs_info *info = root->fs_info; 363 struct btrfs_fs_info *info = root->fs_info;
359 struct radix_tree_root *radix;
360 u64 total = num; 364 u64 total = num;
361 u64 old_val; 365 u64 old_val;
362 u64 block_in_group; 366 u64 block_in_group;
363 int ret; 367
364 if (num != 1)
365 radix = &info->block_group_data_radix;
366 else
367 radix = &info->block_group_radix;
368 while(total) { 368 while(total) {
369 ret = radix_tree_gang_lookup(radix, (void **)&cache, 369 cache = lookup_block_group(info, blocknr);
370 blocknr, 1); 370 if (!cache) {
371 if (!ret) {
372 printk(KERN_CRIT "blocknr %Lu lookup failed\n", 371 printk(KERN_CRIT "blocknr %Lu lookup failed\n",
373 blocknr); 372 blocknr);
374 return -1; 373 return -1;
375 } 374 }
376 block_in_group = blocknr - cache->key.objectid; 375 block_in_group = blocknr - cache->key.objectid;
377 if (block_in_group > cache->key.offset || cache->key.objectid >
378 blocknr) {
379 if (radix == &info->block_group_data_radix)
380 radix = &info->block_group_radix;
381 else
382 radix = &info->block_group_data_radix;
383 ret = radix_tree_gang_lookup(radix, (void **)&cache,
384 blocknr, 1);
385 if (!ret) {
386 printk(KERN_CRIT "blocknr %Lu lookup failed\n",
387 blocknr);
388 return -1;
389 }
390 block_in_group = blocknr - cache->key.objectid;
391 if (block_in_group > cache->key.offset ||
392 cache->key.objectid > blocknr) {
393 BUG();
394 }
395 }
396 WARN_ON(block_in_group > cache->key.offset); 376 WARN_ON(block_in_group > cache->key.offset);
397 radix_tree_tag_set(radix, cache->key.objectid + 377 radix_tree_tag_set(cache->radix, cache->key.objectid +
398 cache->key.offset - 1, 378 cache->key.offset - 1,
399 BTRFS_BLOCK_GROUP_DIRTY); 379 BTRFS_BLOCK_GROUP_DIRTY);
400 380
@@ -693,6 +673,8 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
693 num_blocks = 1; 673 num_blocks = 1;
694 total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3; 674 total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3;
695 } 675 }
676 if (search_end == (u64)-1)
677 search_end = btrfs_super_total_blocks(info->disk_super);
696 if (search_start) { 678 if (search_start) {
697 block_group = lookup_block_group(info, search_start); 679 block_group = lookup_block_group(info, search_start);
698 block_group = btrfs_find_block_group(root, block_group, 680 block_group = btrfs_find_block_group(root, block_group,
@@ -704,7 +686,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
704 } 686 }
705 687
706check_failed: 688check_failed:
707 if (block_group->data != data) 689 if (!full_scan && block_group->data != data)
708 WARN_ON(1); 690 WARN_ON(1);
709 if (block_group->last_alloc > search_start) 691 if (block_group->last_alloc > search_start)
710 search_start = block_group->last_alloc; 692 search_start = block_group->last_alloc;
@@ -734,13 +716,13 @@ check_failed:
734 goto error; 716 goto error;
735 if (!start_found) { 717 if (!start_found) {
736 ins->objectid = search_start; 718 ins->objectid = search_start;
737 ins->offset = (u64)-1 - search_start; 719 ins->offset = search_end - search_start;
738 start_found = 1; 720 start_found = 1;
739 goto check_pending; 721 goto check_pending;
740 } 722 }
741 ins->objectid = last_block > search_start ? 723 ins->objectid = last_block > search_start ?
742 last_block : search_start; 724 last_block : search_start;
743 ins->offset = (u64)-1 - ins->objectid; 725 ins->offset = search_end - ins->objectid;
744 goto check_pending; 726 goto check_pending;
745 } 727 }
746 btrfs_disk_key_to_cpu(&key, &l->items[slot].key); 728 btrfs_disk_key_to_cpu(&key, &l->items[slot].key);
@@ -777,7 +759,7 @@ check_pending:
777 */ 759 */
778 btrfs_release_path(root, path); 760 btrfs_release_path(root, path);
779 BUG_ON(ins->objectid < search_start); 761 BUG_ON(ins->objectid < search_start);
780 if (ins->objectid >= btrfs_super_total_blocks(info->disk_super)) { 762 if (ins->objectid + num_blocks >= search_end) {
781 if (full_scan) 763 if (full_scan)
782 return -ENOSPC; 764 return -ENOSPC;
783 search_start = orig_search_start; 765 search_start = orig_search_start;
@@ -840,7 +822,7 @@ check_pending:
840 return 0; 822 return 0;
841 823
842new_group: 824new_group:
843 if (search_start >= btrfs_super_total_blocks(info->disk_super)) { 825 if (search_start + num_blocks >= search_end) {
844 search_start = orig_search_start; 826 search_start = orig_search_start;
845 full_scan = 1; 827 full_scan = 1;
846 } 828 }
@@ -900,7 +882,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
900 return ret; 882 return ret;
901 883
902 /* then do prealloc for the extent tree */ 884 /* then do prealloc for the extent tree */
903 ret = find_free_extent(trans, root, 0, ins->objectid + ins->offset, 885 if (ins->objectid + ins->offset >= search_end)
886 search_end = ins->objectid - 1;
887 else
888 search_start = ins->objectid + ins->offset;
889
890 ret = find_free_extent(trans, root, 0, search_start,
904 search_end, &prealloc_key, 0); 891 search_end, &prealloc_key, 0);
905 if (ret) 892 if (ret)
906 return ret; 893 return ret;
@@ -1198,6 +1185,12 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1198 err = -1; 1185 err = -1;
1199 break; 1186 break;
1200 } 1187 }
1188
1189 if (nr & 1)
1190 radix = &info->block_group_data_radix;
1191 else
1192 radix = &info->block_group_radix;
1193
1201 bi = btrfs_item_ptr(leaf, path->slots[0], 1194 bi = btrfs_item_ptr(leaf, path->slots[0],
1202 struct btrfs_block_group_item); 1195 struct btrfs_block_group_item);
1203 memcpy(&cache->item, bi, sizeof(*bi)); 1196 memcpy(&cache->item, bi, sizeof(*bi));
@@ -1206,12 +1199,10 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1206 cache->first_free = cache->key.objectid; 1199 cache->first_free = cache->key.objectid;
1207 cache->pinned = 0; 1200 cache->pinned = 0;
1208 cache->data = (nr & 1); 1201 cache->data = (nr & 1);
1202 cache->radix = radix;
1203
1209 key.objectid = found_key.objectid + found_key.offset; 1204 key.objectid = found_key.objectid + found_key.offset;
1210 btrfs_release_path(root, path); 1205 btrfs_release_path(root, path);
1211 if (nr & 1)
1212 radix = &info->block_group_data_radix;
1213 else
1214 radix = &info->block_group_radix;
1215 ret = radix_tree_insert(radix, found_key.objectid + 1206 ret = radix_tree_insert(radix, found_key.objectid +
1216 found_key.offset - 1, 1207 found_key.offset - 1,
1217 (void *)cache); 1208 (void *)cache);