From 5528e3ae62ead1cfd5be36c1712d1a2dd5ccb3af Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Tue, 22 Feb 2022 04:55:39 -0500 Subject: [PATCH] Update bcachefs sources to 9b3aa5ec6c bcachefs: Add tabstops to printbufs --- .bcachefs_revision | 2 +- cmd_debug.c | 2 +- cmd_format.c | 20 +- cmd_fs.c | 226 +++++++++++++------ libbcachefs.c | 497 ----------------------------------------- libbcachefs.h | 2 - libbcachefs/move.c | 4 +- libbcachefs/super-io.c | 12 +- libbcachefs/util.c | 8 +- libbcachefs/util.h | 80 ++++++- tools-util.c | 36 --- tools-util.h | 14 -- 12 files changed, 259 insertions(+), 644 deletions(-) diff --git a/.bcachefs_revision b/.bcachefs_revision index b537d89..1730c99 100644 --- a/.bcachefs_revision +++ b/.bcachefs_revision @@ -1 +1 @@ -9d554fa16def4f6310d2df74092c5568419e69e3 +9b3aa5ec6cb7a3f12b9c683b4d28be2df0faa95c diff --git a/cmd_debug.c b/cmd_debug.c index 6340255..029890a 100644 --- a/cmd_debug.c +++ b/cmd_debug.c @@ -620,7 +620,7 @@ int cmd_list_journal(int argc, char *argv[]) * log entries denote the start of a new transaction * commit: */ - printbuf_indent_push(&buf, + pr_indent_push(&buf, entry->type == BCH_JSET_ENTRY_log ? 2 : 4); bch2_journal_entry_to_text(&buf, c, entry); printf("%s\n", _buf); diff --git a/cmd_format.c b/cmd_format.c index cc16b31..e57553d 100644 --- a/cmd_format.c +++ b/cmd_format.c @@ -236,8 +236,15 @@ int cmd_format(int argc, char *argv[]) devices.item, darray_size(devices)); bch2_opt_strs_free(&fs_opt_strs); - if (!quiet) - bch2_sb_print(sb, false, 1 << BCH_SB_FIELD_members, HUMAN_READABLE); + if (!quiet) { + char buf[4096]; + struct printbuf out = PBUF(buf); + + out.units = PRINTBUF_UNITS_HUMAN_READABLE; + + bch2_sb_to_text(&PBUF(buf), sb, false, 1 << BCH_SB_FIELD_members); + printf("%s", buf); + } free(sb); if (opts.passphrase) { @@ -325,7 +332,14 @@ int cmd_show_super(int argc, char *argv[]) if (ret) die("Error opening %s: %s", dev, strerror(-ret)); - bch2_sb_print(sb.sb, print_layout, fields, HUMAN_READABLE); + char buf[4096 << 2]; + struct printbuf out = PBUF(buf); + + out.units = PRINTBUF_UNITS_HUMAN_READABLE; + + bch2_sb_to_text(&PBUF(buf), sb.sb, print_layout, fields); + printf("%s", buf); + bch2_free_super(&sb); return 0; } diff --git a/cmd_fs.c b/cmd_fs.c index f8c4642..759c989 100644 --- a/cmd_fs.c +++ b/cmd_fs.c @@ -14,56 +14,90 @@ #include "cmds.h" #include "libbcachefs.h" -static void print_dev_usage_type(const char *type, - unsigned bucket_size, - u64 buckets, u64 sectors, - enum units units) +static void dev_usage_type_to_text(struct printbuf *out, + const char *type, + unsigned bucket_size, + u64 buckets, u64 sectors) { 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)); + pr_buf(out, "%s:", type); + pr_tab(out); + pr_sectors(out, sectors); + pr_tab_rjust(out); + pr_buf(out, "%llu", buckets); + pr_tab_rjust(out); + pr_sectors(out, frag); + pr_tab_rjust(out); + pr_newline(out); } -static void print_dev_usage(struct bchfs_handle fs, - struct dev_name *d, - enum units units) +static void dev_usage_to_text(struct printbuf *out, + struct bchfs_handle fs, + struct dev_name *d) { struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, d->idx); unsigned i; - printf("\n"); - printf_pad(20, "%s (device %u):", d->label ?: "(no label)", d->idx); - printf("%30s%16s\n", d->dev ?: "(device not found)", bch2_member_states[u.state]); + pr_newline(out); + pr_buf(out, "%s (device %u):", d->label ?: "(no label)", d->idx); + pr_tab(out); + pr_buf(out, "%s", d->dev ?: "(device not found)"); + pr_tab_rjust(out); - printf("%-20s%16s%16s%16s\n", - "", "data", "buckets", "fragmented"); + pr_buf(out, "%s", bch2_member_states[u.state]); + pr_tab_rjust(out); + + pr_newline(out); + + pr_indent_push(out, 2); + pr_tab(out); + + pr_buf(out, "data"); + pr_tab_rjust(out); + + pr_buf(out, "buckets"); + pr_tab_rjust(out); + + pr_buf(out, "fragmented"); + pr_tab_rjust(out); + + pr_newline(out); 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); - - print_dev_usage_type("erasure coded", - u.bucket_size, - u.ec_buckets, - u.ec_sectors, - units); - - printf_pad(20, " available:"); - printf(" %15s %15llu\n", - pr_units(u.available_buckets * u.bucket_size, units), - u.available_buckets); - - printf_pad(20, " capacity:"); - printf(" %15s %15llu\n", - pr_units(u.nr_buckets * u.bucket_size, units), - u.nr_buckets); + dev_usage_type_to_text(out, + bch2_data_types[i], + u.bucket_size, + u.buckets[i], + u.sectors[i]); + + dev_usage_type_to_text(out, + "erasure coded", + u.bucket_size, + u.ec_buckets, + u.ec_sectors); + + pr_buf(out, "available:"); + pr_tab(out); + + pr_sectors(out, u.available_buckets * u.bucket_size); + pr_tab_rjust(out); + + pr_buf(out, "%llu", u.available_buckets); + pr_tab_rjust(out); + pr_newline(out); + + pr_buf(out, "capacity:"); + pr_tab(out); + + pr_sectors(out, u.nr_buckets * u.bucket_size); + pr_tab_rjust(out); + pr_buf(out, "%llu", u.nr_buckets); + pr_tab_rjust(out); + + pr_indent_pop(out, 2); + + pr_newline(out); } static int dev_by_label_cmp(const void *_l, const void *_r) @@ -88,8 +122,9 @@ static struct dev_name *dev_idx_to_name(dev_names *dev_names, unsigned idx) return NULL; } -static void print_replicas_usage(const struct bch_replicas_usage *r, - dev_names *dev_names, enum units units) +static void replicas_usage_to_text(struct printbuf *out, + const struct bch_replicas_usage *r, + dev_names *dev_names) { unsigned i; @@ -113,10 +148,18 @@ static void print_replicas_usage(const struct bch_replicas_usage *r, *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)); + pr_buf(out, "%s: ", bch2_data_types[r->r.data_type]); + pr_tab(out); + + pr_buf(out, "%u/%u ", r->r.nr_required, r->r.nr_devs); + pr_tab(out); + + pr_buf(out, "%s ", devs); + pr_tab(out); + + pr_sectors(out, r->sectors); + pr_tab_rjust(out); + pr_newline(out); } #define for_each_usage_replica(_u, _r) \ @@ -125,10 +168,9 @@ static void print_replicas_usage(const struct bch_replicas_usage *r, _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) +static void fs_usage_to_text(struct printbuf *out, const char *path) { unsigned i; - char uuid[40]; struct bchfs_handle fs = bcache_fs_open(path); @@ -137,54 +179,93 @@ static void print_fs_usage(const char *path, enum units units) struct bch_ioctl_fs_usage *u = bchu_fs_usage(fs); - uuid_unparse(fs.uuid.b, uuid); - printf("Filesystem %s:\n", uuid); + pr_buf(out, "Filesystem: "); + pr_uuid(out, fs.uuid.b); + pr_newline(out); + + out->tabstops[0] = 20; + out->tabstops[1] = 36; + + pr_buf(out, "Size:"); + pr_tab(out); + pr_sectors(out, u->capacity); + pr_tab_rjust(out); + pr_newline(out); - printf("%-20s%12s\n", "Size:", pr_units(u->capacity, units)); - printf("%-20s%12s\n", "Used:", pr_units(u->used, units)); + pr_buf(out, "Used:"); + pr_tab(out); + pr_sectors(out, u->used); + pr_tab_rjust(out); + pr_newline(out); - printf("%-20s%12s\n", "Online reserved:", pr_units(u->online_reserved, units)); + pr_buf(out, "Online reserved:"); + pr_tab(out); + pr_sectors(out, u->online_reserved); + pr_tab_rjust(out); + pr_newline(out); - printf("\n"); - printf("%-16s%-16s%s\n", "Data type", "Required/total", "Devices"); + pr_newline(out); + + out->tabstops[0] = 16; + out->tabstops[1] = 32; + out->tabstops[2] = 50; + out->tabstops[3] = 68; + + pr_buf(out, "Data type"); + pr_tab(out); + + pr_buf(out, "Required/total"); + pr_tab(out); + + pr_buf(out, "Devices"); + pr_newline(out); for (i = 0; i < BCH_REPLICAS_MAX; i++) { if (!u->persistent_reserved[i]) continue; - 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)); + pr_buf(out, "reserved:"); + pr_tab(out); + pr_buf(out, "%u/%u ", 1, i); + pr_tab(out); + pr_buf(out, "[] "); + pr_sectors(out, u->persistent_reserved[i]); + pr_tab_rjust(out); + pr_newline(out); } struct bch_replicas_usage *r; for_each_usage_replica(u, r) if (r->r.data_type < BCH_DATA_user) - print_replicas_usage(r, &dev_names, units); + replicas_usage_to_text(out, r, &dev_names); 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); + replicas_usage_to_text(out, r, &dev_names); 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); + replicas_usage_to_text(out, r, &dev_names); for_each_usage_replica(u, r) if (r->r.data_type > BCH_DATA_user) - print_replicas_usage(r, &dev_names, units); + replicas_usage_to_text(out, r, &dev_names); free(u); sort(&darray_item(dev_names, 0), darray_size(dev_names), sizeof(darray_item(dev_names, 0)), dev_by_label_cmp, NULL); + out->tabstops[0] = 16; + out->tabstops[1] = 36; + out->tabstops[2] = 52; + out->tabstops[3] = 68; + darray_foreach(dev, dev_names) - print_dev_usage(fs, dev, units); + dev_usage_to_text(out, fs, dev); darray_foreach(dev, dev_names) { free(dev->dev); @@ -209,23 +290,34 @@ int fs_usage(void) int cmd_fs_usage(int argc, char *argv[]) { - enum units units = BYTES; + enum printbuf_units units = PRINTBUF_UNITS_BYTES; + char _buf[1 << 16]; + struct printbuf buf; char *fs; int opt; while ((opt = getopt(argc, argv, "h")) != -1) switch (opt) { case 'h': - units = HUMAN_READABLE; + units = PRINTBUF_UNITS_HUMAN_READABLE; break; } args_shift(optind); if (!argc) { - print_fs_usage(".", units); + buf = PBUF(_buf); + buf.units = units; + fs_usage_to_text(&buf, "."); + *buf.pos = 0; + printf("%s", _buf); } else { - while ((fs = arg_pop())) - print_fs_usage(fs, units); + while ((fs = arg_pop())) { + buf = PBUF(_buf); + buf.units = units; + fs_usage_to_text(&buf, fs); + *buf.pos = 0; + printf("%s", _buf); + } } return 0; diff --git a/libbcachefs.c b/libbcachefs.c index f78ebf0..1c780be 100644 --- a/libbcachefs.c +++ b/libbcachefs.c @@ -365,503 +365,6 @@ struct bch_sb *__bch2_super_read(int fd, u64 sector) return ret; } -static unsigned get_dev_has_data(struct bch_sb *sb, unsigned dev) -{ - struct bch_sb_field_replicas *replicas; - struct bch_replicas_entry *r; - unsigned i, data_has = 0; - - replicas = bch2_sb_get_replicas(sb); - - if (replicas) - for_each_replicas_entry(replicas, r) - for (i = 0; i < r->nr_devs; i++) - if (r->devs[i] == dev) - data_has |= 1 << r->data_type; - - return data_has; -} - -static int bch2_sb_get_target(struct bch_sb *sb, char *buf, size_t len, u64 v) -{ - struct target t = target_decode(v); - int ret; - - switch (t.type) { - case TARGET_NULL: - return scnprintf(buf, len, "none"); - case TARGET_DEV: { - struct bch_sb_field_members *mi = bch2_sb_get_members(sb); - struct bch_member *m = mi->members + t.dev; - - if (bch2_dev_exists(sb, mi, t.dev)) { - char uuid_str[40]; - - uuid_unparse(m->uuid.b, uuid_str); - - ret = scnprintf(buf, len, "Device %u (%s)", t.dev, - uuid_str); - } else { - ret = scnprintf(buf, len, "Bad device %u", t.dev); - } - - break; - } - case TARGET_GROUP: { - struct bch_sb_field_disk_groups *gi; - gi = bch2_sb_get_disk_groups(sb); - - struct bch_disk_group *g = gi->entries + t.group; - - if (t.group < disk_groups_nr(gi) && !BCH_GROUP_DELETED(g)) { - ret = scnprintf(buf, len, "Label %u (%.*s)", t.group, - BCH_SB_LABEL_SIZE, g->label); - } else { - ret = scnprintf(buf, len, "Bad label %u", t.group); - } - break; - } - default: - BUG(); - } - - return ret; -} - -/* superblock printing: */ - -static void bch2_sb_print_layout(struct bch_sb *sb, enum units units) -{ - struct bch_sb_layout *l = &sb->layout; - unsigned i; - - printf(" type: %u\n" - " superblock max size: %s\n" - " nr superblocks: %u\n" - " Offsets: ", - l->layout_type, - pr_units(1 << l->sb_max_size_bits, units), - l->nr_superblocks); - - for (i = 0; i < l->nr_superblocks; i++) { - if (i) - printf(", "); - printf("%llu", le64_to_cpu(l->sb_offset[i])); - } - putchar('\n'); -} - -static void bch2_sb_print_journal(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_journal *journal = field_to_type(f, journal); - unsigned i, nr = bch2_nr_journal_buckets(journal); - - printf(" Buckets: "); - for (i = 0; i < nr; i++) { - if (i) - putchar(' '); - printf("%llu", le64_to_cpu(journal->buckets[i])); - } - putchar('\n'); -} - -static void bch2_sb_print_members(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_members *mi = field_to_type(f, members); - struct bch_sb_field_disk_groups *gi = bch2_sb_get_disk_groups(sb); - unsigned i; - - for (i = 0; i < sb->nr_devices; i++) { - struct bch_member *m = mi->members + i; - time_t last_mount = le64_to_cpu(m->last_mount); - char member_uuid_str[40]; - char data_allowed_str[100]; - char data_has_str[100]; - char label [BCH_SB_LABEL_SIZE+10]; - char time_str[64]; - - if (!bch2_member_exists(m)) - continue; - - uuid_unparse(m->uuid.b, member_uuid_str); - - if (BCH_MEMBER_GROUP(m)) { - unsigned idx = BCH_MEMBER_GROUP(m) - 1; - - if (idx < disk_groups_nr(gi)) { - scnprintf(label, sizeof(label), "%.*s (%u)", - BCH_SB_LABEL_SIZE, - gi->entries[idx].label, idx); - } else { - strcpy(label, "(bad disk labels section)"); - } - } else { - strcpy(label, "(none)"); - } - - bch2_flags_to_text(&PBUF(data_allowed_str), - bch2_data_types, - BCH_MEMBER_DATA_ALLOWED(m)); - if (!data_allowed_str[0]) - strcpy(data_allowed_str, "(none)"); - - bch2_flags_to_text(&PBUF(data_has_str), - bch2_data_types, - get_dev_has_data(sb, i)); - if (!data_has_str[0]) - strcpy(data_has_str, "(none)"); - - if (last_mount) { - struct tm *tm = localtime(&last_mount); - size_t err = strftime(time_str, sizeof(time_str), "%c", tm); - if (!err) - strcpy(time_str, "(formatting error)"); - } else { - strcpy(time_str, "(never)"); - } - - printf(" Device %u:\n" - " UUID: %s\n" - " Size: %s\n" - " Bucket size: %s\n" - " First bucket: %u\n" - " Buckets: %llu\n" - " Last mount: %s\n" - " State: %s\n" - " Group: %s\n" - " Data allowed: %s\n" - - " Has data: %s\n" - - " Discard: %llu\n", - i, member_uuid_str, - pr_units(le16_to_cpu(m->bucket_size) * - le64_to_cpu(m->nbuckets), units), - pr_units(le16_to_cpu(m->bucket_size), units), - le16_to_cpu(m->first_bucket), - le64_to_cpu(m->nbuckets), - time_str, - - BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR - ? bch2_member_states[BCH_MEMBER_STATE(m)] - : "unknown", - - label, - data_allowed_str, - data_has_str, - - BCH_MEMBER_DISCARD(m)); - } -} - -static void bch2_sb_print_crypt(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_crypt *crypt = field_to_type(f, crypt); - - printf(" KFD: %llu\n" - " scrypt n: %llu\n" - " scrypt r: %llu\n" - " scrypt p: %llu\n", - BCH_CRYPT_KDF_TYPE(crypt), - BCH_KDF_SCRYPT_N(crypt), - BCH_KDF_SCRYPT_R(crypt), - BCH_KDF_SCRYPT_P(crypt)); -} - -static void bch2_sb_print_replicas_v0(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_replicas_v0 *replicas = field_to_type(f, replicas_v0); - struct bch_replicas_entry_v0 *e; - unsigned i; - - for_each_replicas_entry(replicas, e) { - printf_pad(32, " %s:", bch2_data_types[e->data_type]); - - putchar('['); - for (i = 0; i < e->nr_devs; i++) { - if (i) - putchar(' '); - printf("%u", e->devs[i]); - } - printf("]\n"); - } -} - -static void bch2_sb_print_replicas(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_replicas *replicas = field_to_type(f, replicas); - struct bch_replicas_entry *e; - unsigned i; - - for_each_replicas_entry(replicas, e) { - printf_pad(32, " %s: %u/%u", - bch2_data_types[e->data_type], - e->nr_required, - e->nr_devs); - - putchar('['); - for (i = 0; i < e->nr_devs; i++) { - if (i) - putchar(' '); - printf("%u", e->devs[i]); - } - printf("]\n"); - } -} - -static void bch2_sb_print_quota(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ -} - -static void bch2_sb_print_disk_groups(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ -} - -static void bch2_sb_print_clean(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_clean *clean = field_to_type(f, clean); - - - printf(" flags: %x", le32_to_cpu(clean->flags)); - printf(" journal seq: %llx", le64_to_cpu(clean->journal_seq)); -} - -static void bch2_sb_print_journal_seq_blacklist(struct bch_sb *sb, struct bch_sb_field *f, - enum units units) -{ - struct bch_sb_field_journal_seq_blacklist *bl = field_to_type(f, journal_seq_blacklist); - unsigned i, nr = blacklist_nr_entries(bl); - - for (i = 0; i < nr; i++) { - struct journal_seq_blacklist_entry *e = - bl->start + i; - - printf(" %llu-%llu\n", - le64_to_cpu(e->start), - le64_to_cpu(e->end)); - } -} - -typedef void (*sb_field_print_fn)(struct bch_sb *, struct bch_sb_field *, enum units); - -struct bch_sb_field_toolops { - sb_field_print_fn print; -}; - -static const struct bch_sb_field_toolops bch2_sb_field_ops[] = { -#define x(f, nr) \ - [BCH_SB_FIELD_##f] = { \ - .print = bch2_sb_print_##f, \ - }, - BCH_SB_FIELDS() -#undef x -}; - -static inline void bch2_sb_field_print(struct bch_sb *sb, - struct bch_sb_field *f, - enum units units) -{ - unsigned type = le32_to_cpu(f->type); - - if (type < BCH_SB_FIELD_NR) - bch2_sb_field_ops[type].print(sb, f, units); - else - printf("(unknown field %u)\n", type); -} - -void bch2_sb_print(struct bch_sb *sb, bool print_layout, - unsigned fields, enum units units) -{ - struct bch_sb_field_members *mi; - char user_uuid_str[40], internal_uuid_str[40]; - char features_str[500]; - char compat_features_str[500]; - char fields_have_str[200]; - char label[BCH_SB_LABEL_SIZE + 1]; - char time_str[64]; - char foreground_str[64]; - char background_str[64]; - char promote_str[64]; - char metadata_str[64]; - struct bch_sb_field *f; - u64 fields_have = 0; - unsigned nr_devices = 0; - time_t time_base = le64_to_cpu(sb->time_base_lo) / NSEC_PER_SEC; - - memcpy(label, sb->label, BCH_SB_LABEL_SIZE); - label[BCH_SB_LABEL_SIZE] = '\0'; - - uuid_unparse(sb->user_uuid.b, user_uuid_str); - uuid_unparse(sb->uuid.b, internal_uuid_str); - - if (time_base) { - struct tm *tm = localtime(&time_base); - size_t err = strftime(time_str, sizeof(time_str), "%c", tm); - if (!err) - strcpy(time_str, "(formatting error)"); - } else { - strcpy(time_str, "(not set)"); - } - - mi = bch2_sb_get_members(sb); - if (mi) { - struct bch_member *m; - - for (m = mi->members; - m < mi->members + sb->nr_devices; - m++) - nr_devices += bch2_member_exists(m); - } - - bch2_sb_get_target(sb, foreground_str, sizeof(foreground_str), - BCH_SB_FOREGROUND_TARGET(sb)); - - bch2_sb_get_target(sb, background_str, sizeof(background_str), - BCH_SB_BACKGROUND_TARGET(sb)); - - bch2_sb_get_target(sb, promote_str, sizeof(promote_str), - BCH_SB_PROMOTE_TARGET(sb)); - - bch2_sb_get_target(sb, metadata_str, sizeof(metadata_str), - BCH_SB_METADATA_TARGET(sb)); - - bch2_flags_to_text(&PBUF(features_str), - bch2_sb_features, - le64_to_cpu(sb->features[0])); - - bch2_flags_to_text(&PBUF(compat_features_str), - bch2_sb_compat, - le64_to_cpu(sb->compat[0])); - - vstruct_for_each(sb, f) - fields_have |= 1 << le32_to_cpu(f->type); - bch2_flags_to_text(&PBUF(fields_have_str), - bch2_sb_fields, fields_have); - - printf("External UUID: %s\n" - "Internal UUID: %s\n" - "Device index: %u\n" - "Label: %s\n" - "Version: %u\n" - "Oldest version on disk: %u\n" - "Created: %s\n" - "Squence number: %llu\n" - "Block_size: %s\n" - "Btree node size: %s\n" - "Error action: %s\n" - "Clean: %llu\n" - "Features: %s\n" - "Compat features: %s\n" - - "Metadata replicas: %llu\n" - "Data replicas: %llu\n" - - "Metadata checksum type: %s (%llu)\n" - "Data checksum type: %s (%llu)\n" - "Compression type: %s (%llu)\n" - - "Foreground write target: %s\n" - "Background write target: %s\n" - "Promote target: %s\n" - "Metadata target: %s\n" - - "String hash type: %s (%llu)\n" - "32 bit inodes: %llu\n" - "GC reserve percentage: %llu%%\n" - "Root reserve percentage: %llu%%\n" - - "Devices: %u live, %u total\n" - "Sections: %s\n" - "Superblock size: %llu\n", - user_uuid_str, - internal_uuid_str, - sb->dev_idx, - label, - le16_to_cpu(sb->version), - le16_to_cpu(sb->version_min), - time_str, - le64_to_cpu(sb->seq), - pr_units(le16_to_cpu(sb->block_size), units), - pr_units(BCH_SB_BTREE_NODE_SIZE(sb), units), - - BCH_SB_ERROR_ACTION(sb) < BCH_ON_ERROR_NR - ? bch2_error_actions[BCH_SB_ERROR_ACTION(sb)] - : "unknown", - - BCH_SB_CLEAN(sb), - features_str, - compat_features_str, - - BCH_SB_META_REPLICAS_WANT(sb), - BCH_SB_DATA_REPLICAS_WANT(sb), - - BCH_SB_META_CSUM_TYPE(sb) < BCH_CSUM_OPT_NR - ? bch2_csum_opts[BCH_SB_META_CSUM_TYPE(sb)] - : "unknown", - BCH_SB_META_CSUM_TYPE(sb), - - BCH_SB_DATA_CSUM_TYPE(sb) < BCH_CSUM_OPT_NR - ? bch2_csum_opts[BCH_SB_DATA_CSUM_TYPE(sb)] - : "unknown", - BCH_SB_DATA_CSUM_TYPE(sb), - - BCH_SB_COMPRESSION_TYPE(sb) < BCH_COMPRESSION_OPT_NR - ? bch2_compression_opts[BCH_SB_COMPRESSION_TYPE(sb)] - : "unknown", - BCH_SB_COMPRESSION_TYPE(sb), - - foreground_str, - background_str, - promote_str, - metadata_str, - - BCH_SB_STR_HASH_TYPE(sb) < BCH_STR_HASH_NR - ? bch2_str_hash_types[BCH_SB_STR_HASH_TYPE(sb)] - : "unknown", - BCH_SB_STR_HASH_TYPE(sb), - - BCH_SB_INODE_32BIT(sb), - BCH_SB_GC_RESERVE(sb), - BCH_SB_ROOT_RESERVE(sb), - - nr_devices, sb->nr_devices, - fields_have_str, - vstruct_bytes(sb)); - - if (print_layout) { - printf("\n" - "Layout:\n"); - bch2_sb_print_layout(sb, units); - } - - vstruct_for_each(sb, f) { - unsigned type = le32_to_cpu(f->type); - char name[60]; - - if (!(fields & (1 << type))) - continue; - - if (type < BCH_SB_FIELD_NR) { - scnprintf(name, sizeof(name), "%s", bch2_sb_fields[type]); - name[0] = toupper(name[0]); - } else { - scnprintf(name, sizeof(name), "(unknown field %u)", type); - } - - printf("\n%s (size %llu):\n", name, vstruct_bytes(f)); - if (type < BCH_SB_FIELD_NR) - bch2_sb_field_print(sb, f, units); - } -} - /* ioctl interface: */ /* Global control device: */ diff --git a/libbcachefs.h b/libbcachefs.h index ab4f0cd..3a83e16 100644 --- a/libbcachefs.h +++ b/libbcachefs.h @@ -79,8 +79,6 @@ struct bch_sb *bch2_format(struct bch_opt_strs, void bch2_super_write(int, struct bch_sb *); struct bch_sb *__bch2_super_read(int, u64); -void bch2_sb_print(struct bch_sb *, bool, unsigned, enum units); - /* ioctl interface: */ int bcachectl_open(void); diff --git a/libbcachefs/move.c b/libbcachefs/move.c index 7ca7ce3..16bca14 100644 --- a/libbcachefs/move.c +++ b/libbcachefs/move.c @@ -481,9 +481,7 @@ static void move_read_endio(struct bio *bio) atomic_sub(io->read_sectors, &ctxt->read_sectors); io->read_completed = true; - if (next_pending_write(ctxt)) - wake_up(&ctxt->wait); - + wake_up(&ctxt->wait); closure_put(&ctxt->cl); } diff --git a/libbcachefs/super-io.c b/libbcachefs/super-io.c index 08613a7..c22e2c0 100644 --- a/libbcachefs/super-io.c +++ b/libbcachefs/super-io.c @@ -1059,7 +1059,7 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, pr_buf(out, "Device: %u", i); pr_newline(out); - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); pr_buf(out, "UUID: "); pr_uuid(out, m->uuid.b); @@ -1127,7 +1127,7 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb, BCH_MEMBER_DISCARD(m)); pr_newline(out); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } } @@ -1468,9 +1468,9 @@ void bch2_sb_field_to_text(struct printbuf *out, struct bch_sb *sb, pr_newline(out); if (ops && ops->to_text) { - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); bch2_sb_field_ops[type]->to_text(out, sb, f); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } } @@ -1653,9 +1653,9 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb, pr_newline(out); pr_buf(out, "layout:"); pr_newline(out); - printbuf_indent_push(out, 2); + pr_indent_push(out, 2); bch2_sb_layout_to_text(out, &sb->layout); - printbuf_indent_pop(out, 2); + pr_indent_pop(out, 2); } vstruct_for_each(sb, f) diff --git a/libbcachefs/util.c b/libbcachefs/util.c index ab808fe..26d0ae3 100644 --- a/libbcachefs/util.c +++ b/libbcachefs/util.c @@ -117,17 +117,11 @@ void bch2_hprint(struct printbuf *buf, s64 v) if (u && t && v < 100 && v > -100) pr_buf(buf, ".%i", t / 103); if (u) - pr_buf(buf, "%c", si_units[u]); + pr_char(buf, si_units[u]); } void bch2_pr_units(struct printbuf *out, s64 raw, s64 bytes) { - if (raw < 0) { - pr_buf(out, "-"); - raw = -raw; - bytes = -bytes; - } - switch (out->units) { case PRINTBUF_UNITS_RAW: pr_buf(out, "%llu", raw); diff --git a/libbcachefs/util.h b/libbcachefs/util.h index b43c195..58d5570 100644 --- a/libbcachefs/util.h +++ b/libbcachefs/util.h @@ -244,8 +244,12 @@ enum printbuf_units { struct printbuf { char *pos; char *end; + char *last_newline; + char *last_field; unsigned indent; enum printbuf_units units; + unsigned tabstop; + unsigned tabstops[4]; }; static inline size_t printbuf_remaining(struct printbuf *buf) @@ -253,28 +257,44 @@ static inline size_t printbuf_remaining(struct printbuf *buf) return buf->end - buf->pos; } +static inline size_t printbuf_linelen(struct printbuf *buf) +{ + return buf->pos - buf->last_newline; +} + #define _PBUF(_buf, _len) \ ((struct printbuf) { \ - .pos = _buf, \ - .end = _buf + _len, \ + .pos = _buf, \ + .end = _buf + _len, \ + .last_newline = _buf, \ + .last_field = _buf, \ }) #define PBUF(_buf) _PBUF(_buf, sizeof(_buf)) + #define pr_buf(_out, ...) \ do { \ (_out)->pos += scnprintf((_out)->pos, printbuf_remaining(_out), \ __VA_ARGS__); \ } while (0) -static inline void printbuf_indent_push(struct printbuf *buf, unsigned spaces) +static inline void pr_char(struct printbuf *out, char c) +{ + if (printbuf_remaining(out) > 1) { + *out->pos = c; + out->pos++; + } +} + +static inline void pr_indent_push(struct printbuf *buf, unsigned spaces) { buf->indent += spaces; while (spaces--) - pr_buf(buf, " "); + pr_char(buf, ' '); } -static inline void printbuf_indent_pop(struct printbuf *buf, unsigned spaces) +static inline void pr_indent_pop(struct printbuf *buf, unsigned spaces) { buf->indent -= spaces; } @@ -283,14 +303,60 @@ static inline void pr_newline(struct printbuf *buf) { unsigned i; - pr_buf(buf, "\n"); + pr_char(buf, '\n'); + + buf->last_newline = buf->pos; + for (i = 0; i < buf->indent; i++) - pr_buf(buf, " "); + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop = 0; +} + +static inline void pr_tab(struct printbuf *buf) +{ + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + while (printbuf_remaining(buf) > 1 && + printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop++; +} + +static inline void pr_tab_rjust(struct printbuf *buf) +{ + ssize_t shift = min_t(ssize_t, buf->tabstops[buf->tabstop] - + printbuf_linelen(buf), + printbuf_remaining(buf)); + ssize_t move = min_t(ssize_t, buf->pos - buf->last_field, + printbuf_remaining(buf) - shift); + + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + if (shift > 0) { + memmove(buf->last_field + shift, + buf->last_field, + move); + memset(buf->last_field, ' ', shift); + buf->pos += shift; + *buf->pos = 0; + } + + buf->last_field = buf->pos; + buf->tabstop++; } void bch2_pr_units(struct printbuf *, s64, s64); #define pr_units(...) bch2_pr_units(__VA_ARGS__) +static inline void pr_sectors(struct printbuf *out, u64 v) +{ + bch2_pr_units(out, v, v << 9); +} + #ifdef __KERNEL__ static inline void pr_time(struct printbuf *out, u64 time) { diff --git a/tools-util.c b/tools-util.c index 9491779..621ab42 100644 --- a/tools-util.c +++ b/tools-util.c @@ -143,42 +143,6 @@ int printf_pad(unsigned pad, const char * fmt, ...) return ret; } -struct units_buf __pr_units(s64 _v, enum units units) -{ - struct units_buf ret; - char *out = ret.b, *end = out + sizeof(ret.b); - u64 v = _v; - - if (_v < 0) { - out += scnprintf(out, end - out, "-"); - v = -_v; - } - - switch (units) { - case BYTES: - snprintf(out, end - out, "%llu", v << 9); - break; - case SECTORS: - snprintf(out, end - out, "%llu", v); - break; - case HUMAN_READABLE: - v <<= 9; - - if (v >= 1024) { - int exp = log(v) / log(1024); - snprintf(out, end - out, "%.1f%c", - v / pow(1024, exp), - "KMGTPE"[exp-1]); - } else { - snprintf(out, end - out, "%llu", v); - } - - break; - } - - return ret; -} - /* Argument parsing stuff: */ /* File parsing (i.e. sysfs) */ diff --git a/tools-util.h b/tools-util.h index 9468f07..78827b8 100644 --- a/tools-util.h +++ b/tools-util.h @@ -55,20 +55,6 @@ struct stat xstat(const char *); int printf_pad(unsigned pad, const char * fmt, ...); -enum units { - BYTES, - SECTORS, - HUMAN_READABLE, -}; - -struct units_buf __pr_units(s64, enum units); - -struct units_buf { - char b[20]; -}; - -#define pr_units(_v, _u) &(__pr_units(_v, _u).b[0]) - char *read_file_str(int, const char *); u64 read_file_u64(int, const char *); -- 2.39.2