Message ID | 20200924135502.19560-1-marcos@mpdesouza.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] btrfs-progs: convert: Show more info when reserve_space fails | expand |
On Thu, Sep 24, 2020 at 10:55:02AM -0300, Marcos Paulo de Souza wrote: > From: Marcos Paulo de Souza <mpdesouza@suse.com> > > btrfs-convert currently can't handle more fragmented block groups when > converting ext4 because the minimum size of a data chunk is 32Mb. > > When converting an ext4 fs with more fragmented block group with the disk > almost full, we can end up hitting a ENOSPC problem [1] since smaller > block groups (10Mb for example) end up being extended to 32Mb, leaving > the free space tree smaller when converting it to btrfs. > > This patch adds error messages telling which needed bytes couldn't be > allocated from the free space tree and shows the largest portion available: > > create btrfs filesystem: > blocksize: 4096 > nodesize: 16384 > features: extref, skinny-metadata (default) > checksum: crc32c > free space report: > total: 1073741824 > free: 39124992 (3.64%) > ERROR: failed to reserve 33554432 bytes for metadata chunk, largest available: 33488896 bytes > ERROR: unable to create initial ctree: No space left on device > > Link: https://github.com/kdave/btrfs-progs/issues/251 > > Reviewed-by: Neal Gompa <ngompa13@gmail.com> > Reviewed-by: Qu Wenruo <wqu@suse.com> > Signed-off-by: Marcos Paulo de Souza <mpdesouza@suse.com> > --- > Changes from v1: > * Added reviewed-by tag from Neal and Qu > * Add largest free space portion available to the error message (Qu) Thanks, added to devel.
diff --git a/convert/common.c b/convert/common.c index 048629df..e636896b 100644 --- a/convert/common.c +++ b/convert/common.c @@ -774,6 +774,20 @@ out: return ret; } +static u64 largest_free_space(struct cache_tree *free_space) +{ + struct cache_extent *cache; + u64 largest_free_space = 0; + + for (cache = first_cache_extent(free_space); cache; + cache = next_cache_extent(cache)) { + if (cache->size > largest_free_space) + largest_free_space = cache->size; + } + + return largest_free_space; +} + /* * Improved version of make_btrfs(). * @@ -812,8 +826,12 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg, */ ret = reserve_free_space(free_space, BTRFS_STRIPE_LEN, &cfg->super_bytenr); - if (ret < 0) + if (ret < 0) { + error("failed to reserve %d bytes for temporary superblock, largest available: %llu bytes", + BTRFS_STRIPE_LEN, + largest_free_space(free_space)); goto out; + } /* * Then reserve system chunk space @@ -823,12 +841,20 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg, */ ret = reserve_free_space(free_space, BTRFS_MKFS_SYSTEM_GROUP_SIZE, &sys_chunk_start); - if (ret < 0) + if (ret < 0) { + error("failed to reserve %d bytes for system chunk, largest available: %llu bytes", + BTRFS_MKFS_SYSTEM_GROUP_SIZE, + largest_free_space(free_space)); goto out; + } ret = reserve_free_space(free_space, BTRFS_CONVERT_META_GROUP_SIZE, &meta_chunk_start); - if (ret < 0) + if (ret < 0) { + error("failed to reserve %d bytes for metadata chunk, largest available: %llu bytes", + BTRFS_CONVERT_META_GROUP_SIZE, + largest_free_space(free_space)); goto out; + } /* * Allocated meta/sys chunks will be mapped 1:1 with device offset.