X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=cmd_fs.c;h=cd5a666def823d0ee938017c2e0b9fe98d91b720;hb=4064aa126e2c77b86d090cd8b7731d238e73ae85;hp=44316fc5d3773e18f624b8744dc1f1eb0625599f;hpb=9c62b2b4f11374cbffe88e0c31b9b1ab32a2863a;p=bcachefs-tools-debian diff --git a/cmd_fs.c b/cmd_fs.c index 44316fc..cd5a666 100644 --- a/cmd_fs.c +++ b/cmd_fs.c @@ -14,123 +14,184 @@ #include "cmds.h" #include "libbcachefs.h" -static void print_dev_usage(struct bch_ioctl_dev_usage *d, unsigned idx, - const char *label, enum units units) +static void print_dev_usage_type(const char *type, + unsigned bucket_size, + u64 buckets, u64 sectors, + enum units units) { - char *name = NULL; - u64 available = d->nr_buckets; + u64 frag = max((s64) buckets * bucket_size - (s64) sectors, 0LL); + + printf_pad(20, " %s:", type); + printf(" %15s %15llu %15s\n", + pr_units(sectors, units), + buckets, + pr_units(frag, units)); +} + +static void print_dev_usage(struct bchfs_handle fs, + struct dev_name *d, + enum units units) +{ + struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, d->idx); unsigned i; printf("\n"); - printf_pad(20, "%s (device %u):", label, idx); - - name = !d->dev ? strdup("(offline)") - : dev_to_path(d->dev) - ?: strdup("(device not found)"); - printf("%24s%12s\n", name, bch2_dev_state[d->state]); - free(name); + printf_pad(20, "%s (device %u):", d->label ?: "(no label)", d->idx); + printf("%30s%16s\n", d->dev ?: "(device not found)", bch2_dev_state[u.state]); - printf("%-20s%12s%12s%12s\n", + printf("%-20s%16s%16s%16s\n", "", "data", "buckets", "fragmented"); - for (i = BCH_DATA_SB; i < BCH_DATA_NR; i++) { - u64 frag = max((s64) d->buckets[i] * d->bucket_size - - (s64) d->sectors[i], 0LL); + for (i = BCH_DATA_sb; i < BCH_DATA_NR; i++) + print_dev_usage_type(bch2_data_types[i], + u.bucket_size, + u.buckets[i], + u.sectors[i], + units); - printf_pad(20, " %s:", bch2_data_types[i]); - printf("%12s%12llu%12s\n", - pr_units(d->sectors[i], units), - d->buckets[i], - pr_units(frag, units)); - - if (i != BCH_DATA_CACHED) - available -= d->buckets[i]; - } + print_dev_usage_type("erasure coded", + u.bucket_size, + u.ec_buckets, + u.ec_sectors, + units); printf_pad(20, " available:"); - printf("%12s%12llu\n", - pr_units(available * d->bucket_size, units), - available); + printf(" %15s %15llu\n", + pr_units(u.available_buckets * u.bucket_size, units), + u.available_buckets); printf_pad(20, " capacity:"); - printf("%12s%12llu\n", - pr_units(d->nr_buckets * d->bucket_size, units), - d->nr_buckets); + printf(" %15s %15llu\n", + pr_units(u.nr_buckets * u.bucket_size, units), + u.nr_buckets); } -struct dev_by_label { - unsigned idx; - char *label; -}; - static int dev_by_label_cmp(const void *_l, const void *_r) { - const struct dev_by_label *l = _l, *r = _r; + const struct dev_name *l = _l, *r = _r; + + return (l->label && r->label + ? strcmp(l->label, r->label) : 0) ?: + (l->dev && r->dev + ? strcmp(l->dev, r->dev) : 0) ?: + cmp_int(l->idx, r->idx); +} + +static struct dev_name *dev_idx_to_name(dev_names *dev_names, unsigned idx) +{ + struct dev_name *dev; + + darray_foreach(dev, *dev_names) + if (dev->idx == idx) + return dev; + + return NULL; +} + +static void print_replicas_usage(const struct bch_replicas_usage *r, + dev_names *dev_names, enum units units) +{ + unsigned i; + + if (!r->sectors) + return; - return strcmp(l->label, r->label); + char devs[4096], *d = devs; + *d++ = '['; + + for (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); + + if (i) + *d++ = ' '; + + d += dev && dev->dev + ? sprintf(d, "%s", dev->dev) + : sprintf(d, "%u", dev_idx); + } + *d++ = ']'; + *d++ = '\0'; + + printf_pad(16, "%s: ", bch2_data_types[r->r.data_type]); + printf_pad(16, "%u/%u ", r->r.nr_required, r->r.nr_devs); + printf_pad(32, "%s ", devs); + printf(" %s\n", pr_units(r->sectors, units)); } +#define for_each_usage_replica(_u, _r) \ + for (_r = (_u)->replicas; \ + _r != (void *) (_u)->replicas + (_u)->replica_entries_bytes;\ + _r = replicas_usage_next(_r), \ + BUG_ON((void *) _r > (void *) (_u)->replicas + (_u)->replica_entries_bytes)) + static void print_fs_usage(const char *path, enum units units) { - unsigned i, j; + unsigned i; char uuid[40]; struct bchfs_handle fs = bcache_fs_open(path); - struct bch_ioctl_usage *u = bchu_usage(fs); + + struct dev_name *dev; + dev_names dev_names = bchu_fs_get_devices(fs); + + struct bch_ioctl_fs_usage *u = bchu_fs_usage(fs); uuid_unparse(fs.uuid.b, uuid); printf("Filesystem %s:\n", uuid); - printf("%-20s%12s\n", "Size:", pr_units(u->fs.capacity, units)); - printf("%-20s%12s\n", "Used:", pr_units(u->fs.used, units)); + printf("%-20s%12s\n", "Size:", pr_units(u->capacity, units)); + printf("%-20s%12s\n", "Used:", pr_units(u->used, units)); - printf("%-20s%12s%12s%12s%12s\n", - "By replicas:", "1x", "2x", "3x", "4x"); + printf("%-20s%12s\n", "Online reserved:", pr_units(u->online_reserved, units)); - for (j = BCH_DATA_SB; j < BCH_DATA_NR; j++) { - printf_pad(20, " %s:", bch2_data_types[j]); + printf("\n"); + printf("%-16s%-16s%s\n", "Data type", "Required/total", "Devices"); - for (i = 0; i < BCH_REPLICAS_MAX; i++) - printf("%12s", pr_units(u->fs.sectors[j][i], units)); - printf("\n"); - } + for (i = 0; i < BCH_REPLICAS_MAX; i++) { + if (!u->persistent_reserved[i]) + continue; - printf_pad(20, " %s:", "reserved"); - for (i = 0; i < BCH_REPLICAS_MAX; i++) - printf("%12s", pr_units(u->fs.persistent_reserved[i], units)); - printf("\n"); + printf_pad(16, "%s: ", "reserved"); + printf_pad(16, "%u/%u ", 1, i); + printf_pad(32, "[] "); + printf("%s\n", pr_units(u->persistent_reserved[i], units)); + } - printf("%-20s%12s\n", " online reserved:", pr_units(u->fs.online_reserved, units)); + struct bch_replicas_usage *r; - darray(struct dev_by_label) devs_by_label; - darray_init(devs_by_label); + for_each_usage_replica(u, r) + if (r->r.data_type < BCH_DATA_user) + print_replicas_usage(r, &dev_names, units); - for (i = 0; i < u->nr_devices; i++) { - struct bch_ioctl_dev_usage *d = u->devs + i; + for_each_usage_replica(u, r) + if (r->r.data_type == BCH_DATA_user && + r->r.nr_required <= 1) + print_replicas_usage(r, &dev_names, units); - if (!d->alive) - continue; + for_each_usage_replica(u, r) + if (r->r.data_type == BCH_DATA_user && + r->r.nr_required > 1) + print_replicas_usage(r, &dev_names, units); - char *label_attr = mprintf("dev-%u/label", i); - char *label = read_file_str(fs.sysfs_fd, label_attr); - free(label_attr); + for_each_usage_replica(u, r) + if (r->r.data_type > BCH_DATA_user) + print_replicas_usage(r, &dev_names, units); - darray_append(devs_by_label, - (struct dev_by_label) { i, label }); - } + free(u); - sort(&darray_item(devs_by_label, 0), darray_size(devs_by_label), - sizeof(darray_item(devs_by_label, 0)), dev_by_label_cmp, NULL); + sort(&darray_item(dev_names, 0), darray_size(dev_names), + sizeof(darray_item(dev_names, 0)), dev_by_label_cmp, NULL); - struct dev_by_label *d; - darray_foreach(d, devs_by_label) - print_dev_usage(u->devs + d->idx, d->idx, d->label, units); + darray_foreach(dev, dev_names) + print_dev_usage(fs, dev, units); - darray_foreach(d, devs_by_label) - free(d->label); - darray_free(devs_by_label); + darray_foreach(dev, dev_names) { + free(dev->dev); + free(dev->label); + } + darray_free(dev_names); - free(u); bcache_fs_close(fs); }