diff options
-rw-r--r-- | fs/btrfs/extent-tree.c | 28 |
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 | } |
2242 | new_group: | 2250 | new_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) { |