-
+#include <getopt.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include "libbcachefs/bcachefs_ioctl.h"
#include "libbcachefs/darray.h"
#include "libbcachefs/opts.h"
+#include "libbcachefs/super-io.h"
#include "cmds.h"
#include "libbcachefs.h"
}
static void dev_usage_type_to_text(struct printbuf *out,
- struct bch_ioctl_dev_usage *u,
+ struct bch_ioctl_dev_usage_v2 *u,
enum bch_data_type type)
{
+ u64 sectors = 0;
+ switch (type) {
+ case BCH_DATA_free:
+ case BCH_DATA_need_discard:
+ case BCH_DATA_need_gc_gens:
+ /* sectors are 0 for these types so calculate sectors for them */
+ sectors = u->d[type].buckets * u->bucket_size;
+ break;
+ default:
+ sectors = u->d[type].sectors;
+ }
+
__dev_usage_type_to_text(out, bch2_data_types[type],
u->bucket_size,
u->d[type].buckets,
- u->d[type].sectors,
+ sectors,
u->d[type].fragmented);
}
struct bchfs_handle fs,
struct dev_name *d)
{
- struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, d->idx);
- unsigned i;
+ struct bch_ioctl_dev_usage_v2 *u = bchu_dev_usage(fs, d->idx);
prt_newline(out);
prt_printf(out, "%s (device %u):", d->label ?: "(no label)", d->idx);
prt_str(out, d->dev ?: "(device not found)");
prt_tab_rjust(out);
- prt_str(out, bch2_member_states[u.state]);
+ prt_str(out, bch2_member_states[u->state]);
prt_tab_rjust(out);
prt_newline(out);
prt_newline(out);
- for (i = 0; i < BCH_DATA_NR; i++)
- dev_usage_type_to_text(out, &u, i);
- __dev_usage_type_to_text(out, "erasure coded",
- u.bucket_size,
- u.buckets_ec, u.buckets_ec * u.bucket_size, 0);
+ for (unsigned i = 0; i < u->nr_data_types; i++)
+ dev_usage_type_to_text(out, u, i);
prt_str(out, "capacity:");
prt_tab(out);
- prt_units_u64(out, (u.nr_buckets * u.bucket_size) << 9);
+ prt_units_u64(out, (u->nr_buckets * u->bucket_size) << 9);
prt_tab_rjust(out);
- prt_printf(out, "%llu", u.nr_buckets);
+ prt_printf(out, "%llu", u->nr_buckets);
prt_tab_rjust(out);
printbuf_indent_sub(out, 2);
prt_newline(out);
+ free(u);
}
static int dev_by_label_cmp(const void *_l, const void *_r)
static struct dev_name *dev_idx_to_name(dev_names *dev_names, unsigned idx)
{
- struct dev_name *dev;
-
darray_for_each(*dev_names, dev)
if (dev->idx == idx)
return dev;
-
return NULL;
}
const struct bch_replicas_usage *r,
dev_names *dev_names)
{
- unsigned i;
-
if (!r->sectors)
return;
char devs[4096], *d = devs;
*d++ = '[';
- for (i = 0; i < r->r.nr_devs; i++) {
+ unsigned durability = 0;
+
+ for (unsigned i = 0; i < r->r.nr_devs; i++) {
unsigned dev_idx = r->r.devs[i];
struct dev_name *dev = dev_idx_to_name(dev_names, dev_idx);
+ durability += dev->durability;
+
if (i)
*d++ = ' ';
prt_printf(out, "%u/%u ", r->r.nr_required, r->r.nr_devs);
prt_tab(out);
+ prt_printf(out, "%u ", durability);
+ prt_tab(out);
+
prt_printf(out, "%s ", devs);
prt_tab(out);
struct bchfs_handle fs = bcache_fs_open(path);
- struct dev_name *dev;
dev_names dev_names = bchu_fs_get_devices(fs);
struct bch_ioctl_fs_usage *u = bchu_fs_usage(fs);
prt_newline(out);
printbuf_tabstops_reset(out);
- printbuf_tabstop_push(out, 16);
- printbuf_tabstop_push(out, 16);
- printbuf_tabstop_push(out, 18);
- printbuf_tabstop_push(out, 18);
+ printbuf_tabstop_push(out, 16);
prt_str(out, "Data type");
prt_tab(out);
+ printbuf_tabstop_push(out, 16);
prt_str(out, "Required/total");
prt_tab(out);
+ printbuf_tabstop_push(out, 14);
+ prt_str(out, "Durability");
+ prt_tab(out);
+
+ printbuf_tabstop_push(out, 14);
prt_str(out, "Devices");
prt_newline(out);
+ printbuf_tabstop_push(out, 14);
+
for (i = 0; i < BCH_REPLICAS_MAX; i++) {
if (!u->persistent_reserved[i])
continue;
bcache_fs_close(fs);
}
-int fs_usage(void)
+static void fs_usage_usage(void)
{
- puts("bcachefs fs - manage a running filesystem\n"
- "Usage: bcachefs fs <CMD> [OPTION]... path\n"
- "\n"
- "Commands:\n"
- " usage show disk usage\n"
- "\n"
- "Report bugs to <linux-bcachefs@vger.kernel.org>");
- return 0;
+ puts("bcachefs fs usage - display detailed filesystem usage\n"
+ "Usage: bcachefs fs usage [OPTION]... <mountpoint>\n"
+ "\n"
+ "Options:\n"
+ " -h, --human-readable Human readable units\n"
+ " -H, --help Display this help and exit\n"
+ "Report bugs to <linux-bcachefs@vger.kernel.org>");
}
int cmd_fs_usage(int argc, char *argv[])
{
+ static const struct option longopts[] = {
+ { "help", no_argument, NULL, 'H' },
+ { "human-readable", no_argument, NULL, 'h' },
+ { NULL }
+ };
bool human_readable = false;
struct printbuf buf = PRINTBUF;
char *fs;
int opt;
- while ((opt = getopt(argc, argv, "h")) != -1)
+ while ((opt = getopt_long(argc, argv, "h",
+ longopts, NULL)) != -1)
switch (opt) {
case 'h':
human_readable = true;
break;
+ case 'H':
+ fs_usage_usage();
+ exit(EXIT_SUCCESS);
+ default:
+ fs_usage_usage();
+ exit(EXIT_FAILURE);
}
args_shift(optind);