blob: 655aad0f9e1c8cc4de27afaf8222959be2bf04cf [file] [log] [blame]
David Sterbac1d7c512018-04-03 19:23:33 +02001// SPDX-License-Identifier: GPL-2.0
Omar Sandovala5ed9182015-09-29 20:50:35 -07002/*
3 * Copyright (C) 2015 Facebook. All rights reserved.
Omar Sandovala5ed9182015-09-29 20:50:35 -07004 */
5
6#include <linux/kernel.h>
Omar Sandoval25ff17e2017-06-05 00:12:31 -07007#include <linux/sched/mm.h>
Omar Sandovala5ed9182015-09-29 20:50:35 -07008#include "ctree.h"
9#include "disk-io.h"
10#include "locking.h"
11#include "free-space-tree.h"
12#include "transaction.h"
Josef Bacikaac00232019-06-20 15:37:44 -040013#include "block-group.h"
Omar Sandovala5ed9182015-09-29 20:50:35 -070014
15static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +010016 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -070017 struct btrfs_path *path);
18
Josef Bacik7939dd92021-11-05 16:45:49 -040019static struct btrfs_root *btrfs_free_space_root(
20 struct btrfs_block_group *block_group)
21{
Josef Bacikabed4aa2021-11-05 16:45:51 -040022 struct btrfs_key key = {
23 .objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
24 .type = BTRFS_ROOT_ITEM_KEY,
25 .offset = 0,
26 };
27
28 return btrfs_global_root(block_group->fs_info, &key);
Josef Bacik7939dd92021-11-05 16:45:49 -040029}
30
David Sterba32da53862019-10-29 19:20:18 +010031void set_free_space_tree_thresholds(struct btrfs_block_group *cache)
Omar Sandovala5ed9182015-09-29 20:50:35 -070032{
33 u32 bitmap_range;
34 size_t bitmap_size;
35 u64 num_bitmaps, total_bitmap_size;
36
Marcos Paulo de Souzae3e39c72020-08-21 11:54:44 -030037 if (WARN_ON(cache->length == 0))
38 btrfs_warn(cache->fs_info, "block group %llu length is zero",
39 cache->start);
40
Omar Sandovala5ed9182015-09-29 20:50:35 -070041 /*
42 * We convert to bitmaps when the disk space required for using extents
43 * exceeds that required for using bitmaps.
44 */
Jeff Mahoneyda170662016-06-15 09:22:56 -040045 bitmap_range = cache->fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
David Sterbab3470b52019-10-23 18:48:22 +020046 num_bitmaps = div_u64(cache->length + bitmap_range - 1, bitmap_range);
Omar Sandovala5ed9182015-09-29 20:50:35 -070047 bitmap_size = sizeof(struct btrfs_item) + BTRFS_FREE_SPACE_BITMAP_SIZE;
48 total_bitmap_size = num_bitmaps * bitmap_size;
49 cache->bitmap_high_thresh = div_u64(total_bitmap_size,
50 sizeof(struct btrfs_item));
51
52 /*
53 * We allow for a small buffer between the high threshold and low
54 * threshold to avoid thrashing back and forth between the two formats.
55 */
56 if (cache->bitmap_high_thresh > 100)
57 cache->bitmap_low_thresh = cache->bitmap_high_thresh - 100;
58 else
59 cache->bitmap_low_thresh = 0;
60}
61
62static int add_new_free_space_info(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +010063 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -070064 struct btrfs_path *path)
65{
Josef Bacik7939dd92021-11-05 16:45:49 -040066 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -070067 struct btrfs_free_space_info *info;
68 struct btrfs_key key;
69 struct extent_buffer *leaf;
70 int ret;
71
David Sterbab3470b52019-10-23 18:48:22 +020072 key.objectid = block_group->start;
Omar Sandovala5ed9182015-09-29 20:50:35 -070073 key.type = BTRFS_FREE_SPACE_INFO_KEY;
David Sterbab3470b52019-10-23 18:48:22 +020074 key.offset = block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -070075
76 ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*info));
77 if (ret)
78 goto out;
79
80 leaf = path->nodes[0];
81 info = btrfs_item_ptr(leaf, path->slots[0],
82 struct btrfs_free_space_info);
83 btrfs_set_free_space_extent_count(leaf, info, 0);
84 btrfs_set_free_space_flags(leaf, info, 0);
85 btrfs_mark_buffer_dirty(leaf);
86
87 ret = 0;
88out:
89 btrfs_release_path(path);
90 return ret;
91}
92
Johannes Thumshirnce9f9672018-11-19 10:38:17 +010093EXPORT_FOR_TESTS
94struct btrfs_free_space_info *search_free_space_info(
David Sterba2ccf5452019-03-20 14:11:21 +010095 struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +010096 struct btrfs_block_group *block_group,
Johannes Thumshirnce9f9672018-11-19 10:38:17 +010097 struct btrfs_path *path, int cow)
Omar Sandovala5ed9182015-09-29 20:50:35 -070098{
David Sterba2ccf5452019-03-20 14:11:21 +010099 struct btrfs_fs_info *fs_info = block_group->fs_info;
Josef Bacik7939dd92021-11-05 16:45:49 -0400100 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700101 struct btrfs_key key;
102 int ret;
103
David Sterbab3470b52019-10-23 18:48:22 +0200104 key.objectid = block_group->start;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700105 key.type = BTRFS_FREE_SPACE_INFO_KEY;
David Sterbab3470b52019-10-23 18:48:22 +0200106 key.offset = block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700107
108 ret = btrfs_search_slot(trans, root, &key, path, 0, cow);
109 if (ret < 0)
110 return ERR_PTR(ret);
111 if (ret != 0) {
Jeff Mahoneyab8d0fc2016-09-20 10:05:02 -0400112 btrfs_warn(fs_info, "missing free space info for %llu",
David Sterbab3470b52019-10-23 18:48:22 +0200113 block_group->start);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700114 ASSERT(0);
115 return ERR_PTR(-ENOENT);
116 }
117
118 return btrfs_item_ptr(path->nodes[0], path->slots[0],
119 struct btrfs_free_space_info);
120}
121
122/*
123 * btrfs_search_slot() but we're looking for the greatest key less than the
124 * passed key.
125 */
126static int btrfs_search_prev_slot(struct btrfs_trans_handle *trans,
127 struct btrfs_root *root,
128 struct btrfs_key *key, struct btrfs_path *p,
129 int ins_len, int cow)
130{
131 int ret;
132
133 ret = btrfs_search_slot(trans, root, key, p, ins_len, cow);
134 if (ret < 0)
135 return ret;
136
137 if (ret == 0) {
138 ASSERT(0);
139 return -EIO;
140 }
141
142 if (p->slots[0] == 0) {
143 ASSERT(0);
144 return -EIO;
145 }
146 p->slots[0]--;
147
148 return 0;
149}
150
David Sterba098e6302020-07-01 21:07:40 +0200151static inline u32 free_space_bitmap_size(const struct btrfs_fs_info *fs_info,
152 u64 size)
Omar Sandovala5ed9182015-09-29 20:50:35 -0700153{
David Sterba098e6302020-07-01 21:07:40 +0200154 return DIV_ROUND_UP(size >> fs_info->sectorsize_bits, BITS_PER_BYTE);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700155}
156
Howard McLauchlana5659712018-04-18 18:02:36 -0700157static unsigned long *alloc_bitmap(u32 bitmap_size)
Omar Sandovala5ed9182015-09-29 20:50:35 -0700158{
Howard McLauchlana5659712018-04-18 18:02:36 -0700159 unsigned long *ret;
Omar Sandoval25ff17e2017-06-05 00:12:31 -0700160 unsigned int nofs_flag;
Howard McLauchlana5659712018-04-18 18:02:36 -0700161 u32 bitmap_rounded_size = round_up(bitmap_size, sizeof(unsigned long));
David Sterba79b134a2016-01-22 17:16:18 +0100162
163 /*
Omar Sandoval25ff17e2017-06-05 00:12:31 -0700164 * GFP_NOFS doesn't work with kvmalloc(), but we really can't recurse
165 * into the filesystem as the free space bitmap can be modified in the
166 * critical section of a transaction commit.
167 *
168 * TODO: push the memalloc_nofs_{save,restore}() to the caller where we
169 * know that recursion is unsafe.
David Sterba79b134a2016-01-22 17:16:18 +0100170 */
Omar Sandoval25ff17e2017-06-05 00:12:31 -0700171 nofs_flag = memalloc_nofs_save();
Howard McLauchlana5659712018-04-18 18:02:36 -0700172 ret = kvzalloc(bitmap_rounded_size, GFP_KERNEL);
Omar Sandoval25ff17e2017-06-05 00:12:31 -0700173 memalloc_nofs_restore(nofs_flag);
174 return ret;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700175}
176
Howard McLauchlana5659712018-04-18 18:02:36 -0700177static void le_bitmap_set(unsigned long *map, unsigned int start, int len)
Howard McLauchlan6faa8f42018-04-18 18:02:35 -0700178{
Howard McLauchlana5659712018-04-18 18:02:36 -0700179 u8 *p = ((u8 *)map) + BIT_BYTE(start);
Howard McLauchlan6faa8f42018-04-18 18:02:35 -0700180 const unsigned int size = start + len;
181 int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
182 u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
183
184 while (len - bits_to_set >= 0) {
185 *p |= mask_to_set;
186 len -= bits_to_set;
187 bits_to_set = BITS_PER_BYTE;
188 mask_to_set = ~0;
189 p++;
190 }
191 if (len) {
192 mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
193 *p |= mask_to_set;
194 }
195}
196
Johannes Thumshirnce9f9672018-11-19 10:38:17 +0100197EXPORT_FOR_TESTS
Omar Sandovala5ed9182015-09-29 20:50:35 -0700198int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100199 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700200 struct btrfs_path *path)
201{
Nikolay Borisov719fb4d2018-05-10 15:44:47 +0300202 struct btrfs_fs_info *fs_info = trans->fs_info;
Josef Bacik7939dd92021-11-05 16:45:49 -0400203 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700204 struct btrfs_free_space_info *info;
205 struct btrfs_key key, found_key;
206 struct extent_buffer *leaf;
Howard McLauchlana5659712018-04-18 18:02:36 -0700207 unsigned long *bitmap;
208 char *bitmap_cursor;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700209 u64 start, end;
210 u64 bitmap_range, i;
211 u32 bitmap_size, flags, expected_extent_count;
212 u32 extent_count = 0;
213 int done = 0, nr;
214 int ret;
215
David Sterba098e6302020-07-01 21:07:40 +0200216 bitmap_size = free_space_bitmap_size(fs_info, block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700217 bitmap = alloc_bitmap(bitmap_size);
218 if (!bitmap) {
219 ret = -ENOMEM;
220 goto out;
221 }
222
David Sterbab3470b52019-10-23 18:48:22 +0200223 start = block_group->start;
224 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700225
226 key.objectid = end - 1;
227 key.type = (u8)-1;
228 key.offset = (u64)-1;
229
230 while (!done) {
231 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
232 if (ret)
233 goto out;
234
235 leaf = path->nodes[0];
236 nr = 0;
237 path->slots[0]++;
238 while (path->slots[0] > 0) {
239 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
240
241 if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
David Sterbab3470b52019-10-23 18:48:22 +0200242 ASSERT(found_key.objectid == block_group->start);
243 ASSERT(found_key.offset == block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700244 done = 1;
245 break;
246 } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) {
247 u64 first, last;
248
249 ASSERT(found_key.objectid >= start);
250 ASSERT(found_key.objectid < end);
251 ASSERT(found_key.objectid + found_key.offset <= end);
252
253 first = div_u64(found_key.objectid - start,
Jeff Mahoney0b246af2016-06-22 18:54:23 -0400254 fs_info->sectorsize);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700255 last = div_u64(found_key.objectid + found_key.offset - start,
Jeff Mahoney0b246af2016-06-22 18:54:23 -0400256 fs_info->sectorsize);
Omar Sandoval2fe1d552016-09-22 17:24:20 -0700257 le_bitmap_set(bitmap, first, last - first);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700258
259 extent_count++;
260 nr++;
261 path->slots[0]--;
262 } else {
263 ASSERT(0);
264 }
265 }
266
267 ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
268 if (ret)
269 goto out;
270 btrfs_release_path(path);
271 }
272
David Sterba2ccf5452019-03-20 14:11:21 +0100273 info = search_free_space_info(trans, block_group, path, 1);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700274 if (IS_ERR(info)) {
275 ret = PTR_ERR(info);
276 goto out;
277 }
278 leaf = path->nodes[0];
279 flags = btrfs_free_space_flags(leaf, info);
280 flags |= BTRFS_FREE_SPACE_USING_BITMAPS;
281 btrfs_set_free_space_flags(leaf, info, flags);
282 expected_extent_count = btrfs_free_space_extent_count(leaf, info);
283 btrfs_mark_buffer_dirty(leaf);
284 btrfs_release_path(path);
285
286 if (extent_count != expected_extent_count) {
Jeff Mahoney5d163e02016-09-20 10:05:00 -0400287 btrfs_err(fs_info,
288 "incorrect extent count for %llu; counted %u, expected %u",
David Sterbab3470b52019-10-23 18:48:22 +0200289 block_group->start, extent_count,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700290 expected_extent_count);
291 ASSERT(0);
292 ret = -EIO;
293 goto out;
294 }
295
Howard McLauchlana5659712018-04-18 18:02:36 -0700296 bitmap_cursor = (char *)bitmap;
Jeff Mahoney0b246af2016-06-22 18:54:23 -0400297 bitmap_range = fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700298 i = start;
299 while (i < end) {
300 unsigned long ptr;
301 u64 extent_size;
302 u32 data_size;
303
304 extent_size = min(end - i, bitmap_range);
David Sterba098e6302020-07-01 21:07:40 +0200305 data_size = free_space_bitmap_size(fs_info, extent_size);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700306
307 key.objectid = i;
308 key.type = BTRFS_FREE_SPACE_BITMAP_KEY;
309 key.offset = extent_size;
310
311 ret = btrfs_insert_empty_item(trans, root, path, &key,
312 data_size);
313 if (ret)
314 goto out;
315
316 leaf = path->nodes[0];
317 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
318 write_extent_buffer(leaf, bitmap_cursor, ptr,
319 data_size);
320 btrfs_mark_buffer_dirty(leaf);
321 btrfs_release_path(path);
322
323 i += extent_size;
324 bitmap_cursor += data_size;
325 }
326
327 ret = 0;
328out:
David Sterba79b134a2016-01-22 17:16:18 +0100329 kvfree(bitmap);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700330 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -0400331 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700332 return ret;
333}
334
Johannes Thumshirnce9f9672018-11-19 10:38:17 +0100335EXPORT_FOR_TESTS
Omar Sandovala5ed9182015-09-29 20:50:35 -0700336int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100337 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700338 struct btrfs_path *path)
339{
Nikolay Borisov5296c2b2018-05-10 15:44:48 +0300340 struct btrfs_fs_info *fs_info = trans->fs_info;
Josef Bacik7939dd92021-11-05 16:45:49 -0400341 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700342 struct btrfs_free_space_info *info;
343 struct btrfs_key key, found_key;
344 struct extent_buffer *leaf;
Howard McLauchlana5659712018-04-18 18:02:36 -0700345 unsigned long *bitmap;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700346 u64 start, end;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700347 u32 bitmap_size, flags, expected_extent_count;
Howard McLauchlana5659712018-04-18 18:02:36 -0700348 unsigned long nrbits, start_bit, end_bit;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700349 u32 extent_count = 0;
350 int done = 0, nr;
351 int ret;
352
David Sterba098e6302020-07-01 21:07:40 +0200353 bitmap_size = free_space_bitmap_size(fs_info, block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700354 bitmap = alloc_bitmap(bitmap_size);
355 if (!bitmap) {
356 ret = -ENOMEM;
357 goto out;
358 }
359
David Sterbab3470b52019-10-23 18:48:22 +0200360 start = block_group->start;
361 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700362
363 key.objectid = end - 1;
364 key.type = (u8)-1;
365 key.offset = (u64)-1;
366
367 while (!done) {
368 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
369 if (ret)
370 goto out;
371
372 leaf = path->nodes[0];
373 nr = 0;
374 path->slots[0]++;
375 while (path->slots[0] > 0) {
376 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
377
378 if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
David Sterbab3470b52019-10-23 18:48:22 +0200379 ASSERT(found_key.objectid == block_group->start);
380 ASSERT(found_key.offset == block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700381 done = 1;
382 break;
383 } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
384 unsigned long ptr;
Howard McLauchlana5659712018-04-18 18:02:36 -0700385 char *bitmap_cursor;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700386 u32 bitmap_pos, data_size;
387
388 ASSERT(found_key.objectid >= start);
389 ASSERT(found_key.objectid < end);
390 ASSERT(found_key.objectid + found_key.offset <= end);
391
392 bitmap_pos = div_u64(found_key.objectid - start,
Jeff Mahoney0b246af2016-06-22 18:54:23 -0400393 fs_info->sectorsize *
Omar Sandovala5ed9182015-09-29 20:50:35 -0700394 BITS_PER_BYTE);
Howard McLauchlana5659712018-04-18 18:02:36 -0700395 bitmap_cursor = ((char *)bitmap) + bitmap_pos;
David Sterba098e6302020-07-01 21:07:40 +0200396 data_size = free_space_bitmap_size(fs_info,
397 found_key.offset);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700398
399 ptr = btrfs_item_ptr_offset(leaf, path->slots[0] - 1);
400 read_extent_buffer(leaf, bitmap_cursor, ptr,
401 data_size);
402
403 nr++;
404 path->slots[0]--;
405 } else {
406 ASSERT(0);
407 }
408 }
409
410 ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
411 if (ret)
412 goto out;
413 btrfs_release_path(path);
414 }
415
David Sterba2ccf5452019-03-20 14:11:21 +0100416 info = search_free_space_info(trans, block_group, path, 1);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700417 if (IS_ERR(info)) {
418 ret = PTR_ERR(info);
419 goto out;
420 }
421 leaf = path->nodes[0];
422 flags = btrfs_free_space_flags(leaf, info);
423 flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS;
424 btrfs_set_free_space_flags(leaf, info, flags);
425 expected_extent_count = btrfs_free_space_extent_count(leaf, info);
426 btrfs_mark_buffer_dirty(leaf);
427 btrfs_release_path(path);
428
David Sterbaab108d92020-07-01 20:45:04 +0200429 nrbits = block_group->length >> block_group->fs_info->sectorsize_bits;
Howard McLauchlana5659712018-04-18 18:02:36 -0700430 start_bit = find_next_bit_le(bitmap, nrbits, 0);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700431
Howard McLauchlana5659712018-04-18 18:02:36 -0700432 while (start_bit < nrbits) {
433 end_bit = find_next_zero_bit_le(bitmap, nrbits, start_bit);
434 ASSERT(start_bit < end_bit);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700435
Howard McLauchlana5659712018-04-18 18:02:36 -0700436 key.objectid = start + start_bit * block_group->fs_info->sectorsize;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700437 key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
Howard McLauchlana5659712018-04-18 18:02:36 -0700438 key.offset = (end_bit - start_bit) * block_group->fs_info->sectorsize;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700439
440 ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
441 if (ret)
442 goto out;
443 btrfs_release_path(path);
444
445 extent_count++;
Howard McLauchlana5659712018-04-18 18:02:36 -0700446
447 start_bit = find_next_bit_le(bitmap, nrbits, end_bit);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700448 }
449
450 if (extent_count != expected_extent_count) {
Jeff Mahoney5d163e02016-09-20 10:05:00 -0400451 btrfs_err(fs_info,
452 "incorrect extent count for %llu; counted %u, expected %u",
David Sterbab3470b52019-10-23 18:48:22 +0200453 block_group->start, extent_count,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700454 expected_extent_count);
455 ASSERT(0);
456 ret = -EIO;
457 goto out;
458 }
459
460 ret = 0;
461out:
David Sterba79b134a2016-01-22 17:16:18 +0100462 kvfree(bitmap);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700463 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -0400464 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700465 return ret;
466}
467
468static int update_free_space_extent_count(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100469 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700470 struct btrfs_path *path,
471 int new_extents)
472{
473 struct btrfs_free_space_info *info;
474 u32 flags;
475 u32 extent_count;
476 int ret = 0;
477
478 if (new_extents == 0)
479 return 0;
480
David Sterba2ccf5452019-03-20 14:11:21 +0100481 info = search_free_space_info(trans, block_group, path, 1);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700482 if (IS_ERR(info)) {
483 ret = PTR_ERR(info);
484 goto out;
485 }
486 flags = btrfs_free_space_flags(path->nodes[0], info);
487 extent_count = btrfs_free_space_extent_count(path->nodes[0], info);
488
489 extent_count += new_extents;
490 btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count);
491 btrfs_mark_buffer_dirty(path->nodes[0]);
492 btrfs_release_path(path);
493
494 if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
495 extent_count > block_group->bitmap_high_thresh) {
Nikolay Borisov719fb4d2018-05-10 15:44:47 +0300496 ret = convert_free_space_to_bitmaps(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700497 } else if ((flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
498 extent_count < block_group->bitmap_low_thresh) {
Nikolay Borisov5296c2b2018-05-10 15:44:48 +0300499 ret = convert_free_space_to_extents(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700500 }
501
502out:
503 return ret;
504}
505
Johannes Thumshirnce9f9672018-11-19 10:38:17 +0100506EXPORT_FOR_TESTS
David Sterba32da53862019-10-29 19:20:18 +0100507int free_space_test_bit(struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700508 struct btrfs_path *path, u64 offset)
509{
510 struct extent_buffer *leaf;
511 struct btrfs_key key;
512 u64 found_start, found_end;
513 unsigned long ptr, i;
514
515 leaf = path->nodes[0];
516 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
517 ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
518
519 found_start = key.objectid;
520 found_end = key.objectid + key.offset;
521 ASSERT(offset >= found_start && offset < found_end);
522
523 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
Jeff Mahoneyda170662016-06-15 09:22:56 -0400524 i = div_u64(offset - found_start,
525 block_group->fs_info->sectorsize);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700526 return !!extent_buffer_test_bit(leaf, ptr, i);
527}
528
David Sterba32da53862019-10-29 19:20:18 +0100529static void free_space_set_bits(struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700530 struct btrfs_path *path, u64 *start, u64 *size,
531 int bit)
532{
Jeff Mahoney0b246af2016-06-22 18:54:23 -0400533 struct btrfs_fs_info *fs_info = block_group->fs_info;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700534 struct extent_buffer *leaf;
535 struct btrfs_key key;
536 u64 end = *start + *size;
537 u64 found_start, found_end;
538 unsigned long ptr, first, last;
539
540 leaf = path->nodes[0];
541 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
542 ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
543
544 found_start = key.objectid;
545 found_end = key.objectid + key.offset;
546 ASSERT(*start >= found_start && *start < found_end);
547 ASSERT(end > found_start);
548
549 if (end > found_end)
550 end = found_end;
551
552 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
David Sterbaab108d92020-07-01 20:45:04 +0200553 first = (*start - found_start) >> fs_info->sectorsize_bits;
554 last = (end - found_start) >> fs_info->sectorsize_bits;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700555 if (bit)
556 extent_buffer_bitmap_set(leaf, ptr, first, last - first);
557 else
558 extent_buffer_bitmap_clear(leaf, ptr, first, last - first);
559 btrfs_mark_buffer_dirty(leaf);
560
561 *size -= end - *start;
562 *start = end;
563}
564
565/*
566 * We can't use btrfs_next_item() in modify_free_space_bitmap() because
567 * btrfs_next_leaf() doesn't get the path for writing. We can forgo the fancy
568 * tree walking in btrfs_next_leaf() anyways because we know exactly what we're
569 * looking for.
570 */
571static int free_space_next_bitmap(struct btrfs_trans_handle *trans,
572 struct btrfs_root *root, struct btrfs_path *p)
573{
574 struct btrfs_key key;
575
576 if (p->slots[0] + 1 < btrfs_header_nritems(p->nodes[0])) {
577 p->slots[0]++;
578 return 0;
579 }
580
581 btrfs_item_key_to_cpu(p->nodes[0], &key, p->slots[0]);
582 btrfs_release_path(p);
583
584 key.objectid += key.offset;
585 key.type = (u8)-1;
586 key.offset = (u64)-1;
587
588 return btrfs_search_prev_slot(trans, root, &key, p, 0, 1);
589}
590
591/*
592 * If remove is 1, then we are removing free space, thus clearing bits in the
593 * bitmap. If remove is 0, then we are adding free space, thus setting bits in
594 * the bitmap.
595 */
596static int modify_free_space_bitmap(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100597 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700598 struct btrfs_path *path,
599 u64 start, u64 size, int remove)
600{
Josef Bacik7939dd92021-11-05 16:45:49 -0400601 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700602 struct btrfs_key key;
603 u64 end = start + size;
604 u64 cur_start, cur_size;
605 int prev_bit, next_bit;
606 int new_extents;
607 int ret;
608
609 /*
610 * Read the bit for the block immediately before the extent of space if
611 * that block is within the block group.
612 */
David Sterbab3470b52019-10-23 18:48:22 +0200613 if (start > block_group->start) {
Jeff Mahoneyda170662016-06-15 09:22:56 -0400614 u64 prev_block = start - block_group->fs_info->sectorsize;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700615
616 key.objectid = prev_block;
617 key.type = (u8)-1;
618 key.offset = (u64)-1;
619
620 ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);
621 if (ret)
622 goto out;
623
624 prev_bit = free_space_test_bit(block_group, path, prev_block);
625
626 /* The previous block may have been in the previous bitmap. */
627 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
628 if (start >= key.objectid + key.offset) {
629 ret = free_space_next_bitmap(trans, root, path);
630 if (ret)
631 goto out;
632 }
633 } else {
634 key.objectid = start;
635 key.type = (u8)-1;
636 key.offset = (u64)-1;
637
638 ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);
639 if (ret)
640 goto out;
641
642 prev_bit = -1;
643 }
644
645 /*
646 * Iterate over all of the bitmaps overlapped by the extent of space,
647 * clearing/setting bits as required.
648 */
649 cur_start = start;
650 cur_size = size;
651 while (1) {
652 free_space_set_bits(block_group, path, &cur_start, &cur_size,
653 !remove);
654 if (cur_size == 0)
655 break;
656 ret = free_space_next_bitmap(trans, root, path);
657 if (ret)
658 goto out;
659 }
660
661 /*
662 * Read the bit for the block immediately after the extent of space if
663 * that block is within the block group.
664 */
David Sterbab3470b52019-10-23 18:48:22 +0200665 if (end < block_group->start + block_group->length) {
Omar Sandovala5ed9182015-09-29 20:50:35 -0700666 /* The next block may be in the next bitmap. */
667 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
668 if (end >= key.objectid + key.offset) {
669 ret = free_space_next_bitmap(trans, root, path);
670 if (ret)
671 goto out;
672 }
673
674 next_bit = free_space_test_bit(block_group, path, end);
675 } else {
676 next_bit = -1;
677 }
678
679 if (remove) {
680 new_extents = -1;
681 if (prev_bit == 1) {
682 /* Leftover on the left. */
683 new_extents++;
684 }
685 if (next_bit == 1) {
686 /* Leftover on the right. */
687 new_extents++;
688 }
689 } else {
690 new_extents = 1;
691 if (prev_bit == 1) {
692 /* Merging with neighbor on the left. */
693 new_extents--;
694 }
695 if (next_bit == 1) {
696 /* Merging with neighbor on the right. */
697 new_extents--;
698 }
699 }
700
701 btrfs_release_path(path);
Nikolay Borisov690d7682018-05-10 15:44:49 +0300702 ret = update_free_space_extent_count(trans, block_group, path,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700703 new_extents);
704
705out:
706 return ret;
707}
708
709static int remove_free_space_extent(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100710 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700711 struct btrfs_path *path,
712 u64 start, u64 size)
713{
Josef Bacik7939dd92021-11-05 16:45:49 -0400714 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700715 struct btrfs_key key;
716 u64 found_start, found_end;
717 u64 end = start + size;
718 int new_extents = -1;
719 int ret;
720
721 key.objectid = start;
722 key.type = (u8)-1;
723 key.offset = (u64)-1;
724
725 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
726 if (ret)
727 goto out;
728
729 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
730
731 ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
732
733 found_start = key.objectid;
734 found_end = key.objectid + key.offset;
735 ASSERT(start >= found_start && end <= found_end);
736
737 /*
738 * Okay, now that we've found the free space extent which contains the
739 * free space that we are removing, there are four cases:
740 *
741 * 1. We're using the whole extent: delete the key we found and
742 * decrement the free space extent count.
743 * 2. We are using part of the extent starting at the beginning: delete
744 * the key we found and insert a new key representing the leftover at
745 * the end. There is no net change in the number of extents.
746 * 3. We are using part of the extent ending at the end: delete the key
747 * we found and insert a new key representing the leftover at the
748 * beginning. There is no net change in the number of extents.
749 * 4. We are using part of the extent in the middle: delete the key we
750 * found and insert two new keys representing the leftovers on each
751 * side. Where we used to have one extent, we now have two, so increment
752 * the extent count. We may need to convert the block group to bitmaps
753 * as a result.
754 */
755
756 /* Delete the existing key (cases 1-4). */
757 ret = btrfs_del_item(trans, root, path);
758 if (ret)
759 goto out;
760
761 /* Add a key for leftovers at the beginning (cases 3 and 4). */
762 if (start > found_start) {
763 key.objectid = found_start;
764 key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
765 key.offset = start - found_start;
766
767 btrfs_release_path(path);
768 ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
769 if (ret)
770 goto out;
771 new_extents++;
772 }
773
774 /* Add a key for leftovers at the end (cases 2 and 4). */
775 if (end < found_end) {
776 key.objectid = end;
777 key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
778 key.offset = found_end - end;
779
780 btrfs_release_path(path);
781 ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
782 if (ret)
783 goto out;
784 new_extents++;
785 }
786
787 btrfs_release_path(path);
Nikolay Borisov690d7682018-05-10 15:44:49 +0300788 ret = update_free_space_extent_count(trans, block_group, path,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700789 new_extents);
790
791out:
792 return ret;
793}
794
Johannes Thumshirnce9f9672018-11-19 10:38:17 +0100795EXPORT_FOR_TESTS
Omar Sandovala5ed9182015-09-29 20:50:35 -0700796int __remove_from_free_space_tree(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100797 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700798 struct btrfs_path *path, u64 start, u64 size)
799{
800 struct btrfs_free_space_info *info;
801 u32 flags;
802 int ret;
803
804 if (block_group->needs_free_space) {
Nikolay Borisov9a7e0f92018-05-10 15:44:42 +0300805 ret = __add_block_group_free_space(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700806 if (ret)
807 return ret;
808 }
809
David Sterba2ccf5452019-03-20 14:11:21 +0100810 info = search_free_space_info(NULL, block_group, path, 0);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700811 if (IS_ERR(info))
812 return PTR_ERR(info);
813 flags = btrfs_free_space_flags(path->nodes[0], info);
814 btrfs_release_path(path);
815
816 if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
Nikolay Borisov85a7ef12018-05-10 15:44:50 +0300817 return modify_free_space_bitmap(trans, block_group, path,
818 start, size, 1);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700819 } else {
Nikolay Borisove5811682018-05-10 15:44:52 +0300820 return remove_free_space_extent(trans, block_group, path,
821 start, size);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700822 }
823}
824
825int remove_from_free_space_tree(struct btrfs_trans_handle *trans,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700826 u64 start, u64 size)
827{
David Sterba32da53862019-10-29 19:20:18 +0100828 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -0700829 struct btrfs_path *path;
830 int ret;
831
Nikolay Borisov25a356d2018-05-10 15:44:54 +0300832 if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
Omar Sandovala5ed9182015-09-29 20:50:35 -0700833 return 0;
834
835 path = btrfs_alloc_path();
836 if (!path) {
837 ret = -ENOMEM;
838 goto out;
839 }
840
Nikolay Borisov25a356d2018-05-10 15:44:54 +0300841 block_group = btrfs_lookup_block_group(trans->fs_info, start);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700842 if (!block_group) {
843 ASSERT(0);
844 ret = -ENOENT;
845 goto out;
846 }
847
848 mutex_lock(&block_group->free_space_lock);
Nikolay Borisovc31683a2018-05-10 15:44:53 +0300849 ret = __remove_from_free_space_tree(trans, block_group, path, start,
850 size);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700851 mutex_unlock(&block_group->free_space_lock);
852
853 btrfs_put_block_group(block_group);
854out:
855 btrfs_free_path(path);
856 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -0400857 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700858 return ret;
859}
860
861static int add_free_space_extent(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100862 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700863 struct btrfs_path *path,
864 u64 start, u64 size)
865{
Josef Bacik7939dd92021-11-05 16:45:49 -0400866 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700867 struct btrfs_key key, new_key;
868 u64 found_start, found_end;
869 u64 end = start + size;
870 int new_extents = 1;
871 int ret;
872
873 /*
874 * We are adding a new extent of free space, but we need to merge
875 * extents. There are four cases here:
876 *
877 * 1. The new extent does not have any immediate neighbors to merge
878 * with: add the new key and increment the free space extent count. We
879 * may need to convert the block group to bitmaps as a result.
880 * 2. The new extent has an immediate neighbor before it: remove the
881 * previous key and insert a new key combining both of them. There is no
882 * net change in the number of extents.
883 * 3. The new extent has an immediate neighbor after it: remove the next
884 * key and insert a new key combining both of them. There is no net
885 * change in the number of extents.
886 * 4. The new extent has immediate neighbors on both sides: remove both
887 * of the keys and insert a new key combining all of them. Where we used
888 * to have two extents, we now have one, so decrement the extent count.
889 */
890
891 new_key.objectid = start;
892 new_key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
893 new_key.offset = size;
894
895 /* Search for a neighbor on the left. */
David Sterbab3470b52019-10-23 18:48:22 +0200896 if (start == block_group->start)
Omar Sandovala5ed9182015-09-29 20:50:35 -0700897 goto right;
898 key.objectid = start - 1;
899 key.type = (u8)-1;
900 key.offset = (u64)-1;
901
902 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
903 if (ret)
904 goto out;
905
906 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
907
908 if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {
909 ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);
910 btrfs_release_path(path);
911 goto right;
912 }
913
914 found_start = key.objectid;
915 found_end = key.objectid + key.offset;
David Sterbab3470b52019-10-23 18:48:22 +0200916 ASSERT(found_start >= block_group->start &&
917 found_end > block_group->start);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700918 ASSERT(found_start < start && found_end <= start);
919
920 /*
921 * Delete the neighbor on the left and absorb it into the new key (cases
922 * 2 and 4).
923 */
924 if (found_end == start) {
925 ret = btrfs_del_item(trans, root, path);
926 if (ret)
927 goto out;
928 new_key.objectid = found_start;
929 new_key.offset += key.offset;
930 new_extents--;
931 }
932 btrfs_release_path(path);
933
934right:
935 /* Search for a neighbor on the right. */
David Sterbab3470b52019-10-23 18:48:22 +0200936 if (end == block_group->start + block_group->length)
Omar Sandovala5ed9182015-09-29 20:50:35 -0700937 goto insert;
938 key.objectid = end;
939 key.type = (u8)-1;
940 key.offset = (u64)-1;
941
942 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
943 if (ret)
944 goto out;
945
946 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
947
948 if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {
949 ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);
950 btrfs_release_path(path);
951 goto insert;
952 }
953
954 found_start = key.objectid;
955 found_end = key.objectid + key.offset;
David Sterbab3470b52019-10-23 18:48:22 +0200956 ASSERT(found_start >= block_group->start &&
957 found_end > block_group->start);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700958 ASSERT((found_start < start && found_end <= start) ||
959 (found_start >= end && found_end > end));
960
961 /*
962 * Delete the neighbor on the right and absorb it into the new key
963 * (cases 3 and 4).
964 */
965 if (found_start == end) {
966 ret = btrfs_del_item(trans, root, path);
967 if (ret)
968 goto out;
969 new_key.offset += key.offset;
970 new_extents--;
971 }
972 btrfs_release_path(path);
973
974insert:
975 /* Insert the new key (cases 1-4). */
976 ret = btrfs_insert_empty_item(trans, root, path, &new_key, 0);
977 if (ret)
978 goto out;
979
980 btrfs_release_path(path);
Nikolay Borisov690d7682018-05-10 15:44:49 +0300981 ret = update_free_space_extent_count(trans, block_group, path,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700982 new_extents);
983
984out:
985 return ret;
986}
987
Johannes Thumshirnce9f9672018-11-19 10:38:17 +0100988EXPORT_FOR_TESTS
Omar Sandovala5ed9182015-09-29 20:50:35 -0700989int __add_to_free_space_tree(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +0100990 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -0700991 struct btrfs_path *path, u64 start, u64 size)
992{
993 struct btrfs_free_space_info *info;
994 u32 flags;
995 int ret;
996
997 if (block_group->needs_free_space) {
Nikolay Borisov9a7e0f92018-05-10 15:44:42 +0300998 ret = __add_block_group_free_space(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -0700999 if (ret)
1000 return ret;
1001 }
1002
David Sterba2ccf5452019-03-20 14:11:21 +01001003 info = search_free_space_info(NULL, block_group, path, 0);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001004 if (IS_ERR(info))
1005 return PTR_ERR(info);
1006 flags = btrfs_free_space_flags(path->nodes[0], info);
1007 btrfs_release_path(path);
1008
1009 if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
Nikolay Borisov85a7ef12018-05-10 15:44:50 +03001010 return modify_free_space_bitmap(trans, block_group, path,
1011 start, size, 0);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001012 } else {
Nikolay Borisov5cb17822018-05-10 15:44:51 +03001013 return add_free_space_extent(trans, block_group, path, start,
1014 size);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001015 }
1016}
1017
1018int add_to_free_space_tree(struct btrfs_trans_handle *trans,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001019 u64 start, u64 size)
1020{
David Sterba32da53862019-10-29 19:20:18 +01001021 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001022 struct btrfs_path *path;
1023 int ret;
1024
Nikolay Borisove7355e52018-05-10 15:44:55 +03001025 if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
Omar Sandovala5ed9182015-09-29 20:50:35 -07001026 return 0;
1027
1028 path = btrfs_alloc_path();
1029 if (!path) {
1030 ret = -ENOMEM;
1031 goto out;
1032 }
1033
Nikolay Borisove7355e52018-05-10 15:44:55 +03001034 block_group = btrfs_lookup_block_group(trans->fs_info, start);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001035 if (!block_group) {
1036 ASSERT(0);
1037 ret = -ENOENT;
1038 goto out;
1039 }
1040
1041 mutex_lock(&block_group->free_space_lock);
Nikolay Borisov2d5cffa2018-05-10 15:44:43 +03001042 ret = __add_to_free_space_tree(trans, block_group, path, start, size);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001043 mutex_unlock(&block_group->free_space_lock);
1044
1045 btrfs_put_block_group(block_group);
1046out:
1047 btrfs_free_path(path);
1048 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -04001049 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001050 return ret;
1051}
1052
1053/*
1054 * Populate the free space tree by walking the extent tree. Operations on the
1055 * extent tree that happen as a result of writes to the free space tree will go
1056 * through the normal add/remove hooks.
1057 */
1058static int populate_free_space_tree(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +01001059 struct btrfs_block_group *block_group)
Omar Sandovala5ed9182015-09-29 20:50:35 -07001060{
Josef Bacik29cbcf42021-11-05 16:45:45 -04001061 struct btrfs_root *extent_root;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001062 struct btrfs_path *path, *path2;
1063 struct btrfs_key key;
1064 u64 start, end;
1065 int ret;
1066
1067 path = btrfs_alloc_path();
1068 if (!path)
1069 return -ENOMEM;
Gu Jinxiang019599a2018-01-11 16:12:17 +08001070 path->reada = READA_FORWARD;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001071
1072 path2 = btrfs_alloc_path();
1073 if (!path2) {
1074 btrfs_free_path(path);
1075 return -ENOMEM;
1076 }
1077
Nikolay Borisov66afee12018-05-10 15:44:44 +03001078 ret = add_new_free_space_info(trans, block_group, path2);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001079 if (ret)
1080 goto out;
1081
Chris Mason511711a2015-12-30 07:52:35 -08001082 mutex_lock(&block_group->free_space_lock);
1083
Omar Sandovala5ed9182015-09-29 20:50:35 -07001084 /*
1085 * Iterate through all of the extent and metadata items in this block
1086 * group, adding the free space between them and the free space at the
1087 * end. Note that EXTENT_ITEM and METADATA_ITEM are less than
1088 * BLOCK_GROUP_ITEM, so an extent may precede the block group that it's
1089 * contained in.
1090 */
David Sterbab3470b52019-10-23 18:48:22 +02001091 key.objectid = block_group->start;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001092 key.type = BTRFS_EXTENT_ITEM_KEY;
1093 key.offset = 0;
1094
Josef Bacik29cbcf42021-11-05 16:45:45 -04001095 extent_root = btrfs_extent_root(trans->fs_info, key.objectid);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001096 ret = btrfs_search_slot_for_read(extent_root, &key, path, 1, 0);
1097 if (ret < 0)
Chris Mason511711a2015-12-30 07:52:35 -08001098 goto out_locked;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001099 ASSERT(ret == 0);
1100
David Sterbab3470b52019-10-23 18:48:22 +02001101 start = block_group->start;
1102 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001103 while (1) {
1104 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
1105
1106 if (key.type == BTRFS_EXTENT_ITEM_KEY ||
1107 key.type == BTRFS_METADATA_ITEM_KEY) {
1108 if (key.objectid >= end)
1109 break;
1110
1111 if (start < key.objectid) {
Nikolay Borisov2d5cffa2018-05-10 15:44:43 +03001112 ret = __add_to_free_space_tree(trans,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001113 block_group,
1114 path2, start,
1115 key.objectid -
1116 start);
1117 if (ret)
Chris Mason511711a2015-12-30 07:52:35 -08001118 goto out_locked;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001119 }
1120 start = key.objectid;
1121 if (key.type == BTRFS_METADATA_ITEM_KEY)
Nikolay Borisovffa9a9e2018-05-10 15:44:56 +03001122 start += trans->fs_info->nodesize;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001123 else
1124 start += key.offset;
1125 } else if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
David Sterbab3470b52019-10-23 18:48:22 +02001126 if (key.objectid != block_group->start)
Omar Sandovala5ed9182015-09-29 20:50:35 -07001127 break;
1128 }
1129
1130 ret = btrfs_next_item(extent_root, path);
1131 if (ret < 0)
Chris Mason511711a2015-12-30 07:52:35 -08001132 goto out_locked;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001133 if (ret)
1134 break;
1135 }
1136 if (start < end) {
Nikolay Borisov2d5cffa2018-05-10 15:44:43 +03001137 ret = __add_to_free_space_tree(trans, block_group, path2,
1138 start, end - start);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001139 if (ret)
Chris Mason511711a2015-12-30 07:52:35 -08001140 goto out_locked;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001141 }
1142
1143 ret = 0;
Chris Mason511711a2015-12-30 07:52:35 -08001144out_locked:
1145 mutex_unlock(&block_group->free_space_lock);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001146out:
1147 btrfs_free_path(path2);
1148 btrfs_free_path(path);
1149 return ret;
1150}
1151
1152int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
1153{
1154 struct btrfs_trans_handle *trans;
1155 struct btrfs_root *tree_root = fs_info->tree_root;
1156 struct btrfs_root *free_space_root;
David Sterba32da53862019-10-29 19:20:18 +01001157 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001158 struct rb_node *node;
1159 int ret;
1160
1161 trans = btrfs_start_transaction(tree_root, 0);
1162 if (IS_ERR(trans))
1163 return PTR_ERR(trans);
1164
Josef Bacikafcdd122016-09-02 15:40:02 -04001165 set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
Josef Bacik2f96e402021-01-15 16:26:17 -05001166 set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
David Sterba9b7a2442019-03-20 13:20:49 +01001167 free_space_root = btrfs_create_tree(trans,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001168 BTRFS_FREE_SPACE_TREE_OBJECTID);
1169 if (IS_ERR(free_space_root)) {
1170 ret = PTR_ERR(free_space_root);
1171 goto abort;
1172 }
Josef Bacikabed4aa2021-11-05 16:45:51 -04001173 ret = btrfs_global_root_insert(free_space_root);
1174 if (ret) {
1175 btrfs_put_root(free_space_root);
1176 goto abort;
1177 }
Omar Sandovala5ed9182015-09-29 20:50:35 -07001178
1179 node = rb_first(&fs_info->block_group_cache_tree);
1180 while (node) {
David Sterba32da53862019-10-29 19:20:18 +01001181 block_group = rb_entry(node, struct btrfs_block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001182 cache_node);
Nikolay Borisovffa9a9e2018-05-10 15:44:56 +03001183 ret = populate_free_space_tree(trans, block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001184 if (ret)
1185 goto abort;
1186 node = rb_next(node);
1187 }
1188
1189 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
Omar Sandoval6675df32016-09-22 17:24:22 -07001190 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
Josef Bacikafcdd122016-09-02 15:40:02 -04001191 clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
Josef Bacik2f96e402021-01-15 16:26:17 -05001192 ret = btrfs_commit_transaction(trans);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001193
Josef Bacik2f96e402021-01-15 16:26:17 -05001194 /*
1195 * Now that we've committed the transaction any reading of our commit
1196 * root will be safe, so we can cache from the free space tree now.
1197 */
1198 clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
1199 return ret;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001200
1201abort:
Josef Bacikafcdd122016-09-02 15:40:02 -04001202 clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
Josef Bacik2f96e402021-01-15 16:26:17 -05001203 clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
Jeff Mahoney66642832016-06-10 18:19:25 -04001204 btrfs_abort_transaction(trans, ret);
Jeff Mahoney3a45bb22016-09-09 21:39:03 -04001205 btrfs_end_transaction(trans);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001206 return ret;
1207}
1208
1209static int clear_free_space_tree(struct btrfs_trans_handle *trans,
1210 struct btrfs_root *root)
1211{
1212 struct btrfs_path *path;
1213 struct btrfs_key key;
1214 int nr;
1215 int ret;
1216
1217 path = btrfs_alloc_path();
1218 if (!path)
1219 return -ENOMEM;
1220
Omar Sandovala5ed9182015-09-29 20:50:35 -07001221 key.objectid = 0;
1222 key.type = 0;
1223 key.offset = 0;
1224
1225 while (1) {
1226 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
1227 if (ret < 0)
1228 goto out;
1229
1230 nr = btrfs_header_nritems(path->nodes[0]);
1231 if (!nr)
1232 break;
1233
1234 path->slots[0] = 0;
1235 ret = btrfs_del_items(trans, root, path, 0, nr);
1236 if (ret)
1237 goto out;
1238
1239 btrfs_release_path(path);
1240 }
1241
1242 ret = 0;
1243out:
1244 btrfs_free_path(path);
1245 return ret;
1246}
1247
1248int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
1249{
1250 struct btrfs_trans_handle *trans;
1251 struct btrfs_root *tree_root = fs_info->tree_root;
Josef Bacikabed4aa2021-11-05 16:45:51 -04001252 struct btrfs_key key = {
1253 .objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
1254 .type = BTRFS_ROOT_ITEM_KEY,
1255 .offset = 0,
1256 };
1257 struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001258 int ret;
1259
1260 trans = btrfs_start_transaction(tree_root, 0);
1261 if (IS_ERR(trans))
1262 return PTR_ERR(trans);
1263
1264 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);
Omar Sandoval6675df32016-09-22 17:24:22 -07001265 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001266
1267 ret = clear_free_space_tree(trans, free_space_root);
1268 if (ret)
1269 goto abort;
1270
Lu Fengqiab9ce7d2018-08-01 11:32:27 +08001271 ret = btrfs_del_root(trans, &free_space_root->root_key);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001272 if (ret)
1273 goto abort;
1274
Josef Bacikabed4aa2021-11-05 16:45:51 -04001275 btrfs_global_root_delete(free_space_root);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001276 list_del(&free_space_root->dirty_list);
1277
1278 btrfs_tree_lock(free_space_root->node);
David Sterba6a884d7d2019-03-20 14:30:02 +01001279 btrfs_clean_tree_block(free_space_root->node);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001280 btrfs_tree_unlock(free_space_root->node);
Filipe Manana7a1636082021-12-13 08:45:12 +00001281 btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
1282 free_space_root->node, 0, 1);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001283
Josef Bacik00246522020-01-24 09:33:01 -05001284 btrfs_put_root(free_space_root);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001285
Sahil Kang0bef7102017-05-17 03:33:45 -07001286 return btrfs_commit_transaction(trans);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001287
1288abort:
Jeff Mahoney66642832016-06-10 18:19:25 -04001289 btrfs_abort_transaction(trans, ret);
Jeff Mahoney3a45bb22016-09-09 21:39:03 -04001290 btrfs_end_transaction(trans);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001291 return ret;
1292}
1293
1294static int __add_block_group_free_space(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +01001295 struct btrfs_block_group *block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001296 struct btrfs_path *path)
1297{
Omar Sandovala5ed9182015-09-29 20:50:35 -07001298 int ret;
1299
Omar Sandovala5ed9182015-09-29 20:50:35 -07001300 block_group->needs_free_space = 0;
1301
Nikolay Borisov66afee12018-05-10 15:44:44 +03001302 ret = add_new_free_space_info(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001303 if (ret)
1304 return ret;
1305
Nikolay Borisov2d5cffa2018-05-10 15:44:43 +03001306 return __add_to_free_space_tree(trans, block_group, path,
David Sterbab3470b52019-10-23 18:48:22 +02001307 block_group->start,
1308 block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001309}
1310
1311int add_block_group_free_space(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +01001312 struct btrfs_block_group *block_group)
Omar Sandovala5ed9182015-09-29 20:50:35 -07001313{
Nikolay Borisove4e07112018-05-10 15:44:41 +03001314 struct btrfs_fs_info *fs_info = trans->fs_info;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001315 struct btrfs_path *path = NULL;
1316 int ret = 0;
1317
1318 if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
1319 return 0;
1320
1321 mutex_lock(&block_group->free_space_lock);
1322 if (!block_group->needs_free_space)
1323 goto out;
1324
1325 path = btrfs_alloc_path();
1326 if (!path) {
1327 ret = -ENOMEM;
1328 goto out;
1329 }
1330
Nikolay Borisov9a7e0f92018-05-10 15:44:42 +03001331 ret = __add_block_group_free_space(trans, block_group, path);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001332
1333out:
1334 btrfs_free_path(path);
1335 mutex_unlock(&block_group->free_space_lock);
1336 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -04001337 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001338 return ret;
1339}
1340
1341int remove_block_group_free_space(struct btrfs_trans_handle *trans,
David Sterba32da53862019-10-29 19:20:18 +01001342 struct btrfs_block_group *block_group)
Omar Sandovala5ed9182015-09-29 20:50:35 -07001343{
Josef Bacik7939dd92021-11-05 16:45:49 -04001344 struct btrfs_root *root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001345 struct btrfs_path *path;
1346 struct btrfs_key key, found_key;
1347 struct extent_buffer *leaf;
1348 u64 start, end;
1349 int done = 0, nr;
1350 int ret;
1351
Nikolay Borisovf3f72772018-05-10 15:44:46 +03001352 if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
Omar Sandovala5ed9182015-09-29 20:50:35 -07001353 return 0;
1354
1355 if (block_group->needs_free_space) {
1356 /* We never added this block group to the free space tree. */
1357 return 0;
1358 }
1359
1360 path = btrfs_alloc_path();
1361 if (!path) {
1362 ret = -ENOMEM;
1363 goto out;
1364 }
1365
David Sterbab3470b52019-10-23 18:48:22 +02001366 start = block_group->start;
1367 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001368
1369 key.objectid = end - 1;
1370 key.type = (u8)-1;
1371 key.offset = (u64)-1;
1372
1373 while (!done) {
1374 ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
1375 if (ret)
1376 goto out;
1377
1378 leaf = path->nodes[0];
1379 nr = 0;
1380 path->slots[0]++;
1381 while (path->slots[0] > 0) {
1382 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
1383
1384 if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
David Sterbab3470b52019-10-23 18:48:22 +02001385 ASSERT(found_key.objectid == block_group->start);
1386 ASSERT(found_key.offset == block_group->length);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001387 done = 1;
1388 nr++;
1389 path->slots[0]--;
1390 break;
1391 } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY ||
1392 found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
1393 ASSERT(found_key.objectid >= start);
1394 ASSERT(found_key.objectid < end);
1395 ASSERT(found_key.objectid + found_key.offset <= end);
1396 nr++;
1397 path->slots[0]--;
1398 } else {
1399 ASSERT(0);
1400 }
1401 }
1402
1403 ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
1404 if (ret)
1405 goto out;
1406 btrfs_release_path(path);
1407 }
1408
1409 ret = 0;
1410out:
1411 btrfs_free_path(path);
1412 if (ret)
Jeff Mahoney66642832016-06-10 18:19:25 -04001413 btrfs_abort_transaction(trans, ret);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001414 return ret;
1415}
1416
1417static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
1418 struct btrfs_path *path,
1419 u32 expected_extent_count)
1420{
David Sterba32da53862019-10-29 19:20:18 +01001421 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001422 struct btrfs_fs_info *fs_info;
1423 struct btrfs_root *root;
1424 struct btrfs_key key;
1425 int prev_bit = 0, bit;
1426 /* Initialize to silence GCC. */
1427 u64 extent_start = 0;
1428 u64 end, offset;
1429 u64 total_found = 0;
1430 u32 extent_count = 0;
1431 int ret;
1432
1433 block_group = caching_ctl->block_group;
1434 fs_info = block_group->fs_info;
Josef Bacik7939dd92021-11-05 16:45:49 -04001435 root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001436
David Sterbab3470b52019-10-23 18:48:22 +02001437 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001438
1439 while (1) {
1440 ret = btrfs_next_item(root, path);
1441 if (ret < 0)
1442 goto out;
1443 if (ret)
1444 break;
1445
1446 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
1447
1448 if (key.type == BTRFS_FREE_SPACE_INFO_KEY)
1449 break;
1450
1451 ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
1452 ASSERT(key.objectid < end && key.objectid + key.offset <= end);
1453
1454 caching_ctl->progress = key.objectid;
1455
1456 offset = key.objectid;
1457 while (offset < key.objectid + key.offset) {
1458 bit = free_space_test_bit(block_group, path, offset);
1459 if (prev_bit == 0 && bit == 1) {
1460 extent_start = offset;
1461 } else if (prev_bit == 1 && bit == 0) {
1462 total_found += add_new_free_space(block_group,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001463 extent_start,
1464 offset);
1465 if (total_found > CACHING_CTL_WAKE_UP) {
1466 total_found = 0;
1467 wake_up(&caching_ctl->wait);
1468 }
1469 extent_count++;
1470 }
1471 prev_bit = bit;
Jeff Mahoney0b246af2016-06-22 18:54:23 -04001472 offset += fs_info->sectorsize;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001473 }
1474 }
1475 if (prev_bit == 1) {
Nikolay Borisov4457c1c2018-05-10 15:44:45 +03001476 total_found += add_new_free_space(block_group, extent_start,
1477 end);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001478 extent_count++;
1479 }
1480
1481 if (extent_count != expected_extent_count) {
Jeff Mahoney5d163e02016-09-20 10:05:00 -04001482 btrfs_err(fs_info,
1483 "incorrect extent count for %llu; counted %u, expected %u",
David Sterbab3470b52019-10-23 18:48:22 +02001484 block_group->start, extent_count,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001485 expected_extent_count);
1486 ASSERT(0);
1487 ret = -EIO;
1488 goto out;
1489 }
1490
1491 caching_ctl->progress = (u64)-1;
1492
1493 ret = 0;
1494out:
1495 return ret;
1496}
1497
1498static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
1499 struct btrfs_path *path,
1500 u32 expected_extent_count)
1501{
David Sterba32da53862019-10-29 19:20:18 +01001502 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001503 struct btrfs_fs_info *fs_info;
1504 struct btrfs_root *root;
1505 struct btrfs_key key;
1506 u64 end;
1507 u64 total_found = 0;
1508 u32 extent_count = 0;
1509 int ret;
1510
1511 block_group = caching_ctl->block_group;
1512 fs_info = block_group->fs_info;
Josef Bacik7939dd92021-11-05 16:45:49 -04001513 root = btrfs_free_space_root(block_group);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001514
David Sterbab3470b52019-10-23 18:48:22 +02001515 end = block_group->start + block_group->length;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001516
1517 while (1) {
1518 ret = btrfs_next_item(root, path);
1519 if (ret < 0)
1520 goto out;
1521 if (ret)
1522 break;
1523
1524 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
1525
1526 if (key.type == BTRFS_FREE_SPACE_INFO_KEY)
1527 break;
1528
1529 ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
1530 ASSERT(key.objectid < end && key.objectid + key.offset <= end);
1531
1532 caching_ctl->progress = key.objectid;
1533
Nikolay Borisov4457c1c2018-05-10 15:44:45 +03001534 total_found += add_new_free_space(block_group, key.objectid,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001535 key.objectid + key.offset);
1536 if (total_found > CACHING_CTL_WAKE_UP) {
1537 total_found = 0;
1538 wake_up(&caching_ctl->wait);
1539 }
1540 extent_count++;
1541 }
1542
1543 if (extent_count != expected_extent_count) {
Jeff Mahoney5d163e02016-09-20 10:05:00 -04001544 btrfs_err(fs_info,
1545 "incorrect extent count for %llu; counted %u, expected %u",
David Sterbab3470b52019-10-23 18:48:22 +02001546 block_group->start, extent_count,
Omar Sandovala5ed9182015-09-29 20:50:35 -07001547 expected_extent_count);
1548 ASSERT(0);
1549 ret = -EIO;
1550 goto out;
1551 }
1552
1553 caching_ctl->progress = (u64)-1;
1554
1555 ret = 0;
1556out:
1557 return ret;
1558}
1559
1560int load_free_space_tree(struct btrfs_caching_control *caching_ctl)
1561{
David Sterba32da53862019-10-29 19:20:18 +01001562 struct btrfs_block_group *block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001563 struct btrfs_free_space_info *info;
1564 struct btrfs_path *path;
1565 u32 extent_count, flags;
1566 int ret;
1567
1568 block_group = caching_ctl->block_group;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001569
1570 path = btrfs_alloc_path();
1571 if (!path)
1572 return -ENOMEM;
1573
1574 /*
1575 * Just like caching_thread() doesn't want to deadlock on the extent
1576 * tree, we don't want to deadlock on the free space tree.
1577 */
1578 path->skip_locking = 1;
1579 path->search_commit_root = 1;
Gu JinXiang7ce311d2018-01-11 16:12:18 +08001580 path->reada = READA_FORWARD;
Omar Sandovala5ed9182015-09-29 20:50:35 -07001581
David Sterba2ccf5452019-03-20 14:11:21 +01001582 info = search_free_space_info(NULL, block_group, path, 0);
Omar Sandovala5ed9182015-09-29 20:50:35 -07001583 if (IS_ERR(info)) {
1584 ret = PTR_ERR(info);
1585 goto out;
1586 }
1587 extent_count = btrfs_free_space_extent_count(path->nodes[0], info);
1588 flags = btrfs_free_space_flags(path->nodes[0], info);
1589
1590 /*
1591 * We left path pointing to the free space info item, so now
1592 * load_free_space_foo can just iterate through the free space tree from
1593 * there.
1594 */
1595 if (flags & BTRFS_FREE_SPACE_USING_BITMAPS)
1596 ret = load_free_space_bitmaps(caching_ctl, path, extent_count);
1597 else
1598 ret = load_free_space_extents(caching_ctl, path, extent_count);
1599
1600out:
1601 btrfs_free_path(path);
1602 return ret;
1603}