From: Qu Wenruo Date: Thu, 19 Oct 2017 05:41:33 +0000 (+0800) Subject: btrfs-progs: mkfs: avoid BUG_ON for chunk allocation when ENOSPC happens X-Git-Tag: upstream/4.16.1~306 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=66e485873cf21e03cee5fe59b5dce807d2ac53ea;p=platform%2Fupstream%2Fbtrfs-progs.git btrfs-progs: mkfs: avoid BUG_ON for chunk allocation when ENOSPC happens When passing directory larger than block device using --rootdir parameter, we get the following backtrace: ------ extent-tree.c:2693: btrfs_reserve_extent: BUG_ON `ret` triggered, value -28 ./mkfs.btrfs(+0x1a05d)[0x557939e6b05d] ./mkfs.btrfs(btrfs_reserve_extent+0xb5a)[0x557939e710c8] ./mkfs.btrfs(+0xb0b6)[0x557939e5c0b6] ./mkfs.btrfs(main+0x15d5)[0x557939e5de04] /usr/lib/libc.so.6(__libc_start_main+0xea)[0x7f83b101af6a] ./mkfs.btrfs(_start+0x2a)[0x557939e5af5a] ------ Nothing special, just BUG_ON() abusing from ancient code. Fix them by using correct return. Signed-off-by: Qu Wenruo Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- diff --git a/extent-tree.c b/extent-tree.c index 525a237..055582c 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -2690,7 +2690,8 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, search_start, search_end, hint_byte, ins, trans->alloc_exclude_start, trans->alloc_exclude_nr, data); - BUG_ON(ret); + if (ret < 0) + return ret; clear_extent_dirty(&info->free_space_cache, ins->objectid, ins->objectid + ins->offset - 1); return ret; diff --git a/volumes.c b/volumes.c index 2fde476..e3654a4 100644 --- a/volumes.c +++ b/volumes.c @@ -1046,11 +1046,13 @@ again: info->chunk_root->root_key.objectid, BTRFS_FIRST_CHUNK_TREE_OBJECTID, key.offset, calc_size, &dev_offset, 0); - BUG_ON(ret); + if (ret < 0) + goto out_chunk_map; device->bytes_used += calc_size; ret = btrfs_update_device(trans, device); - BUG_ON(ret); + if (ret < 0) + goto out_chunk_map; map->stripes[index].dev = device; map->stripes[index].physical = dev_offset; @@ -1089,16 +1091,24 @@ again: map->ce.size = *num_bytes; ret = insert_cache_extent(&info->mapping_tree.cache_tree, &map->ce); - BUG_ON(ret); + if (ret < 0) + goto out_chunk_map; if (type & BTRFS_BLOCK_GROUP_SYSTEM) { ret = btrfs_add_system_chunk(info, &key, chunk, btrfs_chunk_item_size(num_stripes)); - BUG_ON(ret); + if (ret < 0) + goto out_chunk; } kfree(chunk); return ret; + +out_chunk_map: + kfree(map); +out_chunk: + kfree(chunk); + return ret; } /*