Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:GA
btrfsprogs.356
0067-btrfs-progs-add-options-to-tune-units-for-...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0067-btrfs-progs-add-options-to-tune-units-for-fi-df-outp.patch of Package btrfsprogs.356
From 0b90a24e11484548801a30a6ad4bbafc0b3d682f Mon Sep 17 00:00:00 2001 From: David Sterba <dsterba@suse.cz> Date: Sat, 30 Aug 2014 15:27:00 -0300 Subject: [PATCH 067/303] btrfs-progs: add options to tune units for fi df output The size unit format is a longstanding annoyance. This patch is based on the work of Nils and Alexandre and enhances the options. It's possible to select raw bytes, SI-based or IEC-based compact units (human frientdly) or a fixed base from kilobytes to terabytes. The default is compact human readable IEC-based, no change to current version. CC: Nils Steinger <nst@voidptr.de> CC: Alexandre Oliva <oliva@gnu.org> Reviewed-by: Hugo Mills <hugo@carfax.org.uk> Signed-off-by: David Sterba <dsterba@suse.cz> --- Documentation/btrfs-filesystem.txt | 25 +++++++++++- cmds-filesystem.c | 79 +++++++++++++++++++++++++++++++++----- utils.c | 52 +++++++++++++++++++------ utils.h | 30 +++++++++++---- 4 files changed, 155 insertions(+), 31 deletions(-) diff --git a/Documentation/btrfs-filesystem.txt b/Documentation/btrfs-filesystem.txt index b0d5820eb2ea..6e63d2c9c2ae 100644 --- a/Documentation/btrfs-filesystem.txt +++ b/Documentation/btrfs-filesystem.txt @@ -17,8 +17,31 @@ resizing, defragment. SUBCOMMAND ---------- -*df* <path> [<path>...]:: +*df* [options] <path>:: Show space usage information for a mount point. ++ +`Options` ++ +-b|--raw:::: +raw numbers in bytes, without the 'B' suffix +-h:::: +print human friendly numbers, base 1024, this is the default +-H:::: +print human friendly numbers, base 1000 +--iec:::: +select the 1024 base for the following options, according to the IEC standard +--si:::: +select the 1000 base for the following options, according to the SI standard +-k|--kbytes:::: +show sizes in KiB, or kB with --si +-m|--mbytes:::: +show sizes in MiB, or mB with --si +-g|--gbytes:::: +show sizes in GiB, or gB with --si +-t|--tbytes:::: +show sizes in TiB, or tB with --si + +If conflicting options are passed, the last one takes precedence. *show* [--mounted|--all-devices|<path>|<uuid>|<device>|<label>]:: Show the btrfs filesystem with some additional info. diff --git a/cmds-filesystem.c b/cmds-filesystem.c index f54391456233..bb5881edef2d 100644 --- a/cmds-filesystem.c +++ b/cmds-filesystem.c @@ -113,9 +113,18 @@ static const char * const filesystem_cmd_group_usage[] = { }; static const char * const cmd_df_usage[] = { - "btrfs filesystem df <path>", - "Show space usage information for a mount point", - NULL + "btrfs filesystem df [options] <path>", + "Show space usage information for a mount point", + "-b|--raw raw numbers in bytes", + "-h human friendly numbers, base 1024 (default)", + "-H human friendly numbers, base 1000", + "--iec use 1024 as a base (KiB, MiB, GiB, TiB)", + "--si use 1000 as a base (kB, mB, gB, tB)", + "-k|--kbytes show sizes in KiB, or kB with --si", + "-m|--mbytes show sizes in MiB, or mB with --si", + "-g|--gbytes show sizes in GiB, or gB with --si", + "-t|--tbytes show sizes in TiB, or tB with --si", + NULL }; static char *group_type_str(u64 flag) @@ -209,7 +218,7 @@ static int get_df(int fd, struct btrfs_ioctl_space_args **sargs_ret) return 0; } -static void print_df(struct btrfs_ioctl_space_args *sargs) +static void print_df(struct btrfs_ioctl_space_args *sargs, unsigned unit_mode) { u64 i; struct btrfs_ioctl_space_info *sp = sargs->spaces; @@ -218,8 +227,8 @@ static void print_df(struct btrfs_ioctl_space_args *sargs) printf("%s, %s: total=%s, used=%s\n", group_type_str(sp->flags), group_profile_str(sp->flags), - pretty_size(sp->total_bytes), - pretty_size(sp->used_bytes)); + pretty_size_mode(sp->total_bytes, unit_mode), + pretty_size_mode(sp->used_bytes, unit_mode)); } } @@ -229,12 +238,62 @@ static int cmd_df(int argc, char **argv) int ret; int fd; char *path; - DIR *dirstream = NULL; + DIR *dirstream = NULL; + unsigned unit_mode = UNITS_DEFAULT; - if (check_argc_exact(argc, 2)) + optind = 1; + while (1) { + int long_index; + static const struct option long_options[] = { + { "raw", no_argument, NULL, 'b'}, + { "kbytes", no_argument, NULL, 'k'}, + { "mbytes", no_argument, NULL, 'm'}, + { "gbytes", no_argument, NULL, 'g'}, + { "tbytes", no_argument, NULL, 't'}, + { "si", no_argument, NULL, 256}, + { "iec", no_argument, NULL, 257}, + }; + int c = getopt_long(argc, argv, "bhHkmgt", long_options, + &long_index); + if (c < 0) + break; + switch (c) { + case 'b': + unit_mode = UNITS_RAW; + break; + case 'k': + units_set_base(&unit_mode, UNITS_KBYTES); + break; + case 'm': + units_set_base(&unit_mode, UNITS_MBYTES); + break; + case 'g': + units_set_base(&unit_mode, UNITS_GBYTES); + break; + case 't': + units_set_base(&unit_mode, UNITS_TBYTES); + break; + case 'h': + unit_mode = UNITS_HUMAN_BINARY; + break; + case 'H': + unit_mode = UNITS_HUMAN_DECIMAL; + break; + case 256: + units_set_mode(&unit_mode, UNITS_DECIMAL); + break; + case 257: + units_set_mode(&unit_mode, UNITS_BINARY); + break; + default: + usage(cmd_df_usage); + } + } + + if (check_argc_max(argc, optind + 1)) usage(cmd_df_usage); - path = argv[1]; + path = argv[optind]; fd = open_file_or_dir(path, &dirstream); if (fd < 0) { @@ -244,7 +303,7 @@ static int cmd_df(int argc, char **argv) ret = get_df(fd, &sargs); if (ret == 0) { - print_df(sargs); + print_df(sargs, unit_mode); free(sargs); } else { fprintf(stderr, "ERROR: get_df failed %s\n", strerror(-ret)); diff --git a/utils.c b/utils.c index bdb73999d5da..e86292acd4eb 100644 --- a/utils.c +++ b/utils.c @@ -1297,35 +1297,38 @@ out: static const char* unit_suffix_binary[] = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}; static const char* unit_suffix_decimal[] = - { "B", "KB", "MB", "GB", "TB", "PB", "EB"}; + { "B", "kB", "mB", "gB", "tB", "pB", "eB"}; -int pretty_size_snprintf(u64 size, char *str, size_t str_size, int unit_mode) +int pretty_size_snprintf(u64 size, char *str, size_t str_size, unsigned unit_mode) { int num_divs; float fraction; - int base = 0; + u64 base = 0; + int mult = 0; const char** suffix = NULL; u64 last_size; if (str_size == 0) return 0; - if (unit_mode == UNITS_RAW) { + if ((unit_mode & ~UNITS_MODE_MASK) == UNITS_RAW) { snprintf(str, str_size, "%llu", size); return 0; } - if (unit_mode == UNITS_BINARY) { + if ((unit_mode & ~UNITS_MODE_MASK) == UNITS_BINARY) { base = 1024; + mult = 1024; suffix = unit_suffix_binary; - } else if (unit_mode == UNITS_DECIMAL) { + } else if ((unit_mode & ~UNITS_MODE_MASK) == UNITS_DECIMAL) { base = 1000; + mult = 1000; suffix = unit_suffix_decimal; } /* Unknown mode */ if (!base) { - fprintf(stderr, "INTERNAL ERROR: unknown unit base, mode %d", + fprintf(stderr, "INTERNAL ERROR: unknown unit base, mode %d\n", unit_mode); assert(0); return -1; @@ -1333,11 +1336,22 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_size, int unit_mode) num_divs = 0; last_size = size; - - while (size >= base) { - last_size = size; - size /= base; - num_divs++; + switch (unit_mode & UNITS_MODE_MASK) { + case UNITS_TBYTES: base *= mult; num_divs++; + case UNITS_GBYTES: base *= mult; num_divs++; + case UNITS_MBYTES: base *= mult; num_divs++; + case UNITS_KBYTES: num_divs++; + break; + case UNITS_BYTES: + base = 1; + num_divs = 0; + break; + default: + while (size >= mult) { + last_size = size; + size /= mult; + num_divs++; + } } if (num_divs >= ARRAY_SIZE(unit_suffix_binary)) { @@ -2377,3 +2391,17 @@ int test_isdir(const char *path) return S_ISDIR(st.st_mode); } + +void units_set_mode(unsigned *units, unsigned mode) +{ + unsigned base = *units & UNITS_MODE_MASK; + + *units = base | mode; +} + +void units_set_base(unsigned *units, unsigned base) +{ + unsigned mode = *units & ~UNITS_MODE_MASK; + + *units = base | mode; +} diff --git a/utils.h b/utils.h index e2b1ba80b9cf..aed03f23fc55 100644 --- a/utils.h +++ b/utils.h @@ -48,12 +48,26 @@ void fixup_argv0(char **argv, const char *token); void set_argv0(char **argv); /* - * Output mode of byte units + * Output modes of size */ -#define UNITS_RAW (1) -#define UNITS_BINARY (2) -#define UNITS_DECIMAL (3) -#define UNITS_HUMAN UNITS_BINARY +#define UNITS_RESERVED (0) +#define UNITS_BYTES (1) +#define UNITS_KBYTES (2) +#define UNITS_MBYTES (3) +#define UNITS_GBYTES (4) +#define UNITS_TBYTES (5) +#define UNITS_RAW (1U << UNITS_MODE_SHIFT) +#define UNITS_BINARY (2U << UNITS_MODE_SHIFT) +#define UNITS_DECIMAL (3U << UNITS_MODE_SHIFT) +#define UNITS_MODE_MASK ((1U << UNITS_MODE_SHIFT) - 1) +#define UNITS_MODE_SHIFT (8) +#define UNITS_HUMAN_BINARY (UNITS_BINARY) +#define UNITS_HUMAN_DECIMAL (UNITS_DECIMAL) +#define UNITS_HUMAN (UNITS_HUMAN_BINARY) +#define UNITS_DEFAULT (UNITS_HUMAN) + +void units_set_mode(unsigned *units, unsigned mode); +void units_set_base(unsigned *units, unsigned base); int make_btrfs(int fd, const char *device, const char *label, char *fs_uuid, u64 blocks[6], u64 num_bytes, u32 nodesize, @@ -76,12 +90,12 @@ int check_mounted_where(int fd, const char *file, char *where, int size, int btrfs_device_already_in_root(struct btrfs_root *root, int fd, int super_offset); -int pretty_size_snprintf(u64 size, char *str, size_t str_bytes, int unit_mode); -#define pretty_size(size) pretty_size_mode(size, UNITS_BINARY) +int pretty_size_snprintf(u64 size, char *str, size_t str_bytes, unsigned unit_mode); +#define pretty_size(size) pretty_size_mode(size, UNITS_DEFAULT) #define pretty_size_mode(size, mode) \ ({ \ static __thread char _str[32]; \ - (void)pretty_size_snprintf((size), _str, sizeof(_str), mode); \ + (void)pretty_size_snprintf((size), _str, sizeof(_str), (mode)); \ _str; \ }) -- 2.1.3
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