@@ -113,8 +113,13 @@ static const char * const filesystem_cmd_group_usage[] = {
};
static const char * const cmd_df_usage[] = {
- "btrfs filesystem df <path>",
+ "btrfs filesystem df [options] <path>",
"Show space usage information for a mount point",
+ "",
+ "-b display all values in bytes",
+ "-k display all values in kibibytes",
+ "-m display all values in mebibytes",
+ "-g display all values in gibibytes",
NULL
};
@@ -204,7 +209,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, int output_unit)
{
u64 i;
struct btrfs_ioctl_space_info *sp = sargs->spaces;
@@ -213,8 +218,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));
+ fixed_unit_size(sp->total_bytes, output_unit),
+ fixed_unit_size(sp->used_bytes, output_unit));
}
}
@@ -223,13 +228,56 @@ static int cmd_df(int argc, char **argv)
struct btrfs_ioctl_space_args *sargs = NULL;
int ret;
int fd;
+ int output_unit = 0;
+ int multiple_options_specified = 0;
char *path;
DIR *dirstream = NULL;
- if (check_argc_exact(argc, 2))
+ optind = 1;
+ while(1) {
+ int c = getopt(argc, argv, "bkmg");
+ if (c < 0)
+ break;
+
+ switch(c) {
+ case 'b':
+ if (output_unit > 0)
+ multiple_options_specified = 1;
+
+ output_unit = 1;
+ break;
+ case 'k':
+ if (output_unit > 0)
+ multiple_options_specified = 1;
+
+ output_unit = 1024;
+ break;
+ case 'm':
+ if (output_unit > 0)
+ multiple_options_specified = 1;
+
+ output_unit = 1024 * 1024;
+ break;
+ case 'g':
+ if (output_unit > 0)
+ multiple_options_specified = 1;
+
+ output_unit = 1024 * 1024 * 1024;
+ break;
+ default:
+ usage(cmd_df_usage);
+ }
+ }
+
+ if (multiple_options_specified) {
+ fprintf(stderr, "Please only specify one the unit selection parameters -b/k/m/g\n.");
+ return EINVAL;
+ }
+
+ if (check_argc_exact(argc - optind, 1))
usage(cmd_df_usage);
- path = argv[1];
+ path = argv[argc - 1];
fd = open_file_or_dir(path, &dirstream);
if (fd < 0) {
@@ -239,7 +287,7 @@ static int cmd_df(int argc, char **argv)
ret = get_df(fd, &sargs);
if (!ret && sargs) {
- print_df(sargs);
+ print_df(sargs, output_unit);
free(sargs);
} else {
fprintf(stderr, "ERROR: get_df failed %s\n", strerror(-ret));
@@ -1280,6 +1280,36 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_bytes)
return snprintf(str, str_bytes, "%.2f%s", fraction,
size_strs[num_divs]);
}
+int fixed_unit_size_snprintf(u64 size, int unit, char *str, size_t str_bytes)
+{
+ int size_str_idx;
+ float fraction;
+
+ switch (unit) {
+ case 1:
+ size_str_idx = 0;
+ break;
+ case 1024:
+ size_str_idx = 1;
+ break;
+ case 1024 * 1024:
+ size_str_idx = 2;
+ break;
+ case 1024 * 1024 * 1024:
+ size_str_idx = 3;
+ break;
+ default:
+ return pretty_size_snprintf(size, str, str_bytes);
+ }
+
+ if (str_bytes == 0)
+ return 0;
+
+ fraction = (float)size / unit;
+
+ return snprintf(str, str_bytes, "%.2f%s", fraction,
+ size_strs[size_str_idx]);
+}
/*
* __strncpy__null - strncpy with null termination
@@ -67,6 +67,14 @@ int pretty_size_snprintf(u64 size, char *str, size_t str_bytes);
_str; \
})
+int fixed_unit_size_snprintf(u64 size, int unit, char *str, size_t str_bytes);
+#define fixed_unit_size(size, unit) \
+ ({ \
+ static __thread char _str[24]; \
+ (void)fixed_unit_size_snprintf((size), (unit), _str, sizeof(_str)); \
+ _str; \
+ })
+
int get_mountpt(char *dev, char *mntpt, size_t size);
int btrfs_scan_block_devices(int run_ioctl);
u64 parse_size(char *s);
The automatic unit selection makes parsing the output of `filesystem df` unnecessarily difficult. Using the new options -b, -k, -m, and -g, the output unit can be set to bytes, kibi-, mebi-, and gibibytes respectively. Signed-off-by: Nils Steinger <nst@voidptr.de> --- cmds-filesystem.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++------- utils.c | 30 +++++++++++++++++++++++++++ utils.h | 8 +++++++ 3 files changed, 93 insertions(+), 7 deletions(-)