diff options
author | Yan <yanzheng@21cn.com> | 2007-11-16 14:57:09 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:57 -0400 |
commit | 5e5745dcaf73c5860a16c09572d59383ecee6d28 (patch) | |
tree | 706cf4745185a24d77708bab736b1bf0d422fca1 /fs/btrfs/extent-tree.c | |
parent | 324ae4df00fdc1a6a179bf584d8addf027bb75fb (diff) |
Btrfs: Add full_scan parameter to find_search_start
This patch adds a new parameter 'full_scan' to 'find_search_start',
thereby 'find_search_start' can know whether 'find_free_extent' is in
full scan phrase. I feel that 'find_search_start' should skip calling
'btrfs_find_block_group' when 'find_free_extent' is in full scan
phrase. In my test on a 2GB volume, Oops occurs when space usage is
about 76%. After apply the patch, Oops occurs when space usage is
near 100%.
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 | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4ef6dc3d7d32..e5340677d6c4 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -158,10 +158,10 @@ struct btrfs_block_group_cache *btrfs_lookup_block_group(struct | |||
158 | 158 | ||
159 | return NULL; | 159 | return NULL; |
160 | } | 160 | } |
161 | |||
162 | static u64 find_search_start(struct btrfs_root *root, | 161 | static u64 find_search_start(struct btrfs_root *root, |
163 | struct btrfs_block_group_cache **cache_ret, | 162 | struct btrfs_block_group_cache **cache_ret, |
164 | u64 search_start, int num, int data) | 163 | u64 search_start, int num, |
164 | int data, int full_scan) | ||
165 | { | 165 | { |
166 | int ret; | 166 | int ret; |
167 | struct btrfs_block_group_cache *cache = *cache_ret; | 167 | struct btrfs_block_group_cache *cache = *cache_ret; |
@@ -218,10 +218,10 @@ wrapped: | |||
218 | if (cache_miss && !cache->cached) { | 218 | if (cache_miss && !cache->cached) { |
219 | cache_block_group(root, cache); | 219 | cache_block_group(root, cache); |
220 | last = cache_miss; | 220 | last = cache_miss; |
221 | |||
222 | cache = btrfs_lookup_block_group(root->fs_info, last); | 221 | cache = btrfs_lookup_block_group(root->fs_info, last); |
223 | } | 222 | } |
224 | cache = btrfs_find_block_group(root, cache, last, data, 0); | 223 | if (!full_scan) |
224 | cache = btrfs_find_block_group(root, cache, last, data, 0); | ||
225 | *cache_ret = cache; | 225 | *cache_ret = cache; |
226 | cache_miss = 0; | 226 | cache_miss = 0; |
227 | goto again; | 227 | goto again; |
@@ -979,12 +979,10 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
979 | 979 | ||
980 | total_needed += empty_size; | 980 | total_needed += empty_size; |
981 | path = btrfs_alloc_path(); | 981 | path = btrfs_alloc_path(); |
982 | |||
983 | check_failed: | 982 | check_failed: |
984 | search_start = find_search_start(root, &block_group, | 983 | search_start = find_search_start(root, &block_group, search_start, |
985 | search_start, total_needed, data); | 984 | total_needed, data, full_scan); |
986 | cached_start = search_start; | 985 | cached_start = search_start; |
987 | |||
988 | btrfs_init_path(path); | 986 | btrfs_init_path(path); |
989 | ins->objectid = search_start; | 987 | ins->objectid = search_start; |
990 | ins->offset = 0; | 988 | ins->offset = 0; |