mirror of
https://github.com/koverstreet/bcachefs-tools.git
synced 2025-02-23 00:00:02 +03:00
Update bcachefs sources to 9b3aa5ec6c bcachefs: Add tabstops to printbufs
This commit is contained in:
parent
c06026ac54
commit
5528e3ae62
@ -1 +1 @@
|
|||||||
9d554fa16def4f6310d2df74092c5568419e69e3
|
9b3aa5ec6cb7a3f12b9c683b4d28be2df0faa95c
|
||||||
|
@ -620,7 +620,7 @@ int cmd_list_journal(int argc, char *argv[])
|
|||||||
* log entries denote the start of a new transaction
|
* log entries denote the start of a new transaction
|
||||||
* commit:
|
* commit:
|
||||||
*/
|
*/
|
||||||
printbuf_indent_push(&buf,
|
pr_indent_push(&buf,
|
||||||
entry->type == BCH_JSET_ENTRY_log ? 2 : 4);
|
entry->type == BCH_JSET_ENTRY_log ? 2 : 4);
|
||||||
bch2_journal_entry_to_text(&buf, c, entry);
|
bch2_journal_entry_to_text(&buf, c, entry);
|
||||||
printf("%s\n", _buf);
|
printf("%s\n", _buf);
|
||||||
|
20
cmd_format.c
20
cmd_format.c
@ -236,8 +236,15 @@ int cmd_format(int argc, char *argv[])
|
|||||||
devices.item, darray_size(devices));
|
devices.item, darray_size(devices));
|
||||||
bch2_opt_strs_free(&fs_opt_strs);
|
bch2_opt_strs_free(&fs_opt_strs);
|
||||||
|
|
||||||
if (!quiet)
|
if (!quiet) {
|
||||||
bch2_sb_print(sb, false, 1 << BCH_SB_FIELD_members, HUMAN_READABLE);
|
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);
|
free(sb);
|
||||||
|
|
||||||
if (opts.passphrase) {
|
if (opts.passphrase) {
|
||||||
@ -325,7 +332,14 @@ int cmd_show_super(int argc, char *argv[])
|
|||||||
if (ret)
|
if (ret)
|
||||||
die("Error opening %s: %s", dev, strerror(-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);
|
bch2_free_super(&sb);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
220
cmd_fs.c
220
cmd_fs.c
@ -14,56 +14,90 @@
|
|||||||
#include "cmds.h"
|
#include "cmds.h"
|
||||||
#include "libbcachefs.h"
|
#include "libbcachefs.h"
|
||||||
|
|
||||||
static void print_dev_usage_type(const char *type,
|
static void dev_usage_type_to_text(struct printbuf *out,
|
||||||
unsigned bucket_size,
|
const char *type,
|
||||||
u64 buckets, u64 sectors,
|
unsigned bucket_size,
|
||||||
enum units units)
|
u64 buckets, u64 sectors)
|
||||||
{
|
{
|
||||||
u64 frag = max((s64) buckets * bucket_size - (s64) sectors, 0LL);
|
u64 frag = max((s64) buckets * bucket_size - (s64) sectors, 0LL);
|
||||||
|
|
||||||
printf_pad(20, " %s:", type);
|
pr_buf(out, "%s:", type);
|
||||||
printf(" %15s %15llu %15s\n",
|
pr_tab(out);
|
||||||
pr_units(sectors, units),
|
pr_sectors(out, sectors);
|
||||||
buckets,
|
pr_tab_rjust(out);
|
||||||
pr_units(frag, units));
|
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,
|
static void dev_usage_to_text(struct printbuf *out,
|
||||||
struct dev_name *d,
|
struct bchfs_handle fs,
|
||||||
enum units units)
|
struct dev_name *d)
|
||||||
{
|
{
|
||||||
struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, d->idx);
|
struct bch_ioctl_dev_usage u = bchu_dev_usage(fs, d->idx);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
printf("\n");
|
pr_newline(out);
|
||||||
printf_pad(20, "%s (device %u):", d->label ?: "(no label)", d->idx);
|
pr_buf(out, "%s (device %u):", d->label ?: "(no label)", d->idx);
|
||||||
printf("%30s%16s\n", d->dev ?: "(device not found)", bch2_member_states[u.state]);
|
pr_tab(out);
|
||||||
|
pr_buf(out, "%s", d->dev ?: "(device not found)");
|
||||||
|
pr_tab_rjust(out);
|
||||||
|
|
||||||
printf("%-20s%16s%16s%16s\n",
|
pr_buf(out, "%s", bch2_member_states[u.state]);
|
||||||
"", "data", "buckets", "fragmented");
|
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++)
|
for (i = BCH_DATA_sb; i < BCH_DATA_NR; i++)
|
||||||
print_dev_usage_type(bch2_data_types[i],
|
dev_usage_type_to_text(out,
|
||||||
u.bucket_size,
|
bch2_data_types[i],
|
||||||
u.buckets[i],
|
u.bucket_size,
|
||||||
u.sectors[i],
|
u.buckets[i],
|
||||||
units);
|
u.sectors[i]);
|
||||||
|
|
||||||
print_dev_usage_type("erasure coded",
|
dev_usage_type_to_text(out,
|
||||||
u.bucket_size,
|
"erasure coded",
|
||||||
u.ec_buckets,
|
u.bucket_size,
|
||||||
u.ec_sectors,
|
u.ec_buckets,
|
||||||
units);
|
u.ec_sectors);
|
||||||
|
|
||||||
printf_pad(20, " available:");
|
pr_buf(out, "available:");
|
||||||
printf(" %15s %15llu\n",
|
pr_tab(out);
|
||||||
pr_units(u.available_buckets * u.bucket_size, units),
|
|
||||||
u.available_buckets);
|
|
||||||
|
|
||||||
printf_pad(20, " capacity:");
|
pr_sectors(out, u.available_buckets * u.bucket_size);
|
||||||
printf(" %15s %15llu\n",
|
pr_tab_rjust(out);
|
||||||
pr_units(u.nr_buckets * u.bucket_size, units),
|
|
||||||
u.nr_buckets);
|
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)
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_replicas_usage(const struct bch_replicas_usage *r,
|
static void replicas_usage_to_text(struct printbuf *out,
|
||||||
dev_names *dev_names, enum units units)
|
const struct bch_replicas_usage *r,
|
||||||
|
dev_names *dev_names)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
@ -113,10 +148,18 @@ static void print_replicas_usage(const struct bch_replicas_usage *r,
|
|||||||
*d++ = ']';
|
*d++ = ']';
|
||||||
*d++ = '\0';
|
*d++ = '\0';
|
||||||
|
|
||||||
printf_pad(16, "%s: ", bch2_data_types[r->r.data_type]);
|
pr_buf(out, "%s: ", bch2_data_types[r->r.data_type]);
|
||||||
printf_pad(16, "%u/%u ", r->r.nr_required, r->r.nr_devs);
|
pr_tab(out);
|
||||||
printf_pad(32, "%s ", devs);
|
|
||||||
printf(" %s\n", pr_units(r->sectors, units));
|
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) \
|
#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), \
|
_r = replicas_usage_next(_r), \
|
||||||
BUG_ON((void *) _r > (void *) (_u)->replicas + (_u)->replica_entries_bytes))
|
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;
|
unsigned i;
|
||||||
char uuid[40];
|
|
||||||
|
|
||||||
struct bchfs_handle fs = bcache_fs_open(path);
|
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);
|
struct bch_ioctl_fs_usage *u = bchu_fs_usage(fs);
|
||||||
|
|
||||||
uuid_unparse(fs.uuid.b, uuid);
|
pr_buf(out, "Filesystem: ");
|
||||||
printf("Filesystem %s:\n", uuid);
|
pr_uuid(out, fs.uuid.b);
|
||||||
|
pr_newline(out);
|
||||||
|
|
||||||
printf("%-20s%12s\n", "Size:", pr_units(u->capacity, units));
|
out->tabstops[0] = 20;
|
||||||
printf("%-20s%12s\n", "Used:", pr_units(u->used, units));
|
out->tabstops[1] = 36;
|
||||||
|
|
||||||
printf("%-20s%12s\n", "Online reserved:", pr_units(u->online_reserved, units));
|
pr_buf(out, "Size:");
|
||||||
|
pr_tab(out);
|
||||||
|
pr_sectors(out, u->capacity);
|
||||||
|
pr_tab_rjust(out);
|
||||||
|
pr_newline(out);
|
||||||
|
|
||||||
printf("\n");
|
pr_buf(out, "Used:");
|
||||||
printf("%-16s%-16s%s\n", "Data type", "Required/total", "Devices");
|
pr_tab(out);
|
||||||
|
pr_sectors(out, u->used);
|
||||||
|
pr_tab_rjust(out);
|
||||||
|
pr_newline(out);
|
||||||
|
|
||||||
|
pr_buf(out, "Online reserved:");
|
||||||
|
pr_tab(out);
|
||||||
|
pr_sectors(out, u->online_reserved);
|
||||||
|
pr_tab_rjust(out);
|
||||||
|
pr_newline(out);
|
||||||
|
|
||||||
|
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++) {
|
for (i = 0; i < BCH_REPLICAS_MAX; i++) {
|
||||||
if (!u->persistent_reserved[i])
|
if (!u->persistent_reserved[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
printf_pad(16, "%s: ", "reserved");
|
pr_buf(out, "reserved:");
|
||||||
printf_pad(16, "%u/%u ", 1, i);
|
pr_tab(out);
|
||||||
printf_pad(32, "[] ");
|
pr_buf(out, "%u/%u ", 1, i);
|
||||||
printf("%s\n", pr_units(u->persistent_reserved[i], units));
|
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;
|
struct bch_replicas_usage *r;
|
||||||
|
|
||||||
for_each_usage_replica(u, r)
|
for_each_usage_replica(u, r)
|
||||||
if (r->r.data_type < BCH_DATA_user)
|
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)
|
for_each_usage_replica(u, r)
|
||||||
if (r->r.data_type == BCH_DATA_user &&
|
if (r->r.data_type == BCH_DATA_user &&
|
||||||
r->r.nr_required <= 1)
|
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)
|
for_each_usage_replica(u, r)
|
||||||
if (r->r.data_type == BCH_DATA_user &&
|
if (r->r.data_type == BCH_DATA_user &&
|
||||||
r->r.nr_required > 1)
|
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)
|
for_each_usage_replica(u, r)
|
||||||
if (r->r.data_type > BCH_DATA_user)
|
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);
|
free(u);
|
||||||
|
|
||||||
sort(&darray_item(dev_names, 0), darray_size(dev_names),
|
sort(&darray_item(dev_names, 0), darray_size(dev_names),
|
||||||
sizeof(darray_item(dev_names, 0)), dev_by_label_cmp, NULL);
|
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)
|
darray_foreach(dev, dev_names)
|
||||||
print_dev_usage(fs, dev, units);
|
dev_usage_to_text(out, fs, dev);
|
||||||
|
|
||||||
darray_foreach(dev, dev_names) {
|
darray_foreach(dev, dev_names) {
|
||||||
free(dev->dev);
|
free(dev->dev);
|
||||||
@ -209,23 +290,34 @@ int fs_usage(void)
|
|||||||
|
|
||||||
int cmd_fs_usage(int argc, char *argv[])
|
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;
|
char *fs;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "h")) != -1)
|
while ((opt = getopt(argc, argv, "h")) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'h':
|
case 'h':
|
||||||
units = HUMAN_READABLE;
|
units = PRINTBUF_UNITS_HUMAN_READABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
args_shift(optind);
|
args_shift(optind);
|
||||||
|
|
||||||
if (!argc) {
|
if (!argc) {
|
||||||
print_fs_usage(".", units);
|
buf = PBUF(_buf);
|
||||||
|
buf.units = units;
|
||||||
|
fs_usage_to_text(&buf, ".");
|
||||||
|
*buf.pos = 0;
|
||||||
|
printf("%s", _buf);
|
||||||
} else {
|
} else {
|
||||||
while ((fs = arg_pop()))
|
while ((fs = arg_pop())) {
|
||||||
print_fs_usage(fs, units);
|
buf = PBUF(_buf);
|
||||||
|
buf.units = units;
|
||||||
|
fs_usage_to_text(&buf, fs);
|
||||||
|
*buf.pos = 0;
|
||||||
|
printf("%s", _buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
497
libbcachefs.c
497
libbcachefs.c
@ -365,503 +365,6 @@ struct bch_sb *__bch2_super_read(int fd, u64 sector)
|
|||||||
return ret;
|
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: */
|
/* ioctl interface: */
|
||||||
|
|
||||||
/* Global control device: */
|
/* Global control device: */
|
||||||
|
@ -79,8 +79,6 @@ struct bch_sb *bch2_format(struct bch_opt_strs,
|
|||||||
void bch2_super_write(int, struct bch_sb *);
|
void bch2_super_write(int, struct bch_sb *);
|
||||||
struct bch_sb *__bch2_super_read(int, u64);
|
struct bch_sb *__bch2_super_read(int, u64);
|
||||||
|
|
||||||
void bch2_sb_print(struct bch_sb *, bool, unsigned, enum units);
|
|
||||||
|
|
||||||
/* ioctl interface: */
|
/* ioctl interface: */
|
||||||
|
|
||||||
int bcachectl_open(void);
|
int bcachectl_open(void);
|
||||||
|
@ -481,9 +481,7 @@ static void move_read_endio(struct bio *bio)
|
|||||||
atomic_sub(io->read_sectors, &ctxt->read_sectors);
|
atomic_sub(io->read_sectors, &ctxt->read_sectors);
|
||||||
io->read_completed = true;
|
io->read_completed = true;
|
||||||
|
|
||||||
if (next_pending_write(ctxt))
|
wake_up(&ctxt->wait);
|
||||||
wake_up(&ctxt->wait);
|
|
||||||
|
|
||||||
closure_put(&ctxt->cl);
|
closure_put(&ctxt->cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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_buf(out, "Device: %u", i);
|
||||||
pr_newline(out);
|
pr_newline(out);
|
||||||
|
|
||||||
printbuf_indent_push(out, 2);
|
pr_indent_push(out, 2);
|
||||||
|
|
||||||
pr_buf(out, "UUID: ");
|
pr_buf(out, "UUID: ");
|
||||||
pr_uuid(out, m->uuid.b);
|
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));
|
BCH_MEMBER_DISCARD(m));
|
||||||
pr_newline(out);
|
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);
|
pr_newline(out);
|
||||||
|
|
||||||
if (ops && ops->to_text) {
|
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);
|
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_newline(out);
|
||||||
pr_buf(out, "layout:");
|
pr_buf(out, "layout:");
|
||||||
pr_newline(out);
|
pr_newline(out);
|
||||||
printbuf_indent_push(out, 2);
|
pr_indent_push(out, 2);
|
||||||
bch2_sb_layout_to_text(out, &sb->layout);
|
bch2_sb_layout_to_text(out, &sb->layout);
|
||||||
printbuf_indent_pop(out, 2);
|
pr_indent_pop(out, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
vstruct_for_each(sb, f)
|
vstruct_for_each(sb, f)
|
||||||
|
@ -117,17 +117,11 @@ void bch2_hprint(struct printbuf *buf, s64 v)
|
|||||||
if (u && t && v < 100 && v > -100)
|
if (u && t && v < 100 && v > -100)
|
||||||
pr_buf(buf, ".%i", t / 103);
|
pr_buf(buf, ".%i", t / 103);
|
||||||
if (u)
|
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)
|
void bch2_pr_units(struct printbuf *out, s64 raw, s64 bytes)
|
||||||
{
|
{
|
||||||
if (raw < 0) {
|
|
||||||
pr_buf(out, "-");
|
|
||||||
raw = -raw;
|
|
||||||
bytes = -bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (out->units) {
|
switch (out->units) {
|
||||||
case PRINTBUF_UNITS_RAW:
|
case PRINTBUF_UNITS_RAW:
|
||||||
pr_buf(out, "%llu", raw);
|
pr_buf(out, "%llu", raw);
|
||||||
|
@ -244,8 +244,12 @@ enum printbuf_units {
|
|||||||
struct printbuf {
|
struct printbuf {
|
||||||
char *pos;
|
char *pos;
|
||||||
char *end;
|
char *end;
|
||||||
|
char *last_newline;
|
||||||
|
char *last_field;
|
||||||
unsigned indent;
|
unsigned indent;
|
||||||
enum printbuf_units units;
|
enum printbuf_units units;
|
||||||
|
unsigned tabstop;
|
||||||
|
unsigned tabstops[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline size_t printbuf_remaining(struct printbuf *buf)
|
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;
|
return buf->end - buf->pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t printbuf_linelen(struct printbuf *buf)
|
||||||
|
{
|
||||||
|
return buf->pos - buf->last_newline;
|
||||||
|
}
|
||||||
|
|
||||||
#define _PBUF(_buf, _len) \
|
#define _PBUF(_buf, _len) \
|
||||||
((struct printbuf) { \
|
((struct printbuf) { \
|
||||||
.pos = _buf, \
|
.pos = _buf, \
|
||||||
.end = _buf + _len, \
|
.end = _buf + _len, \
|
||||||
|
.last_newline = _buf, \
|
||||||
|
.last_field = _buf, \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define PBUF(_buf) _PBUF(_buf, sizeof(_buf))
|
#define PBUF(_buf) _PBUF(_buf, sizeof(_buf))
|
||||||
|
|
||||||
|
|
||||||
#define pr_buf(_out, ...) \
|
#define pr_buf(_out, ...) \
|
||||||
do { \
|
do { \
|
||||||
(_out)->pos += scnprintf((_out)->pos, printbuf_remaining(_out), \
|
(_out)->pos += scnprintf((_out)->pos, printbuf_remaining(_out), \
|
||||||
__VA_ARGS__); \
|
__VA_ARGS__); \
|
||||||
} while (0)
|
} 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;
|
buf->indent += spaces;
|
||||||
while (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;
|
buf->indent -= spaces;
|
||||||
}
|
}
|
||||||
@ -283,14 +303,60 @@ static inline void pr_newline(struct printbuf *buf)
|
|||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
pr_buf(buf, "\n");
|
pr_char(buf, '\n');
|
||||||
|
|
||||||
|
buf->last_newline = buf->pos;
|
||||||
|
|
||||||
for (i = 0; i < buf->indent; i++)
|
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);
|
void bch2_pr_units(struct printbuf *, s64, s64);
|
||||||
#define pr_units(...) bch2_pr_units(__VA_ARGS__)
|
#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__
|
#ifdef __KERNEL__
|
||||||
static inline void pr_time(struct printbuf *out, u64 time)
|
static inline void pr_time(struct printbuf *out, u64 time)
|
||||||
{
|
{
|
||||||
|
36
tools-util.c
36
tools-util.c
@ -143,42 +143,6 @@ int printf_pad(unsigned pad, const char * fmt, ...)
|
|||||||
return ret;
|
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: */
|
/* Argument parsing stuff: */
|
||||||
|
|
||||||
/* File parsing (i.e. sysfs) */
|
/* File parsing (i.e. sysfs) */
|
||||||
|
14
tools-util.h
14
tools-util.h
@ -55,20 +55,6 @@ struct stat xstat(const char *);
|
|||||||
|
|
||||||
int printf_pad(unsigned pad, const char * fmt, ...);
|
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 *);
|
char *read_file_str(int, const char *);
|
||||||
u64 read_file_u64(int, const char *);
|
u64 read_file_u64(int, const char *);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user