Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:GA
btrfsprogs
newdf-rework-calculations.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File newdf-rework-calculations.patch of Package btrfsprogs
From: David Sterba <dsterba@suse.cz> Date: Thu, 26 Jun 2014 15:42:24 +0200 Subject: [PATCH] newdf rework calculations Fix negative numbers in estimated free space. Signed-off-by: David Sterba <dsterba@suse.cz> --- cmds-fi-disk_usage.c | 150 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 102 insertions(+), 48 deletions(-) diff --git a/cmds-fi-disk_usage.c b/cmds-fi-disk_usage.c index b30bd308df55..25d9d0061407 100644 --- a/cmds-fi-disk_usage.c +++ b/cmds-fi-disk_usage.c @@ -306,6 +306,7 @@ static void get_raid56_used(int fd, struct chunk_info *chunks, int chunkcount, } } +#define MIN_UNALOCATED_THRESH (16 * 1024 * 1024) static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo, int chunkcount, struct device_info *devinfo, int devcount, char *path, int mode) @@ -313,16 +314,34 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo, struct btrfs_ioctl_space_args *sargs = 0; int i; int ret = 0; - int e, width; - u64 total_disk; /* filesystem size == sum of - device sizes */ - u64 total_chunks; /* sum of chunks sizes on disk(s) */ - u64 total_used; /* logical space used */ - u64 total_free; /* logical space un-used */ - double K; - u64 raid5_used, raid6_used; - u64 global_reserve; - u64 global_reserve_used; + int width = 10; /* default 10 for human units */ + /* + * r_* prefix is for raw data + * l_* is for logical + */ + u64 r_total_size = 0; /* filesystem size, sum of device sizes */ + u64 r_total_chunks = 0; /* sum of chunks sizes on disk(s) */ + u64 r_total_used = 0; + u64 r_total_unused = 0; + u64 r_data_used = 0; + u64 r_data_chunks = 0; + u64 l_data_chunks = 0; + u64 r_metadata_used = 0; + u64 r_metadata_chunks = 0; + u64 l_metadata_chunks = 0; + u64 r_system_used = 0; + u64 r_system_chunks = 0; + double data_ratio; + double metadata_ratio; + /* logical */ + u64 raid5_used = 0; + u64 raid6_used = 0; + u64 l_global_reserve = 0; + u64 l_global_reserve_used = 0; + /* logical */ + u64 free_estimated = 0; + u64 free_min = 0; + int max_data_ratio = 1; sargs = load_space_info(fd, path); if (!sargs) { @@ -330,27 +349,19 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo, goto exit; } - total_disk = disk_size(path); - e = errno; - if (total_disk == 0) { + r_total_size = disk_size(path); + if (r_total_size == 0) { fprintf(stderr, "ERROR: couldn't get space info on '%s' - %s\n", - path, strerror(e)); + path, strerror(errno)); ret = 1; goto exit; } get_raid56_used(fd, chunkinfo, chunkcount, &raid5_used, &raid6_used); - total_chunks = 0; - total_used = 0; - total_free = 0; - global_reserve = 0; - global_reserve_used = 0; - for (i = 0; i < sargs->total_spaces; i++) { - float ratio = 1; - u64 allocated; + int ratio = 1; u64 flags = sargs->spaces[i].flags; /* @@ -372,52 +383,95 @@ static int print_filesystem_usage_overall(int fd, struct chunk_info *chunkinfo, else ratio = 1; - if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV) { - global_reserve = sargs->spaces[i].total_bytes; - global_reserve_used = sargs->spaces[i].used_bytes; + if (!ratio) { + printf("WARNING: RAID56 detected, not implemented\n"); } - allocated = sargs->spaces[i].total_bytes * ratio; + if (ratio > max_data_ratio) + max_data_ratio = ratio; - total_chunks += allocated; - total_used += sargs->spaces[i].used_bytes; - total_free += (sargs->spaces[i].total_bytes - - sargs->spaces[i].used_bytes); + if (flags & BTRFS_SPACE_INFO_GLOBAL_RSV) { + l_global_reserve = sargs->spaces[i].total_bytes; + l_global_reserve_used = sargs->spaces[i].used_bytes; + } + if ((flags & (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA)) + == (BTRFS_BLOCK_GROUP_DATA | BTRFS_BLOCK_GROUP_METADATA)) { + printf("WARNING: MIXED blockgroups not handled\n"); + } + if (flags & BTRFS_BLOCK_GROUP_DATA) { + r_data_used += sargs->spaces[i].used_bytes * ratio; + r_data_chunks += sargs->spaces[i].total_bytes * ratio; + l_data_chunks += sargs->spaces[i].total_bytes; + } + if (flags & BTRFS_BLOCK_GROUP_METADATA) { + r_metadata_used += sargs->spaces[i].used_bytes * ratio; + r_metadata_chunks += sargs->spaces[i].total_bytes * ratio; + l_metadata_chunks += sargs->spaces[i].total_bytes; + } + if (flags & BTRFS_BLOCK_GROUP_SYSTEM) { + r_system_used += sargs->spaces[i].used_bytes * ratio; + r_system_chunks += sargs->spaces[i].total_bytes * ratio; + } } + r_total_chunks = r_data_chunks + r_metadata_chunks + r_system_chunks; + r_total_used = r_data_used + r_metadata_used + r_system_used; + r_total_unused = r_total_size - r_total_chunks; + + /* Raw / Logical = raid factor, >= 1 */ + data_ratio = (double)r_data_chunks / l_data_chunks; + metadata_ratio = (double)r_metadata_chunks / l_metadata_chunks; + +#if 0 /* add the raid5/6 allocated space */ total_chunks += raid5_used + raid6_used; +#endif - K = ((double)total_used + (double)total_free) / (double)total_chunks; + /* + * We're able to fill at least DATA for the unused space + * + * With mixed raid levels, this gives a rough estimate but more + * accurate than just counting the logical free space + * (l_data_chunks - l_data_used) + * + * In non-mixed case there's no difference. + */ + free_estimated = (r_data_chunks - r_data_used) / data_ratio; + free_min = free_estimated; + + /* Chop unallocatable space */ + /* FIXME: must be applied per device */ + if (r_total_unused >= MIN_UNALOCATED_THRESH) { + free_estimated += r_total_unused / data_ratio; + /* Match the calculation of 'df', use the highest raid ratio */ + free_min += r_total_unused / max_data_ratio; + } - if (mode == UNITS_HUMAN) - width = 10; - else + if (mode != UNITS_HUMAN) width = 18; printf("Overall:\n"); printf(" Device size:\t\t%*s\n", width, - pretty_size_mode(total_disk, mode)); + pretty_size_mode(r_total_size, mode)); printf(" Device allocated:\t\t%*s\n", width, - pretty_size_mode(total_chunks, mode)); + pretty_size_mode(r_total_chunks, mode)); printf(" Device unallocated:\t\t%*s\n", width, - pretty_size_mode(total_disk - total_chunks, mode)); + pretty_size_mode(r_total_unused, mode)); printf(" Used:\t\t\t%*s\n", width, - pretty_size_mode(total_used, mode)); - printf(" Free (Estimated):\t\t%*s\t(", + pretty_size_mode(r_total_used, mode)); + printf(" Free (estimated):\t\t%*s\t(", width, - pretty_size_mode((u64)(K * total_disk - total_used), mode)); - printf("Max: %s, ", - pretty_size_mode(total_disk - total_chunks + total_free, mode)); - printf("min: %s)\n", - pretty_size_mode((total_disk-total_chunks) / 2 + total_free, mode)); - printf(" Data to device ratio:\t%*.0f %%\n", - width - 2, K * 100); + pretty_size_mode(free_estimated, mode)); + printf("min: %s)\n", pretty_size_mode(free_min, mode)); + printf(" Data ratio:\t\t\t%*.2f\n", + width, data_ratio); + printf(" Metadata ratio:\t\t%*.2f\n", + width, metadata_ratio); printf(" Global reserve:\t\t%*s\t(used: %s)\n", width, - pretty_size_mode(global_reserve, mode), - pretty_size_mode(global_reserve_used, mode)); + pretty_size_mode(l_global_reserve, mode), + pretty_size_mode(l_global_reserve_used, mode)); exit: -- 2.1.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor