aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-26 12:20:46 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-26 12:20:46 -0400
commitf2654de42a759127cb1f1e8a626ec94178732e20 (patch)
tree27a4b6ab03a775241d5a80f98139cf17c1fef6f3 /fs/btrfs/extent-tree.c
parent4b52dff6d371b9b93bc99f64c32831ea9a8ec3ac (diff)
Btrfs: Allow find_free_extent callers to pass in an exclusion range
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c79
1 files changed, 30 insertions, 49 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7e550343aee7..01dc30579287 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -25,7 +25,8 @@
25static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 25static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
26 *orig_root, u64 num_blocks, u64 search_start, 26 *orig_root, u64 num_blocks, u64 search_start,
27 u64 search_end, u64 hint_block, 27 u64 search_end, u64 hint_block,
28 struct btrfs_key *ins, int data); 28 struct btrfs_key *ins, u64 exclude_start,
29 u64 exclude_nr, int data);
29static int finish_current_insert(struct btrfs_trans_handle *trans, struct 30static int finish_current_insert(struct btrfs_trans_handle *trans, struct
30 btrfs_root *extent_root); 31 btrfs_root *extent_root);
31static int del_pending_extents(struct btrfs_trans_handle *trans, struct 32static int del_pending_extents(struct btrfs_trans_handle *trans, struct
@@ -407,7 +408,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
407 if (!path) 408 if (!path)
408 return -ENOMEM; 409 return -ENOMEM;
409 ret = find_free_extent(trans, root->fs_info->extent_root, 0, 0, 410 ret = find_free_extent(trans, root->fs_info->extent_root, 0, 0,
410 (u64)-1, 0, &ins, 0); 411 (u64)-1, 0, &ins, 0, 0, 0);
411 if (ret) { 412 if (ret) {
412 btrfs_free_path(path); 413 btrfs_free_path(path);
413 return ret; 414 return ret;
@@ -559,7 +560,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans,
559 struct btrfs_block_group_item *bi; 560 struct btrfs_block_group_item *bi;
560 struct btrfs_key ins; 561 struct btrfs_key ins;
561 562
562 ret = find_free_extent(trans, extent_root, 0, 0, (u64)-1, 0, &ins, 0); 563 ret = find_free_extent(trans, extent_root, 0, 0, (u64)-1, 0, &ins,
564 0, 0, 0);
563 /* FIXME, set bit to recalc cache groups on next mount */ 565 /* FIXME, set bit to recalc cache groups on next mount */
564 if (ret) 566 if (ret)
565 return ret; 567 return ret;
@@ -868,7 +870,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
868 if (!path) 870 if (!path)
869 return -ENOMEM; 871 return -ENOMEM;
870 872
871 ret = find_free_extent(trans, root, 0, 0, (u64)-1, 0, &ins, 0); 873 ret = find_free_extent(trans, root, 0, 0, (u64)-1, 0, &ins, 0, 0, 0);
872 if (ret) { 874 if (ret) {
873 btrfs_free_path(path); 875 btrfs_free_path(path);
874 return ret; 876 return ret;
@@ -987,7 +989,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
987static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root 989static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root
988 *orig_root, u64 num_blocks, u64 search_start, u64 990 *orig_root, u64 num_blocks, u64 search_start, u64
989 search_end, u64 hint_block, 991 search_end, u64 hint_block,
990 struct btrfs_key *ins, int data) 992 struct btrfs_key *ins, u64 exclude_start,
993 u64 exclude_nr, int data)
991{ 994{
992 struct btrfs_path *path; 995 struct btrfs_path *path;
993 struct btrfs_key key; 996 struct btrfs_key key;
@@ -1191,6 +1194,11 @@ check_pending:
1191 goto new_group; 1194 goto new_group;
1192 } 1195 }
1193 } 1196 }
1197 if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start &&
1198 ins->objectid < exclude_start + exclude_nr)) {
1199 search_start = exclude_start + exclude_nr;
1200 goto new_group;
1201 }
1194 if (fill_prealloc) { 1202 if (fill_prealloc) {
1195 int nr; 1203 int nr;
1196 test_block = ins->objectid; 1204 test_block = ins->objectid;
@@ -1267,6 +1275,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1267 int pending_ret; 1275 int pending_ret;
1268 u64 super_blocks_used; 1276 u64 super_blocks_used;
1269 u64 search_start = 0; 1277 u64 search_start = 0;
1278 u64 exclude_start = 0;
1279 u64 exclude_nr = 0;
1270 struct btrfs_fs_info *info = root->fs_info; 1280 struct btrfs_fs_info *info = root->fs_info;
1271 struct btrfs_root *extent_root = info->extent_root; 1281 struct btrfs_root *extent_root = info->extent_root;
1272 struct btrfs_extent_item extent_item; 1282 struct btrfs_extent_item extent_item;
@@ -1298,33 +1308,19 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1298 */ 1308 */
1299 if (data) { 1309 if (data) {
1300 ret = find_free_extent(trans, root, 0, 0, 1310 ret = find_free_extent(trans, root, 0, 0,
1301 search_end, 0, &prealloc_key, 0); 1311 search_end, 0, &prealloc_key, 0, 0, 0);
1302 if (ret) { 1312 if (ret)
1303 return ret; 1313 return ret;
1304 } 1314 exclude_nr = info->extent_tree_prealloc_nr;
1305 if (prealloc_key.objectid + prealloc_key.offset >= search_end) { 1315 exclude_start = info->extent_tree_prealloc[exclude_nr - 1];
1306 int nr = info->extent_tree_prealloc_nr;
1307 search_end = info->extent_tree_prealloc[nr - 1] - 1;
1308 } else {
1309 search_start = info->extent_tree_prealloc[0] + 1;
1310 }
1311 } 1316 }
1312 if (hint_block < search_start) 1317
1313 hint_block = search_start;
1314 /* do the real allocation */ 1318 /* do the real allocation */
1315 ret = find_free_extent(trans, root, num_blocks, search_start, 1319 ret = find_free_extent(trans, root, num_blocks, search_start,
1316 search_end, hint_block, ins, data); 1320 search_end, hint_block, ins,
1317 if (ret) { 1321 exclude_start, exclude_nr, data);
1318 if (search_start == 0) 1322 if (ret)
1319 return ret; 1323 return ret;
1320 search_end = search_start - 1;
1321 search_start = 0;
1322 hint_block = search_start;
1323 ret = find_free_extent(trans, root, num_blocks, search_start,
1324 search_end, hint_block, ins, data);
1325 if (ret)
1326 return ret;
1327 }
1328 1324
1329 /* 1325 /*
1330 * if we're doing a metadata allocation, preallocate space in the 1326 * if we're doing a metadata allocation, preallocate space in the
@@ -1336,29 +1332,14 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans,
1336 * The unused prealloc will get reused the next time around. 1332 * The unused prealloc will get reused the next time around.
1337 */ 1333 */
1338 if (!data) { 1334 if (!data) {
1339 if (ins->objectid + ins->offset >= search_end) 1335 exclude_start = ins->objectid;
1340 search_end = ins->objectid - 1; 1336 exclude_nr = ins->offset;
1341 else
1342 search_start = ins->objectid + ins->offset;
1343
1344 if (hint_block < search_start)
1345 hint_block = search_start;
1346
1347 ret = find_free_extent(trans, root, 0, search_start, 1337 ret = find_free_extent(trans, root, 0, search_start,
1348 search_end, hint_block, 1338 search_end, hint_block,
1349 &prealloc_key, 0); 1339 &prealloc_key, exclude_start,
1350 if (ret) { 1340 exclude_nr, 0);
1351 if (search_start == 0) 1341 if (ret)
1352 return ret; 1342 return ret;
1353 search_end = search_start - 1;
1354 search_start = 0;
1355 hint_block = search_start;
1356 ret = find_free_extent(trans, root, 0, search_start,
1357 search_end, hint_block,
1358 &prealloc_key, 0);
1359 if (ret)
1360 return ret;
1361 }
1362 } 1343 }
1363 1344
1364 super_blocks_used = btrfs_super_blocks_used(&info->super_copy); 1345 super_blocks_used = btrfs_super_blocks_used(&info->super_copy);