aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-08-08 20:17:12 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-08-08 20:17:12 -0400
commit26b8003f10569a9155b7539ef5a7379ee0c6b050 (patch)
tree22d788e74199629ca4deb2d5774fd3e5b9ef748a /fs/btrfs/extent-tree.c
parentf4468e94c86c2031f447788c4bfe7dfd2fcdc93a (diff)
Btrfs: Replace extent tree preallocation code with some bit radix magic.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c230
1 files changed, 43 insertions, 187 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index f7d76d34fc37..ba50bd7b9a78 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -22,12 +22,6 @@
22#include "print-tree.h" 22#include "print-tree.h"
23#include "transaction.h" 23#include "transaction.h"
24 24
25static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
26 *orig_root, u64 num_blocks, u64 empty_size,
27 u64 search_start,
28 u64 search_end, u64 hint_block,
29 struct btrfs_key *ins, u64 exclude_start,
30 u64 exclude_nr, int data);
31static int finish_current_insert(struct btrfs_trans_handle *trans, struct 25static int finish_current_insert(struct btrfs_trans_handle *trans, struct
32 btrfs_root *extent_root); 26 btrfs_root *extent_root);
33static int del_pending_extents(struct btrfs_trans_handle *trans, struct 27static int del_pending_extents(struct btrfs_trans_handle *trans, struct
@@ -174,9 +168,6 @@ static u64 find_search_start(struct btrfs_root *root,
174 168
175 if (cache->data) 169 if (cache->data)
176 goto out; 170 goto out;
177 if (num > 1) {
178 last = max(last, cache->last_prealloc);
179 }
180again: 171again:
181 ret = cache_block_group(root, cache); 172 ret = cache_block_group(root, cache);
182 if (ret) 173 if (ret)
@@ -374,18 +365,12 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
374 struct btrfs_key key; 365 struct btrfs_key key;
375 struct btrfs_leaf *l; 366 struct btrfs_leaf *l;
376 struct btrfs_extent_item *item; 367 struct btrfs_extent_item *item;
377 struct btrfs_key ins;
378 u32 refs; 368 u32 refs;
379 369
380 path = btrfs_alloc_path(); 370 path = btrfs_alloc_path();
381 if (!path) 371 if (!path)
382 return -ENOMEM; 372 return -ENOMEM;
383 ret = find_free_extent(trans, root->fs_info->extent_root, 0, 0, 0, 373
384 (u64)-1, 0, &ins, 0, 0, 0);
385 if (ret) {
386 btrfs_free_path(path);
387 return ret;
388 }
389 key.objectid = blocknr; 374 key.objectid = blocknr;
390 key.flags = 0; 375 key.flags = 0;
391 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); 376 btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY);
@@ -532,13 +517,7 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
532 int pending_ret; 517 int pending_ret;
533 struct btrfs_root *extent_root = root->fs_info->extent_root; 518 struct btrfs_root *extent_root = root->fs_info->extent_root;
534 struct btrfs_block_group_item *bi; 519 struct btrfs_block_group_item *bi;
535 struct btrfs_key ins;
536 520
537 ret = find_free_extent(trans, extent_root, 0, 0, 0, (u64)-1, 0, &ins,
538 0, 0, 0);
539 /* FIXME, set bit to recalc cache groups on next mount */
540 if (ret)
541 return ret;
542 ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); 521 ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1);
543 if (ret < 0) 522 if (ret < 0)
544 goto fail; 523 goto fail;
@@ -706,14 +685,6 @@ static int update_block_group(struct btrfs_trans_handle *trans,
706 return 0; 685 return 0;
707} 686}
708 687
709static int try_remove_page(struct address_space *mapping, unsigned long index)
710{
711 int ret;
712 return 0;
713 ret = invalidate_mapping_pages(mapping, index, index);
714 return ret;
715}
716
717int btrfs_copy_pinned(struct btrfs_root *root, struct radix_tree_root *copy) 688int btrfs_copy_pinned(struct btrfs_root *root, struct radix_tree_root *copy)
718{ 689{
719 unsigned long gang[8]; 690 unsigned long gang[8];
@@ -732,6 +703,9 @@ int btrfs_copy_pinned(struct btrfs_root *root, struct radix_tree_root *copy)
732 last = gang[i] + 1; 703 last = gang[i] + 1;
733 } 704 }
734 } 705 }
706 ret = find_first_radix_bit(&root->fs_info->extent_ins_radix, gang, 0,
707 ARRAY_SIZE(gang));
708 WARN_ON(ret);
735 return 0; 709 return 0;
736} 710}
737 711
@@ -740,7 +714,6 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
740 struct radix_tree_root *unpin_radix) 714 struct radix_tree_root *unpin_radix)
741{ 715{
742 unsigned long gang[8]; 716 unsigned long gang[8];
743 struct inode *btree_inode = root->fs_info->btree_inode;
744 struct btrfs_block_group_cache *block_group; 717 struct btrfs_block_group_cache *block_group;
745 u64 first = 0; 718 u64 first = 0;
746 int ret; 719 int ret;
@@ -765,14 +738,9 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
765 block_group->pinned--; 738 block_group->pinned--;
766 if (gang[i] < block_group->last_alloc) 739 if (gang[i] < block_group->last_alloc)
767 block_group->last_alloc = gang[i]; 740 block_group->last_alloc = gang[i];
768 if (gang[i] < block_group->last_prealloc)
769 block_group->last_prealloc = gang[i];
770 if (!block_group->data) 741 if (!block_group->data)
771 set_radix_bit(extent_radix, gang[i]); 742 set_radix_bit(extent_radix, gang[i]);
772 } 743 }
773 try_remove_page(btree_inode->i_mapping,
774 gang[i] << (PAGE_CACHE_SHIFT -
775 btree_inode->i_blkbits));
776 } 744 }
777 } 745 }
778 return 0; 746 return 0;
@@ -785,7 +753,8 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
785 struct btrfs_extent_item extent_item; 753 struct btrfs_extent_item extent_item;
786 int i; 754 int i;
787 int ret; 755 int ret;
788 u64 super_blocks_used; 756 int err;
757 unsigned long gang[8];
789 struct btrfs_fs_info *info = extent_root->fs_info; 758 struct btrfs_fs_info *info = extent_root->fs_info;
790 759
791 btrfs_set_extent_refs(&extent_item, 1); 760 btrfs_set_extent_refs(&extent_item, 1);
@@ -794,16 +763,21 @@ static int finish_current_insert(struct btrfs_trans_handle *trans, struct
794 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY); 763 btrfs_set_key_type(&ins, BTRFS_EXTENT_ITEM_KEY);
795 btrfs_set_extent_owner(&extent_item, extent_root->root_key.objectid); 764 btrfs_set_extent_owner(&extent_item, extent_root->root_key.objectid);
796 765
797 for (i = 0; i < extent_root->fs_info->extent_tree_insert_nr; i++) { 766 while(1) {
798 ins.objectid = extent_root->fs_info->extent_tree_insert[i]; 767 ret = find_first_radix_bit(&info->extent_ins_radix, gang, 0,
799 super_blocks_used = btrfs_super_blocks_used(&info->super_copy); 768 ARRAY_SIZE(gang));
800 btrfs_set_super_blocks_used(&info->super_copy, 769 if (!ret)
801 super_blocks_used + 1); 770 break;
802 ret = btrfs_insert_item(trans, extent_root, &ins, &extent_item, 771
803 sizeof(extent_item)); 772 for (i = 0; i < ret; i++) {
804 BUG_ON(ret); 773 ins.objectid = gang[i];
774 err = btrfs_insert_item(trans, extent_root, &ins,
775 &extent_item,
776 sizeof(extent_item));
777 clear_radix_bit(&info->extent_ins_radix, gang[i]);
778 WARN_ON(err);
779 }
805 } 780 }
806 extent_root->fs_info->extent_tree_insert_nr = 0;
807 return 0; 781 return 0;
808} 782}
809 783
@@ -856,7 +830,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
856 struct btrfs_root *extent_root = info->extent_root; 830 struct btrfs_root *extent_root = info->extent_root;
857 int ret; 831 int ret;
858 struct btrfs_extent_item *ei; 832 struct btrfs_extent_item *ei;
859 struct btrfs_key ins;
860 u32 refs; 833 u32 refs;
861 834
862 key.objectid = blocknr; 835 key.objectid = blocknr;
@@ -868,12 +841,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
868 if (!path) 841 if (!path)
869 return -ENOMEM; 842 return -ENOMEM;
870 843
871 ret = find_free_extent(trans, root, 0, 0, 0, (u64)-1, 0, &ins, 0, 0, 0);
872 if (ret) {
873 btrfs_free_path(path);
874 return ret;
875 }
876
877 ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1); 844 ret = btrfs_search_slot(trans, extent_root, &key, path, -1, 1);
878 if (ret < 0) 845 if (ret < 0)
879 return ret; 846 return ret;
@@ -1003,35 +970,17 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
1003 struct btrfs_root * root = orig_root->fs_info->extent_root; 970 struct btrfs_root * root = orig_root->fs_info->extent_root;
1004 struct btrfs_fs_info *info = root->fs_info; 971 struct btrfs_fs_info *info = root->fs_info;
1005 int total_needed = num_blocks; 972 int total_needed = num_blocks;
1006 int total_found = 0;
1007 int fill_prealloc = 0;
1008 int level; 973 int level;
1009 struct btrfs_block_group_cache *block_group; 974 struct btrfs_block_group_cache *block_group;
1010 int full_scan = 0; 975 int full_scan = 0;
1011 int wrapped = 0; 976 int wrapped = 0;
1012 u64 limit; 977 u64 limit;
1013 978
979 WARN_ON(num_blocks < 1);
1014 ins->flags = 0; 980 ins->flags = 0;
1015 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY); 981 btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
1016 982
1017 level = btrfs_header_level(btrfs_buffer_header(root->node)); 983 level = btrfs_header_level(btrfs_buffer_header(root->node));
1018 if (num_blocks == 0) {
1019 fill_prealloc = 1;
1020 num_blocks = 1;
1021 total_needed = (min(level + 1, BTRFS_MAX_LEVEL)) * 6;
1022 }
1023 if (fill_prealloc) {
1024 u64 first;
1025 int nr = info->extent_tree_prealloc_nr;
1026 first = info->extent_tree_prealloc[nr - 1];
1027 if (info->extent_tree_prealloc_nr >= total_needed &&
1028 first >= search_start) {
1029 ins->objectid = info->extent_tree_prealloc[0];
1030 ins->offset = 1;
1031 return 0;
1032 }
1033 info->extent_tree_prealloc_nr = 0;
1034 }
1035 if (search_end == (u64)-1) 984 if (search_end == (u64)-1)
1036 search_end = btrfs_super_total_blocks(&info->super_copy); 985 search_end = btrfs_super_total_blocks(&info->super_copy);
1037 if (hint_block) { 986 if (hint_block) {
@@ -1091,10 +1040,6 @@ check_failed:
1091 l = btrfs_buffer_leaf(path->nodes[0]); 1040 l = btrfs_buffer_leaf(path->nodes[0]);
1092 slot = path->slots[0]; 1041 slot = path->slots[0];
1093 if (slot >= btrfs_header_nritems(&l->header)) { 1042 if (slot >= btrfs_header_nritems(&l->header)) {
1094 if (fill_prealloc) {
1095 info->extent_tree_prealloc_nr = 0;
1096 total_found = 0;
1097 }
1098 if (start_found) 1043 if (start_found)
1099 limit = last_block + 1044 limit = last_block +
1100 (block_group->key.offset >> 1); 1045 (block_group->key.offset >> 1);
@@ -1170,67 +1115,21 @@ check_pending:
1170 } 1115 }
1171 for (test_block = ins->objectid; 1116 for (test_block = ins->objectid;
1172 test_block < ins->objectid + num_blocks; test_block++) { 1117 test_block < ins->objectid + num_blocks; test_block++) {
1173 if (test_radix_bit(&info->pinned_radix, test_block)) { 1118 if (test_radix_bit(&info->pinned_radix, test_block) ||
1119 test_radix_bit(&info->extent_ins_radix, test_block)) {
1174 search_start = test_block + 1; 1120 search_start = test_block + 1;
1175 goto new_group; 1121 goto new_group;
1176 } 1122 }
1177 } 1123 }
1178 if (!fill_prealloc && info->extent_tree_insert_nr) {
1179 u64 last =
1180 info->extent_tree_insert[info->extent_tree_insert_nr - 1];
1181 if (ins->objectid + num_blocks >
1182 info->extent_tree_insert[0] &&
1183 ins->objectid <= last) {
1184 search_start = last + 1;
1185 WARN_ON(!full_scan);
1186 goto new_group;
1187 }
1188 }
1189 if (!fill_prealloc && info->extent_tree_prealloc_nr) {
1190 u64 first =
1191 info->extent_tree_prealloc[info->extent_tree_prealloc_nr - 1];
1192 if (ins->objectid + num_blocks > first &&
1193 ins->objectid <= info->extent_tree_prealloc[0]) {
1194 search_start = info->extent_tree_prealloc[0] + 1;
1195 goto new_group;
1196 }
1197 }
1198 if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start && 1124 if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start &&
1199 ins->objectid < exclude_start + exclude_nr)) { 1125 ins->objectid < exclude_start + exclude_nr)) {
1200 search_start = exclude_start + exclude_nr; 1126 search_start = exclude_start + exclude_nr;
1201 goto new_group; 1127 goto new_group;
1202 } 1128 }
1203 if (fill_prealloc) {
1204 int nr;
1205 test_block = ins->objectid;
1206 if (test_block - info->extent_tree_prealloc[total_needed - 1] >=
1207 leaf_range(root)) {
1208 total_found = 0;
1209 info->extent_tree_prealloc_nr = total_found;
1210 }
1211 while(test_block < ins->objectid + ins->offset &&
1212 total_found < total_needed) {
1213 nr = total_needed - total_found - 1;
1214 BUG_ON(nr < 0);
1215 info->extent_tree_prealloc[nr] = test_block;
1216 total_found++;
1217 test_block++;
1218 }
1219 if (total_found < total_needed) {
1220 search_start = test_block;
1221 goto new_group;
1222 }
1223 info->extent_tree_prealloc_nr = total_found;
1224 }
1225 if (!data) { 1129 if (!data) {
1226 block_group = btrfs_lookup_block_group(info, ins->objectid); 1130 block_group = btrfs_lookup_block_group(info, ins->objectid);
1227 if (block_group) { 1131 if (block_group)
1228 if (fill_prealloc) 1132 trans->block_group = block_group;
1229 block_group->last_prealloc =
1230 info->extent_tree_prealloc[total_needed-1];
1231 else
1232 trans->block_group = block_group;
1233 }
1234 } 1133 }
1235 ins->offset = num_blocks; 1134 ins->offset = num_blocks;
1236 btrfs_free_path(path); 1135 btrfs_free_path(path);
@@ -1278,85 +1177,41 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1278 int pending_ret; 1177 int pending_ret;
1279 u64 super_blocks_used; 1178 u64 super_blocks_used;
1280 u64 search_start = 0; 1179 u64 search_start = 0;
1281 u64 exclude_start = 0;
1282 u64 exclude_nr = 0;
1283 struct btrfs_fs_info *info = root->fs_info; 1180 struct btrfs_fs_info *info = root->fs_info;
1284 struct btrfs_root *extent_root = info->extent_root; 1181 struct btrfs_root *extent_root = info->extent_root;
1285 struct btrfs_extent_item extent_item; 1182 struct btrfs_extent_item extent_item;
1286 struct btrfs_key prealloc_key;
1287 1183
1288 btrfs_set_extent_refs(&extent_item, 1); 1184 btrfs_set_extent_refs(&extent_item, 1);
1289 btrfs_set_extent_owner(&extent_item, owner); 1185 btrfs_set_extent_owner(&extent_item, owner);
1290 1186
1291 if (root == extent_root) { 1187 WARN_ON(num_blocks < 1);
1292 int nr;
1293 BUG_ON(info->extent_tree_prealloc_nr == 0);
1294 BUG_ON(num_blocks != 1);
1295 ins->offset = 1;
1296 info->extent_tree_prealloc_nr--;
1297 nr = info->extent_tree_prealloc_nr;
1298 ins->objectid = info->extent_tree_prealloc[nr];
1299 info->extent_tree_insert[info->extent_tree_insert_nr++] =
1300 ins->objectid;
1301 ret = update_block_group(trans, root,
1302 ins->objectid, ins->offset, 1, 0, 0);
1303 WARN_ON(info->extent_tree_insert_nr >
1304 ARRAY_SIZE(info->extent_tree_insert));
1305 BUG_ON(ret);
1306 return 0;
1307 }
1308
1309 /*
1310 * if we're doing a data allocation, preallocate room in the
1311 * extent tree first. This way the extent tree blocks end up
1312 * in the correct block group.
1313 */
1314 if (data) {
1315 ret = find_free_extent(trans, root, 0, 0, 0,
1316 search_end, 0, &prealloc_key, 0, 0, 0);
1317 BUG_ON(ret);
1318 if (ret)
1319 return ret;
1320 exclude_nr = info->extent_tree_prealloc_nr;
1321 exclude_start = info->extent_tree_prealloc[exclude_nr - 1];
1322 }
1323
1324 /* do the real allocation */
1325 ret = find_free_extent(trans, root, num_blocks, empty_size, 1188 ret = find_free_extent(trans, root, num_blocks, empty_size,
1326 search_start, search_end, hint_block, ins, 1189 search_start, search_end, hint_block, ins,
1327 exclude_start, exclude_nr, data); 1190 trans->alloc_exclude_start,
1191 trans->alloc_exclude_nr, data);
1328 BUG_ON(ret); 1192 BUG_ON(ret);
1329 if (ret) 1193 if (ret)
1330 return ret; 1194 return ret;
1331 1195
1332 /*
1333 * if we're doing a metadata allocation, preallocate space in the
1334 * extent tree second. This way, we don't create a tiny hole
1335 * in the allocation map between any unused preallocation blocks
1336 * and the metadata block we're actually allocating. On disk,
1337 * it'll go:
1338 * [block we've allocated], [used prealloc 1], [ unused prealloc ]
1339 * The unused prealloc will get reused the next time around.
1340 */
1341 if (!data) {
1342 exclude_start = ins->objectid;
1343 exclude_nr = ins->offset;
1344 hint_block = exclude_start + exclude_nr;
1345 ret = find_free_extent(trans, root, 0, 0, search_start,
1346 search_end, hint_block,
1347 &prealloc_key, exclude_start,
1348 exclude_nr, 0);
1349 BUG_ON(ret);
1350 if (ret)
1351 return ret;
1352 }
1353
1354 super_blocks_used = btrfs_super_blocks_used(&info->super_copy); 1196 super_blocks_used = btrfs_super_blocks_used(&info->super_copy);
1355 btrfs_set_super_blocks_used(&info->super_copy, super_blocks_used + 1197 btrfs_set_super_blocks_used(&info->super_copy, super_blocks_used +
1356 num_blocks); 1198 num_blocks);
1199
1200 if (root == extent_root) {
1201 BUG_ON(num_blocks != 1);
1202 set_radix_bit(&root->fs_info->extent_ins_radix, ins->objectid);
1203 goto update_block;
1204 }
1205
1206 WARN_ON(trans->alloc_exclude_nr);
1207 trans->alloc_exclude_start = ins->objectid;
1208 trans->alloc_exclude_nr = ins->offset;
1357 ret = btrfs_insert_item(trans, extent_root, ins, &extent_item, 1209 ret = btrfs_insert_item(trans, extent_root, ins, &extent_item,
1358 sizeof(extent_item)); 1210 sizeof(extent_item));
1359 1211
1212 trans->alloc_exclude_start = 0;
1213 trans->alloc_exclude_nr = 0;
1214
1360 BUG_ON(ret); 1215 BUG_ON(ret);
1361 finish_current_insert(trans, extent_root); 1216 finish_current_insert(trans, extent_root);
1362 pending_ret = del_pending_extents(trans, extent_root); 1217 pending_ret = del_pending_extents(trans, extent_root);
@@ -1366,6 +1221,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1366 if (pending_ret) { 1221 if (pending_ret) {
1367 return pending_ret; 1222 return pending_ret;
1368 } 1223 }
1224
1225update_block:
1369 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1, 0, 1226 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1, 0,
1370 data); 1227 data);
1371 BUG_ON(ret); 1228 BUG_ON(ret);
@@ -1750,7 +1607,6 @@ int btrfs_read_block_groups(struct btrfs_root *root)
1750 memcpy(&cache->key, &found_key, sizeof(found_key)); 1607 memcpy(&cache->key, &found_key, sizeof(found_key));
1751 cache->last_alloc = cache->key.objectid; 1608 cache->last_alloc = cache->key.objectid;
1752 cache->first_free = cache->key.objectid; 1609 cache->first_free = cache->key.objectid;
1753 cache->last_prealloc = cache->key.objectid;
1754 cache->pinned = 0; 1610 cache->pinned = 0;
1755 cache->cached = 0; 1611 cache->cached = 0;
1756 1612