aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-11-07 09:06:11 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-07 09:06:11 -0500
commit4366211ccd050e00674b3276b5ed81981b2d7793 (patch)
treeaa2ffcc59c9c5b42ac72230704e29809aaddb361 /fs/btrfs/extent-tree.c
parent3b7885bf96e03271a9fff41124c38ed7176616e2 (diff)
Btfs: More metadata allocator optimizations
This lowers the empty cluster target for metadata allocations. The lower target makes it easier to do allocations and still seems to perform well. It also fixes the allocator loop to drop the empty cluster when things start getting difficult, avoiding false enospc warnings. Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index b8c6541c33fe..0d73a53c6763 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2116,6 +2116,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2116 struct btrfs_root * root = orig_root->fs_info->extent_root; 2116 struct btrfs_root * root = orig_root->fs_info->extent_root;
2117 u64 total_needed = num_bytes; 2117 u64 total_needed = num_bytes;
2118 u64 *last_ptr = NULL; 2118 u64 *last_ptr = NULL;
2119 u64 last_wanted = 0;
2119 struct btrfs_block_group_cache *block_group = NULL; 2120 struct btrfs_block_group_cache *block_group = NULL;
2120 int chunk_alloc_done = 0; 2121 int chunk_alloc_done = 0;
2121 int empty_cluster = 2 * 1024 * 1024; 2122 int empty_cluster = 2 * 1024 * 1024;
@@ -2134,22 +2135,28 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2134 2135
2135 if (data & BTRFS_BLOCK_GROUP_METADATA) { 2136 if (data & BTRFS_BLOCK_GROUP_METADATA) {
2136 last_ptr = &root->fs_info->last_alloc; 2137 last_ptr = &root->fs_info->last_alloc;
2137 empty_cluster = 256 * 1024; 2138 empty_cluster = 64 * 1024;
2138 } 2139 }
2139 2140
2140 if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD)) 2141 if ((data & BTRFS_BLOCK_GROUP_DATA) && btrfs_test_opt(root, SSD))
2141 last_ptr = &root->fs_info->last_data_alloc; 2142 last_ptr = &root->fs_info->last_data_alloc;
2142 2143
2143 if (last_ptr) { 2144 if (last_ptr) {
2144 if (*last_ptr) 2145 if (*last_ptr) {
2145 hint_byte = *last_ptr; 2146 hint_byte = *last_ptr;
2146 else 2147 last_wanted = *last_ptr;
2148 } else
2147 empty_size += empty_cluster; 2149 empty_size += empty_cluster;
2150 } else {
2151 empty_cluster = 0;
2148 } 2152 }
2149 search_start = max(search_start, first_logical_byte(root, 0)); 2153 search_start = max(search_start, first_logical_byte(root, 0));
2150 search_start = max(search_start, hint_byte); 2154 search_start = max(search_start, hint_byte);
2151 total_needed += empty_size; 2155 total_needed += empty_size;
2152 2156
2157 if (search_start != last_wanted)
2158 last_wanted = 0;
2159
2153 block_group = btrfs_lookup_block_group(root->fs_info, search_start); 2160 block_group = btrfs_lookup_block_group(root->fs_info, search_start);
2154 if (!block_group) 2161 if (!block_group)
2155 block_group = btrfs_lookup_first_block_group(root->fs_info, 2162 block_group = btrfs_lookup_first_block_group(root->fs_info,
@@ -2195,9 +2202,9 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2195 if (search_start + num_bytes > end) 2202 if (search_start + num_bytes > end)
2196 goto new_group; 2203 goto new_group;
2197 2204
2198 if (last_ptr && *last_ptr && search_start != *last_ptr) { 2205 if (last_wanted && search_start != last_wanted) {
2199 total_needed += empty_cluster; 2206 total_needed += empty_cluster;
2200 *last_ptr = 0; 2207 last_wanted = 0;
2201 /* 2208 /*
2202 * if search_start is still in this block group 2209 * if search_start is still in this block group
2203 * then we just re-search this block group 2210 * then we just re-search this block group
@@ -2223,6 +2230,7 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2223 if (search_start >= start && 2230 if (search_start >= start &&
2224 search_start < end) { 2231 search_start < end) {
2225 mutex_unlock(&block_group->alloc_mutex); 2232 mutex_unlock(&block_group->alloc_mutex);
2233 last_wanted = 0;
2226 continue; 2234 continue;
2227 } 2235 }
2228 2236
@@ -2240,6 +2248,11 @@ static int noinline find_free_extent(struct btrfs_trans_handle *trans,
2240 break; 2248 break;
2241 } 2249 }
2242new_group: 2250new_group:
2251 last_wanted = 0;
2252 if (loop > 0) {
2253 total_needed -= empty_cluster;
2254 empty_cluster = 0;
2255 }
2243 mutex_unlock(&block_group->alloc_mutex); 2256 mutex_unlock(&block_group->alloc_mutex);
2244 /* 2257 /*
2245 * Here's how this works. 2258 * Here's how this works.
@@ -2256,11 +2269,6 @@ new_group:
2256 if (loop == 0) { 2269 if (loop == 0) {
2257 head = &space_info->block_groups; 2270 head = &space_info->block_groups;
2258 cur = head->next; 2271 cur = head->next;
2259
2260 if (last_ptr && *last_ptr) {
2261 total_needed += empty_cluster;
2262 *last_ptr = 0;
2263 }
2264 loop++; 2272 loop++;
2265 } else if (loop == 1 && cur == head) { 2273 } else if (loop == 1 && cur == head) {
2266 if (allowed_chunk_alloc && !chunk_alloc_done) { 2274 if (allowed_chunk_alloc && !chunk_alloc_done) {