Skip to content

Commit 23e7223

Browse files
fdmananagregkh
authored andcommitted
btrfs: remove BUG_ON()'s in add_new_free_space()
commit d8ccbd2 upstream. At add_new_free_space() we have these BUG_ON()'s that are there to deal with any failure to add free space to the in memory free space cache. Such failures are mostly -ENOMEM that should be very rare. However there's no need to have these BUG_ON()'s, we can just return any error to the caller and all callers and their upper call chain are already dealing with errors. So just make add_new_free_space() return any errors, while removing the BUG_ON()'s, and returning the total amount of added free space to an optional u64 pointer argument. Reported-by: [email protected] Link: https://lore.kernel.org/linux-btrfs/[email protected]/ Signed-off-by: Filipe Manana <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 56c0d76 commit 23e7223

File tree

3 files changed

+53
-26
lines changed

3 files changed

+53
-26
lines changed

fs/btrfs/block-group.c

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -494,12 +494,16 @@ static void fragment_free_space(struct btrfs_block_group *block_group)
494494
* used yet since their free space will be released as soon as the transaction
495495
* commits.
496496
*/
497-
u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end)
497+
int add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end,
498+
u64 *total_added_ret)
498499
{
499500
struct btrfs_fs_info *info = block_group->fs_info;
500-
u64 extent_start, extent_end, size, total_added = 0;
501+
u64 extent_start, extent_end, size;
501502
int ret;
502503

504+
if (total_added_ret)
505+
*total_added_ret = 0;
506+
503507
while (start < end) {
504508
ret = find_first_extent_bit(&info->excluded_extents, start,
505509
&extent_start, &extent_end,
@@ -512,10 +516,12 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
512516
start = extent_end + 1;
513517
} else if (extent_start > start && extent_start < end) {
514518
size = extent_start - start;
515-
total_added += size;
516519
ret = btrfs_add_free_space_async_trimmed(block_group,
517520
start, size);
518-
BUG_ON(ret); /* -ENOMEM or logic error */
521+
if (ret)
522+
return ret;
523+
if (total_added_ret)
524+
*total_added_ret += size;
519525
start = extent_end + 1;
520526
} else {
521527
break;
@@ -524,13 +530,15 @@ u64 add_new_free_space(struct btrfs_block_group *block_group, u64 start, u64 end
524530

525531
if (start < end) {
526532
size = end - start;
527-
total_added += size;
528533
ret = btrfs_add_free_space_async_trimmed(block_group, start,
529534
size);
530-
BUG_ON(ret); /* -ENOMEM or logic error */
535+
if (ret)
536+
return ret;
537+
if (total_added_ret)
538+
*total_added_ret += size;
531539
}
532540

533-
return total_added;
541+
return 0;
534542
}
535543

536544
static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
@@ -637,8 +645,13 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
637645

638646
if (key.type == BTRFS_EXTENT_ITEM_KEY ||
639647
key.type == BTRFS_METADATA_ITEM_KEY) {
640-
total_found += add_new_free_space(block_group, last,
641-
key.objectid);
648+
u64 space_added;
649+
650+
ret = add_new_free_space(block_group, last, key.objectid,
651+
&space_added);
652+
if (ret)
653+
goto out;
654+
total_found += space_added;
642655
if (key.type == BTRFS_METADATA_ITEM_KEY)
643656
last = key.objectid +
644657
fs_info->nodesize;
@@ -653,11 +666,10 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
653666
}
654667
path->slots[0]++;
655668
}
656-
ret = 0;
657-
658-
total_found += add_new_free_space(block_group, last,
659-
block_group->start + block_group->length);
660669

670+
ret = add_new_free_space(block_group, last,
671+
block_group->start + block_group->length,
672+
NULL);
661673
out:
662674
btrfs_free_path(path);
663675
return ret;
@@ -2101,9 +2113,11 @@ static int read_one_block_group(struct btrfs_fs_info *info,
21012113
btrfs_free_excluded_extents(cache);
21022114
} else if (cache->used == 0) {
21032115
cache->cached = BTRFS_CACHE_FINISHED;
2104-
add_new_free_space(cache, cache->start,
2105-
cache->start + cache->length);
2116+
ret = add_new_free_space(cache, cache->start,
2117+
cache->start + cache->length, NULL);
21062118
btrfs_free_excluded_extents(cache);
2119+
if (ret)
2120+
goto error;
21072121
}
21082122

21092123
ret = btrfs_add_block_group_cache(info, cache);
@@ -2529,9 +2543,12 @@ struct btrfs_block_group *btrfs_make_block_group(struct btrfs_trans_handle *tran
25292543
return ERR_PTR(ret);
25302544
}
25312545

2532-
add_new_free_space(cache, chunk_offset, chunk_offset + size);
2533-
2546+
ret = add_new_free_space(cache, chunk_offset, chunk_offset + size, NULL);
25342547
btrfs_free_excluded_extents(cache);
2548+
if (ret) {
2549+
btrfs_put_block_group(cache);
2550+
return ERR_PTR(ret);
2551+
}
25352552

25362553
/*
25372554
* Ensure the corresponding space_info object is created and

fs/btrfs/block-group.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,8 @@ int btrfs_cache_block_group(struct btrfs_block_group *cache, bool wait);
284284
void btrfs_put_caching_control(struct btrfs_caching_control *ctl);
285285
struct btrfs_caching_control *btrfs_get_caching_control(
286286
struct btrfs_block_group *cache);
287-
u64 add_new_free_space(struct btrfs_block_group *block_group,
288-
u64 start, u64 end);
287+
int add_new_free_space(struct btrfs_block_group *block_group,
288+
u64 start, u64 end, u64 *total_added_ret);
289289
struct btrfs_trans_handle *btrfs_start_trans_remove_block_group(
290290
struct btrfs_fs_info *fs_info,
291291
const u64 chunk_offset);

fs/btrfs/free-space-tree.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,9 +1510,13 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
15101510
if (prev_bit == 0 && bit == 1) {
15111511
extent_start = offset;
15121512
} else if (prev_bit == 1 && bit == 0) {
1513-
total_found += add_new_free_space(block_group,
1514-
extent_start,
1515-
offset);
1513+
u64 space_added;
1514+
1515+
ret = add_new_free_space(block_group, extent_start,
1516+
offset, &space_added);
1517+
if (ret)
1518+
goto out;
1519+
total_found += space_added;
15161520
if (total_found > CACHING_CTL_WAKE_UP) {
15171521
total_found = 0;
15181522
wake_up(&caching_ctl->wait);
@@ -1524,8 +1528,9 @@ static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
15241528
}
15251529
}
15261530
if (prev_bit == 1) {
1527-
total_found += add_new_free_space(block_group, extent_start,
1528-
end);
1531+
ret = add_new_free_space(block_group, extent_start, end, NULL);
1532+
if (ret)
1533+
goto out;
15291534
extent_count++;
15301535
}
15311536

@@ -1564,6 +1569,8 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
15641569
end = block_group->start + block_group->length;
15651570

15661571
while (1) {
1572+
u64 space_added;
1573+
15671574
ret = btrfs_next_item(root, path);
15681575
if (ret < 0)
15691576
goto out;
@@ -1578,8 +1585,11 @@ static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
15781585
ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
15791586
ASSERT(key.objectid < end && key.objectid + key.offset <= end);
15801587

1581-
total_found += add_new_free_space(block_group, key.objectid,
1582-
key.objectid + key.offset);
1588+
ret = add_new_free_space(block_group, key.objectid,
1589+
key.objectid + key.offset, &space_added);
1590+
if (ret)
1591+
goto out;
1592+
total_found += space_added;
15831593
if (total_found > CACHING_CTL_WAKE_UP) {
15841594
total_found = 0;
15851595
wake_up(&caching_ctl->wait);

0 commit comments

Comments
 (0)