Update bcachefs sources to 9d554fa16d bcachefs: Add .to_text() methods for all superblock sections

This commit is contained in:
Kent Overstreet 2022-02-21 05:38:44 -05:00
parent f850624092
commit c06026ac54
19 changed files with 606 additions and 96 deletions

View File

@ -1 +1 @@
7d0925084b6927ad8c631bde92fb1c41cc6270c2
9d554fa16def4f6310d2df74092c5568419e69e3

View File

@ -794,7 +794,8 @@ static int push_invalidated_bucket(struct bch_fs *c, struct bch_dev *ca, u64 b)
static void discard_one_bucket(struct bch_fs *c, struct bch_dev *ca, u64 b)
{
if (ca->mi.discard &&
if (!c->opts.nochanges &&
ca->mi.discard &&
blk_queue_discard(bdev_get_queue(ca->disk_sb.bdev)))
blkdev_issue_discard(ca->disk_sb.bdev, bucket_to_sector(ca, b),
ca->mi.bucket_size, GFP_NOFS, 0);

View File

@ -122,9 +122,9 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c,
{
struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
bch_scnmemcpy(out, d.v->d_name,
bch2_dirent_name_bytes(d));
pr_buf(out, " -> %llu type %s",
pr_buf(out, "%.*s -> %llu type %s",
bch2_dirent_name_bytes(d),
d.v->d_name,
d.v->d_type != DT_SUBVOL
? le64_to_cpu(d.v->d_inum)
: le32_to_cpu(d.v->d_child_subvol),

View File

@ -76,8 +76,9 @@ static int bch2_sb_disk_groups_validate(struct bch_sb *sb,
for (g = sorted; g + 1 < sorted + nr_groups; g++)
if (!BCH_GROUP_DELETED(g) &&
!group_cmp(&g[0], &g[1])) {
pr_buf(err, "duplicate label %llu.", BCH_GROUP_PARENT(g));
bch_scnmemcpy(err, g->label, strnlen(g->label, sizeof(g->label)));
pr_buf(err, "duplicate label %llu.%.*s",
BCH_GROUP_PARENT(g),
(int) sizeof(g->label), g->label);
goto err;
}
@ -342,12 +343,10 @@ int bch2_disk_path_find_or_create(struct bch_sb_handle *sb, const char *name)
return v;
}
void bch2_disk_path_to_text(struct printbuf *out,
struct bch_sb_handle *sb,
unsigned v)
void bch2_disk_path_to_text(struct printbuf *out, struct bch_sb *sb, unsigned v)
{
struct bch_sb_field_disk_groups *groups =
bch2_sb_get_disk_groups(sb->sb);
bch2_sb_get_disk_groups(sb);
struct bch_disk_group *g;
unsigned nr = 0;
u16 path[32];
@ -376,15 +375,13 @@ void bch2_disk_path_to_text(struct printbuf *out,
v = path[--nr];
g = groups->entries + v;
bch_scnmemcpy(out, g->label,
strnlen(g->label, sizeof(g->label)));
pr_buf(out, "%.*s", (int) sizeof(g->label), g->label);
if (nr)
pr_buf(out, ".");
}
return;
inval:
pr_buf(out, "invalid group %u", v);
pr_buf(out, "invalid label %u", v);
}
int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
@ -448,6 +445,36 @@ int bch2_opt_target_parse(struct bch_fs *c, const char *buf, u64 *v)
return -EINVAL;
}
void bch2_sb_target_to_text(struct printbuf *out, struct bch_sb *sb, u64 v)
{
struct target t = target_decode(v);
switch (t.type) {
case TARGET_NULL:
pr_buf(out, "none");
break;
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)) {
pr_buf(out, "Device ");
pr_uuid(out, m->uuid.b);
pr_buf(out, " (%u)", t.dev);
} else {
pr_buf(out, "Bad device %u", t.dev);
}
break;
}
case TARGET_GROUP:
bch2_disk_path_to_text(out, sb, t.group);
break;
default:
BUG();
}
}
void bch2_opt_target_to_text(struct printbuf *out, struct bch_fs *c, u64 v)
{
struct target t = target_decode(v);
@ -481,7 +508,7 @@ void bch2_opt_target_to_text(struct printbuf *out, struct bch_fs *c, u64 v)
}
case TARGET_GROUP:
mutex_lock(&c->sb_lock);
bch2_disk_path_to_text(out, &c->disk_sb, t.group);
bch2_disk_path_to_text(out, c->disk_sb.sb, t.group);
mutex_unlock(&c->sb_lock);
break;
default:

View File

@ -75,8 +75,9 @@ int bch2_disk_path_find(struct bch_sb_handle *, const char *);
/* Exported for userspace bcachefs-tools: */
int bch2_disk_path_find_or_create(struct bch_sb_handle *, const char *);
void bch2_disk_path_to_text(struct printbuf *, struct bch_sb_handle *,
unsigned);
void bch2_disk_path_to_text(struct printbuf *, struct bch_sb *, unsigned);
void bch2_sb_target_to_text(struct printbuf *, struct bch_sb *, u64);
int bch2_opt_target_parse(struct bch_fs *, const char *, u64 *);
void bch2_opt_target_to_text(struct printbuf *, struct bch_fs *, u64);

View File

@ -954,15 +954,19 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
switch (__extent_entry_type(entry)) {
case BCH_EXTENT_ENTRY_ptr:
ptr = entry_to_ptr(entry);
ca = ptr->dev < c->sb.nr_devices && c->devs[ptr->dev]
? bch_dev_bkey_exists(c, ptr->dev)
: NULL;
pr_buf(out, "ptr: %u:%llu gen %u%s%s", ptr->dev,
pr_buf(out, "ptr: %u:%llu gen %u%s", ptr->dev,
(u64) ptr->offset, ptr->gen,
ptr->cached ? " cached" : "",
ca && ptr_stale(ca, ptr)
? " stale" : "");
ptr->cached ? " cached" : "");
if (c) {
ca = ptr->dev < c->sb.nr_devices && c->devs[ptr->dev]
? bch_dev_bkey_exists(c, ptr->dev)
: NULL;
if (ca && ptr_stale(ca, ptr))
pr_buf(out, " stale");
}
break;
case BCH_EXTENT_ENTRY_crc32:
case BCH_EXTENT_ENTRY_crc64:

View File

@ -303,7 +303,7 @@ static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs
vstruct_for_each(entry, k) {
if (!first) {
printbuf_newline(out);
pr_newline(out);
pr_buf(out, "%s: ", bch2_jset_entry_types[entry->type]);
}
pr_buf(out, "btree=%s l=%u ", bch2_btree_ids[entry->btree_id], entry->level);
@ -596,7 +596,7 @@ static void journal_entry_log_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
unsigned bytes = vstruct_bytes(entry) - offsetof(struct jset_entry_log, d);
bch_scnmemcpy(out, l->d, strnlen(l->d, bytes));
pr_buf(out, "%.*s", bytes, l->d);
}
struct jset_entry_ops {

View File

@ -286,7 +286,8 @@ void bch2_journal_do_discards(struct journal *j)
struct journal_device *ja = &ca->journal;
while (should_discard_bucket(j, ja)) {
if (ca->mi.discard &&
if (!c->opts.nochanges &&
ca->mi.discard &&
blk_queue_discard(bdev_get_queue(ca->disk_sb.bdev)))
blkdev_issue_discard(ca->disk_sb.bdev,
bucket_to_sector(ca,

View File

@ -235,6 +235,7 @@ static void bch2_sb_journal_seq_blacklist_to_text(struct printbuf *out,
le64_to_cpu(i->start),
le64_to_cpu(i->end));
}
pr_newline(out);
}
const struct bch_sb_field_ops bch_sb_field_ops_journal_seq_blacklist = {

View File

@ -6,7 +6,18 @@
#include "subvolume.h"
#include "super-io.h"
static int bch2_sb_validate_quota(struct bch_sb *sb, struct bch_sb_field *f,
static const char * const bch2_quota_types[] = {
"user",
"group",
"project",
};
static const char * const bch2_quota_counters[] = {
"space",
"inodes",
};
static int bch2_sb_quota_validate(struct bch_sb *sb, struct bch_sb_field *f,
struct printbuf *err)
{
struct bch_sb_field_quota *q = field_to_type(f, quota);
@ -14,13 +25,36 @@ static int bch2_sb_validate_quota(struct bch_sb *sb, struct bch_sb_field *f,
if (vstruct_bytes(&q->field) < sizeof(*q)) {
pr_buf(err, "wrong size (got %llu should be %zu)",
vstruct_bytes(&q->field), sizeof(*q));
return -EINVAL;
}
return 0;
}
static void bch2_sb_quota_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_quota *q = field_to_type(f, quota);
unsigned qtyp, counter;
for (qtyp = 0; qtyp < ARRAY_SIZE(q->q); qtyp++) {
pr_buf(out, "%s: flags %llx",
bch2_quota_types[qtyp],
le64_to_cpu(q->q[qtyp].flags));
for (counter = 0; counter < Q_COUNTERS; counter++)
pr_buf(out, " %s timelimit %u warnlimit %u",
bch2_quota_counters[counter],
le32_to_cpu(q->q[qtyp].c[counter].timelimit),
le32_to_cpu(q->q[qtyp].c[counter].warnlimit));
pr_newline(out);
}
}
const struct bch_sb_field_ops bch_sb_field_ops_quota = {
.validate = bch2_sb_validate_quota,
.validate = bch2_sb_quota_validate,
.to_text = bch2_sb_quota_to_text,
};
const char *bch2_quota_invalid(const struct bch_fs *c, struct bkey_s_c k)
@ -34,11 +68,6 @@ const char *bch2_quota_invalid(const struct bch_fs *c, struct bkey_s_c k)
return NULL;
}
static const char * const bch2_quota_counters[] = {
"space",
"inodes",
};
void bch2_quota_to_text(struct printbuf *out, struct bch_fs *c,
struct bkey_s_c k)
{

View File

@ -803,7 +803,7 @@ static struct bch_sb_field_clean *read_superblock_clean(struct bch_fs *c)
return ERR_PTR(-ENOMEM);
}
ret = bch2_sb_clean_validate(c, clean, READ);
ret = bch2_sb_clean_validate_late(c, clean, READ);
if (ret) {
mutex_unlock(&c->sb_lock);
return ERR_PTR(ret);

View File

@ -36,6 +36,22 @@ static void bch2_cpu_replicas_sort(struct bch_replicas_cpu *r)
eytzinger0_sort(r->entries, r->nr, r->entry_size, memcmp, NULL);
}
void bch2_replicas_entry_v0_to_text(struct printbuf *out,
struct bch_replicas_entry_v0 *e)
{
unsigned i;
if (e->data_type < BCH_DATA_NR)
pr_buf(out, "%s", bch2_data_types[e->data_type]);
else
pr_buf(out, "(invalid data type %u)", e->data_type);
pr_buf(out, ": %u [", e->nr_devs);
for (i = 0; i < e->nr_devs; i++)
pr_buf(out, i ? " %u" : "%u", e->devs[i]);
pr_buf(out, "]");
}
void bch2_replicas_entry_to_text(struct printbuf *out,
struct bch_replicas_entry *e)
{
@ -860,7 +876,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
return 0;
}
static int bch2_sb_validate_replicas(struct bch_sb *sb, struct bch_sb_field *f,
static int bch2_sb_replicas_validate(struct bch_sb *sb, struct bch_sb_field *f,
struct printbuf *err)
{
struct bch_sb_field_replicas *sb_r = field_to_type(f, replicas);
@ -890,14 +906,15 @@ static void bch2_sb_replicas_to_text(struct printbuf *out,
bch2_replicas_entry_to_text(out, e);
}
pr_newline(out);
}
const struct bch_sb_field_ops bch_sb_field_ops_replicas = {
.validate = bch2_sb_validate_replicas,
.validate = bch2_sb_replicas_validate,
.to_text = bch2_sb_replicas_to_text,
};
static int bch2_sb_validate_replicas_v0(struct bch_sb *sb, struct bch_sb_field *f,
static int bch2_sb_replicas_v0_validate(struct bch_sb *sb, struct bch_sb_field *f,
struct printbuf *err)
{
struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
@ -912,8 +929,27 @@ static int bch2_sb_validate_replicas_v0(struct bch_sb *sb, struct bch_sb_field *
return ret;
}
static void bch2_sb_replicas_v0_to_text(struct printbuf *out,
struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_replicas_v0 *sb_r = field_to_type(f, replicas_v0);
struct bch_replicas_entry_v0 *e;
bool first = true;
for_each_replicas_entry(sb_r, e) {
if (!first)
pr_buf(out, " ");
first = false;
bch2_replicas_entry_v0_to_text(out, e);
}
pr_newline(out);
}
const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0 = {
.validate = bch2_sb_validate_replicas_v0,
.validate = bch2_sb_replicas_v0_validate,
.to_text = bch2_sb_replicas_v0_to_text,
};
/* Query replicas: */
@ -970,19 +1006,42 @@ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs,
return ret;
}
unsigned bch2_sb_dev_has_data(struct bch_sb *sb, unsigned dev)
{
struct bch_sb_field_replicas *replicas;
struct bch_sb_field_replicas_v0 *replicas_v0;
unsigned i, data_has = 0;
replicas = bch2_sb_get_replicas(sb);
replicas_v0 = bch2_sb_get_replicas_v0(sb);
if (replicas) {
struct bch_replicas_entry *r;
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;
} else if (replicas_v0) {
struct bch_replicas_entry_v0 *r;
for_each_replicas_entry_v0(replicas_v0, r)
for (i = 0; i < r->nr_devs; i++)
if (r->devs[i] == dev)
data_has |= 1 << r->data_type;
}
return data_has;
}
unsigned bch2_dev_has_data(struct bch_fs *c, struct bch_dev *ca)
{
struct bch_replicas_entry *e;
unsigned i, ret = 0;
unsigned ret;
percpu_down_read(&c->mark_lock);
for_each_cpu_replicas_entry(&c->replicas, e)
for (i = 0; i < e->nr_devs; i++)
if (e->devs[i] == ca->dev_idx)
ret |= 1 << e->data_type;
percpu_up_read(&c->mark_lock);
mutex_lock(&c->sb_lock);
ret = bch2_sb_dev_has_data(c->disk_sb.sb, ca->dev_idx);
mutex_unlock(&c->sb_lock);
return ret;
}

View File

@ -64,6 +64,7 @@ static inline void bch2_replicas_entry_cached(struct bch_replicas_entry *e,
bool bch2_have_enough_devs(struct bch_fs *, struct bch_devs_mask,
unsigned, bool);
unsigned bch2_sb_dev_has_data(struct bch_sb *, unsigned);
unsigned bch2_dev_has_data(struct bch_fs *, struct bch_dev *);
int bch2_replicas_gc_end(struct bch_fs *, int);

View File

@ -918,7 +918,7 @@ static int u64_cmp(const void *_l, const void *_r)
return l < r ? -1 : l > r ? 1 : 0;
}
static int bch2_sb_validate_journal(struct bch_sb *sb,
static int bch2_sb_journal_validate(struct bch_sb *sb,
struct bch_sb_field *f,
struct printbuf *err)
{
@ -971,13 +971,26 @@ err:
return ret;
}
static void bch2_sb_journal_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_journal *journal = field_to_type(f, journal);
unsigned i, nr = bch2_nr_journal_buckets(journal);
pr_buf(out, "Buckets: ");
for (i = 0; i < nr; i++)
pr_buf(out, " %llu", le64_to_cpu(journal->buckets[i]));
pr_newline(out);
}
static const struct bch_sb_field_ops bch_sb_field_ops_journal = {
.validate = bch2_sb_validate_journal,
.validate = bch2_sb_journal_validate,
.to_text = bch2_sb_journal_to_text,
};
/* BCH_SB_FIELD_members: */
static int bch2_sb_validate_members(struct bch_sb *sb,
static int bch2_sb_members_validate(struct bch_sb *sb,
struct bch_sb_field *f,
struct printbuf *err)
{
@ -1027,13 +1040,105 @@ static int bch2_sb_validate_members(struct bch_sb *sb,
return 0;
}
static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
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;
unsigned data_have = bch2_sb_dev_has_data(sb, i);
u64 bucket_size = le16_to_cpu(m->bucket_size);
u64 device_size = le64_to_cpu(m->nbuckets) * bucket_size;
if (!bch2_member_exists(m))
continue;
pr_buf(out, "Device: %u", i);
pr_newline(out);
printbuf_indent_push(out, 2);
pr_buf(out, "UUID: ");
pr_uuid(out, m->uuid.b);
pr_newline(out);
pr_buf(out, "Size: ");
pr_units(out, device_size, device_size << 9);
pr_newline(out);
pr_buf(out, "Bucket size: ");
pr_units(out, bucket_size, bucket_size << 9);
pr_newline(out);
pr_buf(out, "First bucket: %u",
le16_to_cpu(m->first_bucket));
pr_newline(out);
pr_buf(out, "Buckets: %llu",
le64_to_cpu(m->nbuckets));
pr_newline(out);
pr_buf(out, "Last mount: ");
if (m->last_mount)
pr_time(out, le64_to_cpu(m->last_mount));
else
pr_buf(out, "(never)");
pr_newline(out);
pr_buf(out, "State: %s",
BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR
? bch2_member_states[BCH_MEMBER_STATE(m)]
: "unknown");
pr_newline(out);
pr_buf(out, "Group: ");
if (BCH_MEMBER_GROUP(m)) {
unsigned idx = BCH_MEMBER_GROUP(m) - 1;
if (idx < disk_groups_nr(gi))
pr_buf(out, "%s (%u)",
gi->entries[idx].label, idx);
else
pr_buf(out, "(bad disk labels section)");
} else {
pr_buf(out, "(none)");
}
pr_newline(out);
pr_buf(out, "Data allowed: ");
if (BCH_MEMBER_DATA_ALLOWED(m))
bch2_flags_to_text(out, bch2_data_types,
BCH_MEMBER_DATA_ALLOWED(m));
else
pr_buf(out, "(none)");
pr_newline(out);
pr_buf(out, "Has data: ");
if (data_have)
bch2_flags_to_text(out, bch2_data_types, data_have);
else
pr_buf(out, "(none)");
pr_newline(out);
pr_buf(out, "Discard: %llu",
BCH_MEMBER_DISCARD(m));
pr_newline(out);
printbuf_indent_pop(out, 2);
}
}
static const struct bch_sb_field_ops bch_sb_field_ops_members = {
.validate = bch2_sb_validate_members,
.validate = bch2_sb_members_validate,
.to_text = bch2_sb_members_to_text,
};
/* BCH_SB_FIELD_crypt: */
static int bch2_sb_validate_crypt(struct bch_sb *sb,
static int bch2_sb_crypt_validate(struct bch_sb *sb,
struct bch_sb_field *f,
struct printbuf *err)
{
@ -1053,13 +1158,29 @@ static int bch2_sb_validate_crypt(struct bch_sb *sb,
return 0;
}
static void bch2_sb_crypt_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_crypt *crypt = field_to_type(f, crypt);
pr_buf(out, "KFD: %llu", BCH_CRYPT_KDF_TYPE(crypt));
pr_newline(out);
pr_buf(out, "scrypt n: %llu", BCH_KDF_SCRYPT_N(crypt));
pr_newline(out);
pr_buf(out, "scrypt r: %llu", BCH_KDF_SCRYPT_R(crypt));
pr_newline(out);
pr_buf(out, "scrypt p: %llu", BCH_KDF_SCRYPT_P(crypt));
pr_newline(out);
}
static const struct bch_sb_field_ops bch_sb_field_ops_crypt = {
.validate = bch2_sb_validate_crypt,
.validate = bch2_sb_crypt_validate,
.to_text = bch2_sb_crypt_to_text,
};
/* BCH_SB_FIELD_clean: */
int bch2_sb_clean_validate(struct bch_fs *c, struct bch_sb_field_clean *clean, int write)
int bch2_sb_clean_validate_late(struct bch_fs *c, struct bch_sb_field_clean *clean, int write)
{
struct jset_entry *entry;
int ret;
@ -1248,7 +1369,7 @@ void bch2_fs_mark_clean(struct bch_fs *c)
* this should be in the write path, and we should be validating every
* superblock section:
*/
ret = bch2_sb_clean_validate(c, sb_clean, WRITE);
ret = bch2_sb_clean_validate_late(c, sb_clean, WRITE);
if (ret) {
bch_err(c, "error writing marking filesystem clean: validate error");
goto out;
@ -1259,7 +1380,7 @@ out:
mutex_unlock(&c->sb_lock);
}
static int bch2_sb_validate_clean(struct bch_sb *sb,
static int bch2_sb_clean_validate(struct bch_sb *sb,
struct bch_sb_field *f,
struct printbuf *err)
{
@ -1274,8 +1395,32 @@ static int bch2_sb_validate_clean(struct bch_sb *sb,
return 0;
}
static void bch2_sb_clean_to_text(struct printbuf *out, struct bch_sb *sb,
struct bch_sb_field *f)
{
struct bch_sb_field_clean *clean = field_to_type(f, clean);
struct jset_entry *entry;
pr_buf(out, "flags: %x", le32_to_cpu(clean->flags));
pr_newline(out);
pr_buf(out, "journal_seq: %llu", le64_to_cpu(clean->journal_seq));
pr_newline(out);
for (entry = clean->start;
entry != vstruct_end(&clean->field);
entry = vstruct_next(entry)) {
if (entry->type == BCH_JSET_ENTRY_btree_keys &&
!entry->u64s)
continue;
bch2_journal_entry_to_text(out, NULL, entry);
pr_newline(out);
}
}
static const struct bch_sb_field_ops bch_sb_field_ops_clean = {
.validate = bch2_sb_validate_clean,
.validate = bch2_sb_clean_validate,
.to_text = bch2_sb_clean_to_text,
};
static const struct bch_sb_field_ops *bch2_sb_field_ops[] = {
@ -1299,7 +1444,7 @@ static int bch2_sb_field_validate(struct bch_sb *sb, struct bch_sb_field *f,
ret = bch2_sb_field_ops[type]->validate(sb, f, &err);
if (ret) {
pr_buf(&err, "\n");
pr_newline(&err);
bch2_sb_field_to_text(&err, sb, f);
*orig_err = err;
}
@ -1320,7 +1465,202 @@ void bch2_sb_field_to_text(struct printbuf *out, struct bch_sb *sb,
pr_buf(out, "(unknown field %u)", type);
pr_buf(out, " (size %llu):", vstruct_bytes(f));
pr_newline(out);
if (ops && ops->to_text)
if (ops && ops->to_text) {
printbuf_indent_push(out, 2);
bch2_sb_field_ops[type]->to_text(out, sb, f);
printbuf_indent_pop(out, 2);
}
}
void bch2_sb_layout_to_text(struct printbuf *out, struct bch_sb_layout *l)
{
unsigned i;
pr_buf(out, "Type: %u", l->layout_type);
pr_newline(out);
pr_buf(out, "Superblock max size: ");
pr_units(out,
1 << l->sb_max_size_bits,
512 << l->sb_max_size_bits);
pr_newline(out);
pr_buf(out, "Nr superblocks: %u", l->nr_superblocks);
pr_newline(out);
pr_buf(out, "Offsets: ");
for (i = 0; i < l->nr_superblocks; i++) {
if (i)
pr_buf(out, ", ");
pr_buf(out, "%llu", le64_to_cpu(l->sb_offset[i]));
}
pr_newline(out);
}
void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
bool print_layout, unsigned fields)
{
struct bch_sb_field_members *mi;
struct bch_sb_field *f;
u64 fields_have = 0;
unsigned nr_devices = 0;
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);
}
pr_buf(out, "External UUID: ");
pr_uuid(out, sb->user_uuid.b);
pr_newline(out);
pr_buf(out, "Internal UUID: ");
pr_uuid(out, sb->uuid.b);
pr_newline(out);
pr_buf(out, "Device index: %u", sb->dev_idx);
pr_newline(out);
pr_buf(out, "Label: ");
pr_buf(out, "%.*s", (int) sizeof(sb->label), sb->label);
pr_newline(out);
pr_buf(out, "Version: %u", le16_to_cpu(sb->version));
pr_newline(out);
pr_buf(out, "Oldest version on disk: %u", le16_to_cpu(sb->version_min));
pr_newline(out);
pr_buf(out, "Created: ");
if (sb->time_base_lo)
pr_time(out, le64_to_cpu(sb->time_base_lo) / NSEC_PER_SEC);
else
pr_buf(out, "(not set)");
pr_newline(out);
pr_buf(out, "Squence number: %llu", le64_to_cpu(sb->seq));
pr_newline(out);
pr_buf(out, "Block_size: ");
pr_units(out, le16_to_cpu(sb->block_size),
(u32) le16_to_cpu(sb->block_size) << 9);
pr_newline(out);
pr_buf(out, "Btree node size: ");
pr_units(out, BCH_SB_BTREE_NODE_SIZE(sb),
BCH_SB_BTREE_NODE_SIZE(sb) << 9);
pr_newline(out);
pr_buf(out, "Error action: %s",
BCH_SB_ERROR_ACTION(sb) < BCH_ON_ERROR_NR
? bch2_error_actions[BCH_SB_ERROR_ACTION(sb)]
: "unknown");
pr_newline(out);
pr_buf(out, "Clean: %llu", BCH_SB_CLEAN(sb));
pr_newline(out);
pr_buf(out, "Features: ");
bch2_flags_to_text(out, bch2_sb_features,
le64_to_cpu(sb->features[0]));
pr_newline(out);
pr_buf(out, "Compat features: ");
bch2_flags_to_text(out, bch2_sb_compat,
le64_to_cpu(sb->compat[0]));
pr_newline(out);
pr_buf(out, "Metadata replicas: %llu", BCH_SB_META_REPLICAS_WANT(sb));
pr_newline(out);
pr_buf(out, "Data replicas: %llu", BCH_SB_DATA_REPLICAS_WANT(sb));
pr_newline(out);
pr_buf(out, "Metadata checksum type: %s (%llu)",
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));
pr_newline(out);
pr_buf(out, "Data checksum type: %s (%llu)",
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));
pr_newline(out);
pr_buf(out, "Compression type: %s (%llu)",
BCH_SB_COMPRESSION_TYPE(sb) < BCH_COMPRESSION_OPT_NR
? bch2_compression_opts[BCH_SB_COMPRESSION_TYPE(sb)]
: "unknown",
BCH_SB_COMPRESSION_TYPE(sb));
pr_newline(out);
pr_buf(out, "Foreground write target: ");
bch2_sb_target_to_text(out, sb, BCH_SB_FOREGROUND_TARGET(sb));
pr_newline(out);
pr_buf(out, "Background write target: ");
bch2_sb_target_to_text(out, sb, BCH_SB_BACKGROUND_TARGET(sb));
pr_newline(out);
pr_buf(out, "Promote target: ");
bch2_sb_target_to_text(out, sb, BCH_SB_PROMOTE_TARGET(sb));
pr_newline(out);
pr_buf(out, "Metadata target: ");
bch2_sb_target_to_text(out, sb, BCH_SB_METADATA_TARGET(sb));
pr_newline(out);
pr_buf(out, "String hash type: %s (%llu)",
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));
pr_newline(out);
pr_buf(out, "32 bit inodes: %llu", BCH_SB_INODE_32BIT(sb));
pr_newline(out);
pr_buf(out, "GC reserve percentage: %llu%%", BCH_SB_GC_RESERVE(sb));
pr_newline(out);
pr_buf(out, "Root reserve percentage: %llu%%", BCH_SB_ROOT_RESERVE(sb));
pr_newline(out);
pr_buf(out, "Devices: %u live, %u total",
nr_devices, sb->nr_devices);
pr_newline(out);
pr_buf(out, "Sections: ");
vstruct_for_each(sb, f)
fields_have |= 1 << le32_to_cpu(f->type);
bch2_flags_to_text(out, bch2_sb_fields, fields_have);
pr_newline(out);
pr_buf(out, "Superblock size: %llu", vstruct_bytes(sb));
pr_newline(out);
if (print_layout) {
pr_newline(out);
pr_buf(out, "layout:");
pr_newline(out);
printbuf_indent_push(out, 2);
bch2_sb_layout_to_text(out, &sb->layout);
printbuf_indent_pop(out, 2);
}
vstruct_for_each(sb, f)
if (fields & (1 << le32_to_cpu(f->type))) {
pr_newline(out);
bch2_sb_field_to_text(out, sb, f);
}
}

View File

@ -121,12 +121,14 @@ static inline struct bch_member_cpu bch2_mi_to_cpu(struct bch_member *mi)
void bch2_journal_super_entries_add_common(struct bch_fs *,
struct jset_entry **, u64);
int bch2_sb_clean_validate(struct bch_fs *, struct bch_sb_field_clean *, int);
int bch2_sb_clean_validate_late(struct bch_fs *, struct bch_sb_field_clean *, int);
int bch2_fs_mark_dirty(struct bch_fs *);
void bch2_fs_mark_clean(struct bch_fs *);
void bch2_sb_field_to_text(struct printbuf *, struct bch_sb *,
struct bch_sb_field *);
void bch2_sb_layout_to_text(struct printbuf *, struct bch_sb_layout *);
void bch2_sb_to_text(struct printbuf *, struct bch_sb *, bool, unsigned);
#endif /* _BCACHEFS_SUPER_IO_H */

View File

@ -825,7 +825,7 @@ SHOW(bch2_dev)
if (attr == &sysfs_label) {
if (ca->mi.group) {
mutex_lock(&c->sb_lock);
bch2_disk_path_to_text(&out, &c->disk_sb,
bch2_disk_path_to_text(&out, c->disk_sb.sb,
ca->mi.group - 1);
mutex_unlock(&c->sb_lock);
}

View File

@ -120,6 +120,27 @@ void bch2_hprint(struct printbuf *buf, s64 v)
pr_buf(buf, "%c", 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);
break;
case PRINTBUF_UNITS_BYTES:
pr_buf(out, "%llu", bytes);
break;
case PRINTBUF_UNITS_HUMAN_READABLE:
bch2_hprint(out, bytes);
break;
}
}
void bch2_string_opt_to_text(struct printbuf *out,
const char * const list[],
size_t selected)
@ -579,19 +600,6 @@ void memcpy_from_bio(void *dst, struct bio *src, struct bvec_iter src_iter)
}
}
void bch_scnmemcpy(struct printbuf *out,
const char *src, size_t len)
{
size_t n = printbuf_remaining(out);
if (n) {
n = min(n - 1, len);
memcpy(out->pos, src, n);
out->pos += n;
*out->pos = '\0';
}
}
#include "eytzinger.h"
static int alignment_ok(const void *base, size_t align)

View File

@ -235,10 +235,17 @@ do { \
#define ANYSINT_MAX(t) \
((((t) 1 << (sizeof(t) * 8 - 2)) - (t) 1) * (t) 2 + (t) 1)
enum printbuf_units {
PRINTBUF_UNITS_RAW,
PRINTBUF_UNITS_BYTES,
PRINTBUF_UNITS_HUMAN_READABLE,
};
struct printbuf {
char *pos;
char *end;
unsigned indent;
char *pos;
char *end;
unsigned indent;
enum printbuf_units units;
};
static inline size_t printbuf_remaining(struct printbuf *buf)
@ -272,7 +279,7 @@ static inline void printbuf_indent_pop(struct printbuf *buf, unsigned spaces)
buf->indent -= spaces;
}
static inline void printbuf_newline(struct printbuf *buf)
static inline void pr_newline(struct printbuf *buf)
{
unsigned i;
@ -281,7 +288,45 @@ static inline void printbuf_newline(struct printbuf *buf)
pr_buf(buf, " ");
}
void bch_scnmemcpy(struct printbuf *, const char *, size_t);
void bch2_pr_units(struct printbuf *, s64, s64);
#define pr_units(...) bch2_pr_units(__VA_ARGS__)
#ifdef __KERNEL__
static inline void pr_time(struct printbuf *out, u64 time)
{
pr_buf(out, "%llu", time);
}
#else
#include <time.h>
static inline void pr_time(struct printbuf *out, u64 _time)
{
char time_str[64];
time_t time = _time;
struct tm *tm = localtime(&time);
size_t err = strftime(time_str, sizeof(time_str), "%c", tm);
if (!err)
pr_buf(out, "(formatting error)");
else
pr_buf(out, "%s", time_str);
}
#endif
#ifdef __KERNEL__
static inline void uuid_unparse_lower(u8 *uuid, char *out)
{
sprintf(out, "%plU", uuid);
}
#else
#include <uuid/uuid.h>
#endif
static inline void pr_uuid(struct printbuf *out, u8 *uuid)
{
char uuid_str[40];
uuid_unparse_lower(uuid, uuid_str);
pr_buf(out, uuid_str);
}
int bch2_strtoint_h(const char *, int *);
int bch2_strtouint_h(const char *, unsigned int *);
@ -768,13 +813,4 @@ static inline int u8_cmp(u8 l, u8 r)
return cmp_int(l, r);
}
#ifdef __KERNEL__
static inline void uuid_unparse_lower(u8 *uuid, char *out)
{
sprintf(out, "%plU", uuid);
}
#else
#include <uuid/uuid.h>
#endif
#endif /* _BCACHEFS_UTIL_H */

View File

@ -111,11 +111,11 @@ void bch2_xattr_to_text(struct printbuf *out, struct bch_fs *c,
else
pr_buf(out, "(unknown type %u)", xattr.v->x_type);
bch_scnmemcpy(out, xattr.v->x_name,
xattr.v->x_name_len);
pr_buf(out, ":");
bch_scnmemcpy(out, xattr_val(xattr.v),
le16_to_cpu(xattr.v->x_val_len));
pr_buf(out, "%.*s:%.*s",
xattr.v->x_name_len,
xattr.v->x_name,
le16_to_cpu(xattr.v->x_val_len),
(char *) xattr_val(xattr.v));
}
static int bch2_xattr_get_trans(struct btree_trans *trans, struct bch_inode_info *inode,