aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/free-space-cache.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index ad144736a5fd..930c07f79b3d 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -2144,6 +2144,7 @@ again:
2144 */ 2144 */
2145static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group, 2145static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,
2146 struct btrfs_free_cluster *cluster, 2146 struct btrfs_free_cluster *cluster,
2147 struct list_head *bitmaps,
2147 u64 offset, u64 bytes, u64 min_bytes) 2148 u64 offset, u64 bytes, u64 min_bytes)
2148{ 2149{
2149 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 2150 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
@@ -2166,6 +2167,8 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,
2166 * extent entry. 2167 * extent entry.
2167 */ 2168 */
2168 while (entry->bitmap) { 2169 while (entry->bitmap) {
2170 if (list_empty(&entry->list))
2171 list_add_tail(&entry->list, bitmaps);
2169 node = rb_next(&entry->offset_index); 2172 node = rb_next(&entry->offset_index);
2170 if (!node) 2173 if (!node)
2171 return -ENOSPC; 2174 return -ENOSPC;
@@ -2185,8 +2188,12 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,
2185 return -ENOSPC; 2188 return -ENOSPC;
2186 entry = rb_entry(node, struct btrfs_free_space, offset_index); 2189 entry = rb_entry(node, struct btrfs_free_space, offset_index);
2187 2190
2188 if (entry->bitmap) 2191 if (entry->bitmap) {
2192 if (list_empty(&entry->list))
2193 list_add_tail(&entry->list, bitmaps);
2189 continue; 2194 continue;
2195 }
2196
2190 /* 2197 /*
2191 * we haven't filled the empty size and the window is 2198 * we haven't filled the empty size and the window is
2192 * very large. reset and try again 2199 * very large. reset and try again
@@ -2240,6 +2247,7 @@ static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,
2240 */ 2247 */
2241static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group, 2248static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
2242 struct btrfs_free_cluster *cluster, 2249 struct btrfs_free_cluster *cluster,
2250 struct list_head *bitmaps,
2243 u64 offset, u64 bytes, u64 min_bytes) 2251 u64 offset, u64 bytes, u64 min_bytes)
2244{ 2252{
2245 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 2253 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
@@ -2250,10 +2258,39 @@ static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
2250 if (ctl->total_bitmaps == 0) 2258 if (ctl->total_bitmaps == 0)
2251 return -ENOSPC; 2259 return -ENOSPC;
2252 2260
2261 /*
2262 * First check our cached list of bitmaps and see if there is an entry
2263 * here that will work.
2264 */
2265 list_for_each_entry(entry, bitmaps, list) {
2266 if (entry->bytes < min_bytes)
2267 continue;
2268 ret = btrfs_bitmap_cluster(block_group, entry, cluster, offset,
2269 bytes, min_bytes);
2270 if (!ret)
2271 return 0;
2272 }
2273
2274 /*
2275 * If we do have entries on our list and we are here then we didn't find
2276 * anything, so go ahead and get the next entry after the last entry in
2277 * this list and start the search from there.
2278 */
2279 if (!list_empty(bitmaps)) {
2280 entry = list_entry(bitmaps->prev, struct btrfs_free_space,
2281 list);
2282 node = rb_next(&entry->offset_index);
2283 if (!node)
2284 return -ENOSPC;
2285 entry = rb_entry(node, struct btrfs_free_space, offset_index);
2286 goto search;
2287 }
2288
2253 entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1); 2289 entry = tree_search_offset(ctl, offset_to_bitmap(ctl, offset), 0, 1);
2254 if (!entry) 2290 if (!entry)
2255 return -ENOSPC; 2291 return -ENOSPC;
2256 2292
2293search:
2257 node = &entry->offset_index; 2294 node = &entry->offset_index;
2258 do { 2295 do {
2259 entry = rb_entry(node, struct btrfs_free_space, offset_index); 2296 entry = rb_entry(node, struct btrfs_free_space, offset_index);
@@ -2284,6 +2321,8 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
2284 u64 offset, u64 bytes, u64 empty_size) 2321 u64 offset, u64 bytes, u64 empty_size)
2285{ 2322{
2286 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl; 2323 struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
2324 struct list_head bitmaps;
2325 struct btrfs_free_space *entry, *tmp;
2287 u64 min_bytes; 2326 u64 min_bytes;
2288 int ret; 2327 int ret;
2289 2328
@@ -2322,11 +2361,16 @@ int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
2322 goto out; 2361 goto out;
2323 } 2362 }
2324 2363
2325 ret = setup_cluster_no_bitmap(block_group, cluster, offset, bytes, 2364 INIT_LIST_HEAD(&bitmaps);
2326 min_bytes); 2365 ret = setup_cluster_no_bitmap(block_group, cluster, &bitmaps, offset,
2366 bytes, min_bytes);
2327 if (ret) 2367 if (ret)
2328 ret = setup_cluster_bitmap(block_group, cluster, offset, 2368 ret = setup_cluster_bitmap(block_group, cluster, &bitmaps,
2329 bytes, min_bytes); 2369 offset, bytes, min_bytes);
2370
2371 /* Clear our temporary list */
2372 list_for_each_entry_safe(entry, tmp, &bitmaps, list)
2373 list_del_init(&entry->list);
2330 2374
2331 if (!ret) { 2375 if (!ret) {
2332 atomic_inc(&block_group->count); 2376 atomic_inc(&block_group->count);