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) | |
download | lwn-f2654de42a759127cb1f1e8a626ec94178732e20.tar.gz lwn-f2654de42a759127cb1f1e8a626ec94178732e20.zip |
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 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *orig_root, u64 num_blocks, u64 search_start, u64 search_end, u64 hint_block, - struct btrfs_key *ins, int data); + struct btrfs_key *ins, u64 exclude_start, + u64 exclude_nr, int data); static int finish_current_insert(struct btrfs_trans_handle *trans, struct btrfs_root *extent_root); 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, if (!path) return -ENOMEM; ret = find_free_extent(trans, root->fs_info->extent_root, 0, 0, - (u64)-1, 0, &ins, 0); + (u64)-1, 0, &ins, 0, 0, 0); if (ret) { btrfs_free_path(path); return ret; @@ -559,7 +560,8 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, struct btrfs_block_group_item *bi; struct btrfs_key ins; - ret = find_free_extent(trans, extent_root, 0, 0, (u64)-1, 0, &ins, 0); + ret = find_free_extent(trans, extent_root, 0, 0, (u64)-1, 0, &ins, + 0, 0, 0); /* FIXME, set bit to recalc cache groups on next mount */ if (ret) return ret; @@ -868,7 +870,7 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root if (!path) return -ENOMEM; - ret = find_free_extent(trans, root, 0, 0, (u64)-1, 0, &ins, 0); + ret = find_free_extent(trans, root, 0, 0, (u64)-1, 0, &ins, 0, 0, 0); if (ret) { btrfs_free_path(path); return ret; @@ -987,7 +989,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *orig_root, u64 num_blocks, u64 search_start, u64 search_end, u64 hint_block, - struct btrfs_key *ins, int data) + struct btrfs_key *ins, u64 exclude_start, + u64 exclude_nr, int data) { struct btrfs_path *path; struct btrfs_key key; @@ -1191,6 +1194,11 @@ check_pending: goto new_group; } } + if (exclude_nr > 0 && (ins->objectid + num_blocks > exclude_start && + ins->objectid < exclude_start + exclude_nr)) { + search_start = exclude_start + exclude_nr; + goto new_group; + } if (fill_prealloc) { int nr; test_block = ins->objectid; @@ -1267,6 +1275,8 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, int pending_ret; u64 super_blocks_used; u64 search_start = 0; + u64 exclude_start = 0; + u64 exclude_nr = 0; struct btrfs_fs_info *info = root->fs_info; struct btrfs_root *extent_root = info->extent_root; struct btrfs_extent_item extent_item; @@ -1298,33 +1308,19 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, */ if (data) { ret = find_free_extent(trans, root, 0, 0, - search_end, 0, &prealloc_key, 0); - if (ret) { + search_end, 0, &prealloc_key, 0, 0, 0); + if (ret) return ret; - } - if (prealloc_key.objectid + prealloc_key.offset >= search_end) { - int nr = info->extent_tree_prealloc_nr; - search_end = info->extent_tree_prealloc[nr - 1] - 1; - } else { - search_start = info->extent_tree_prealloc[0] + 1; - } + exclude_nr = info->extent_tree_prealloc_nr; + exclude_start = info->extent_tree_prealloc[exclude_nr - 1]; } - if (hint_block < search_start) - hint_block = search_start; + /* do the real allocation */ ret = find_free_extent(trans, root, num_blocks, search_start, - search_end, hint_block, ins, data); - if (ret) { - if (search_start == 0) - return ret; - search_end = search_start - 1; - search_start = 0; - hint_block = search_start; - ret = find_free_extent(trans, root, num_blocks, search_start, - search_end, hint_block, ins, data); - if (ret) - return ret; - } + search_end, hint_block, ins, + exclude_start, exclude_nr, data); + if (ret) + return ret; /* * if we're doing a metadata allocation, preallocate space in the @@ -1336,29 +1332,14 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, * The unused prealloc will get reused the next time around. */ if (!data) { - if (ins->objectid + ins->offset >= search_end) - search_end = ins->objectid - 1; - else - search_start = ins->objectid + ins->offset; - - if (hint_block < search_start) - hint_block = search_start; - + exclude_start = ins->objectid; + exclude_nr = ins->offset; ret = find_free_extent(trans, root, 0, search_start, search_end, hint_block, - &prealloc_key, 0); - if (ret) { - if (search_start == 0) - return ret; - search_end = search_start - 1; - search_start = 0; - hint_block = search_start; - ret = find_free_extent(trans, root, 0, search_start, - search_end, hint_block, - &prealloc_key, 0); - if (ret) - return ret; - } + &prealloc_key, exclude_start, + exclude_nr, 0); + if (ret) + return ret; } super_blocks_used = btrfs_super_blocks_used(&info->super_copy); |