diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-06-26 12:20:46 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-06-26 12:20:46 -0400 |
commit | f2654de42a759127cb1f1e8a626ec94178732e20 (patch) | |
tree | 27a4b6ab03a775241d5a80f98139cf17c1fef6f3 /fs/btrfs/extent-tree.c | |
parent | 4b52dff6d371b9b93bc99f64c32831ea9a8ec3ac (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.c | 79 |
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 @@ | |||
25 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 25 | static 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); | ||
29 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct | 30 | static int finish_current_insert(struct btrfs_trans_handle *trans, struct |
30 | btrfs_root *extent_root); | 31 | btrfs_root *extent_root); |
31 | static int del_pending_extents(struct btrfs_trans_handle *trans, struct | 32 | static 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 | |||
987 | static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | 989 | static 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); |