mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 02:36:02 +00:00
bcachefs: Printbuf rework
This converts bcachefs to the modern printbuf interface/implementation, synced with the version to be submitted upstream. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
652018d661
commit
401ec4db63
@ -47,6 +47,7 @@ bcachefs-y := \
|
||||
move.o \
|
||||
movinggc.o \
|
||||
opts.o \
|
||||
printbuf.o \
|
||||
quota.o \
|
||||
rebalance.o \
|
||||
recovery.o \
|
||||
|
@ -300,7 +300,7 @@ int bch2_alloc_v1_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
/* allow for unknown fields */
|
||||
if (bkey_val_u64s(a.k) < bch_alloc_v1_val_u64s(a.v)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %u)",
|
||||
prt_printf(err, "incorrect value size (%zu < %u)",
|
||||
bkey_val_u64s(a.k), bch_alloc_v1_val_u64s(a.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -314,7 +314,7 @@ int bch2_alloc_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_alloc_unpacked u;
|
||||
|
||||
if (bch2_alloc_unpack_v2(&u, k)) {
|
||||
pr_buf(err, "unpack error");
|
||||
prt_printf(err, "unpack error");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -327,7 +327,7 @@ int bch2_alloc_v3_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_alloc_unpacked u;
|
||||
|
||||
if (bch2_alloc_unpack_v3(&u, k)) {
|
||||
pr_buf(err, "unpack error");
|
||||
prt_printf(err, "unpack error");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -340,14 +340,14 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_alloc_v4 a = bkey_s_c_to_alloc_v4(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_alloc_v4)) {
|
||||
pr_buf(err, "bad val size (%zu != %zu)",
|
||||
prt_printf(err, "bad val size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_alloc_v4));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rw == WRITE) {
|
||||
if (alloc_data_type(*a.v, a.v->data_type) != a.v->data_type) {
|
||||
pr_buf(err, "invalid data type (got %u should be %u)",
|
||||
prt_printf(err, "invalid data type (got %u should be %u)",
|
||||
a.v->data_type, alloc_data_type(*a.v, a.v->data_type));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -359,7 +359,7 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
if (a.v->dirty_sectors ||
|
||||
a.v->cached_sectors ||
|
||||
a.v->stripe) {
|
||||
pr_buf(err, "empty data type free but have data");
|
||||
prt_printf(err, "empty data type free but have data");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
@ -369,7 +369,7 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
case BCH_DATA_user:
|
||||
case BCH_DATA_parity:
|
||||
if (!a.v->dirty_sectors) {
|
||||
pr_buf(err, "data_type %s but dirty_sectors==0",
|
||||
prt_printf(err, "data_type %s but dirty_sectors==0",
|
||||
bch2_data_types[a.v->data_type]);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -378,19 +378,19 @@ int bch2_alloc_v4_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
if (!a.v->cached_sectors ||
|
||||
a.v->dirty_sectors ||
|
||||
a.v->stripe) {
|
||||
pr_buf(err, "data type inconsistency");
|
||||
prt_printf(err, "data type inconsistency");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!a.v->io_time[READ] &&
|
||||
test_bit(BCH_FS_CHECK_ALLOC_TO_LRU_REFS_DONE, &c->flags)) {
|
||||
pr_buf(err, "cached bucket with read_time == 0");
|
||||
prt_printf(err, "cached bucket with read_time == 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
case BCH_DATA_stripe:
|
||||
if (!a.v->stripe) {
|
||||
pr_buf(err, "data_type %s but stripe==0",
|
||||
prt_printf(err, "data_type %s but stripe==0",
|
||||
bch2_data_types[a.v->data_type]);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -421,17 +421,17 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
|
||||
|
||||
bch2_alloc_to_v4(k, &a);
|
||||
|
||||
pr_buf(out, "gen %u oldest_gen %u data_type %s journal_seq %llu need_discard %llu need_inc_gen %llu",
|
||||
prt_printf(out, "gen %u oldest_gen %u data_type %s journal_seq %llu need_discard %llu need_inc_gen %llu",
|
||||
a.gen, a.oldest_gen, bch2_data_types[a.data_type],
|
||||
a.journal_seq,
|
||||
BCH_ALLOC_V4_NEED_DISCARD(&a),
|
||||
BCH_ALLOC_V4_NEED_INC_GEN(&a));
|
||||
pr_buf(out, " dirty_sectors %u", a.dirty_sectors);
|
||||
pr_buf(out, " cached_sectors %u", a.cached_sectors);
|
||||
pr_buf(out, " stripe %u", a.stripe);
|
||||
pr_buf(out, " stripe_redundancy %u", a.stripe_redundancy);
|
||||
pr_buf(out, " read_time %llu", a.io_time[READ]);
|
||||
pr_buf(out, " write_time %llu", a.io_time[WRITE]);
|
||||
prt_printf(out, " dirty_sectors %u", a.dirty_sectors);
|
||||
prt_printf(out, " cached_sectors %u", a.cached_sectors);
|
||||
prt_printf(out, " stripe %u", a.stripe);
|
||||
prt_printf(out, " stripe_redundancy %u", a.stripe_redundancy);
|
||||
prt_printf(out, " read_time %llu", a.io_time[READ]);
|
||||
prt_printf(out, " write_time %llu", a.io_time[WRITE]);
|
||||
}
|
||||
|
||||
int bch2_alloc_read(struct bch_fs *c)
|
||||
@ -1098,7 +1098,7 @@ static int invalidate_one_bucket(struct btree_trans *trans, struct bch_dev *ca)
|
||||
goto out;
|
||||
|
||||
if (k.k->type != KEY_TYPE_lru) {
|
||||
pr_buf(&buf, "non lru key in lru btree:\n ");
|
||||
prt_printf(&buf, "non lru key in lru btree:\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
|
||||
if (!test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) {
|
||||
@ -1122,9 +1122,9 @@ static int invalidate_one_bucket(struct btree_trans *trans, struct bch_dev *ca)
|
||||
goto out;
|
||||
|
||||
if (idx != alloc_lru_idx(a->v)) {
|
||||
pr_buf(&buf, "alloc key does not point back to lru entry when invalidating bucket:\n ");
|
||||
prt_printf(&buf, "alloc key does not point back to lru entry when invalidating bucket:\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&a->k_i));
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
|
||||
if (!test_bit(BCH_FS_CHECK_LRUS_DONE, &c->flags)) {
|
||||
|
@ -299,7 +299,7 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
int ret;
|
||||
|
||||
if (b < ca->mi.first_bucket || b >= ca->mi.nbuckets) {
|
||||
pr_buf(&buf, "freespace btree has bucket outside allowed range %u-%llu\n"
|
||||
prt_printf(&buf, "freespace btree has bucket outside allowed range %u-%llu\n"
|
||||
" freespace key ",
|
||||
ca->mi.first_bucket, ca->mi.nbuckets);
|
||||
bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
@ -319,11 +319,11 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
bch2_alloc_to_v4(k, &a);
|
||||
|
||||
if (genbits != (alloc_freespace_genbits(a) >> 56)) {
|
||||
pr_buf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
|
||||
prt_printf(&buf, "bucket in freespace btree with wrong genbits (got %u should be %llu)\n"
|
||||
" freespace key ",
|
||||
genbits, alloc_freespace_genbits(a) >> 56);
|
||||
bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
ob = ERR_PTR(-EIO);
|
||||
@ -332,10 +332,10 @@ static struct open_bucket *try_alloc_bucket(struct btree_trans *trans, struct bc
|
||||
}
|
||||
|
||||
if (a.data_type != BCH_DATA_free) {
|
||||
pr_buf(&buf, "non free bucket in freespace btree\n"
|
||||
prt_printf(&buf, "non free bucket in freespace btree\n"
|
||||
" freespace key ");
|
||||
bch2_bkey_val_to_text(&buf, c, freespace_k);
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
bch2_trans_inconsistent(trans, "%s", buf.buf);
|
||||
ob = ERR_PTR(-EIO);
|
||||
@ -1381,7 +1381,7 @@ void bch2_open_buckets_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
ob++) {
|
||||
spin_lock(&ob->lock);
|
||||
if (ob->valid && !ob->on_partial_list) {
|
||||
pr_buf(out, "%zu ref %u type %s %u:%llu:%u\n",
|
||||
prt_printf(out, "%zu ref %u type %s %u:%llu:%u\n",
|
||||
ob - c->open_buckets,
|
||||
atomic_read(&ob->pin),
|
||||
bch2_data_types[ob->data_type],
|
||||
@ -1406,17 +1406,17 @@ void bch2_write_points_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
for (wp = c->write_points;
|
||||
wp < c->write_points + ARRAY_SIZE(c->write_points);
|
||||
wp++) {
|
||||
pr_buf(out, "%lu: ", wp->write_point);
|
||||
bch2_hprint(out, wp->sectors_allocated);
|
||||
prt_printf(out, "%lu: ", wp->write_point);
|
||||
prt_human_readable_u64(out, wp->sectors_allocated);
|
||||
|
||||
pr_buf(out, " last wrote: ");
|
||||
prt_printf(out, " last wrote: ");
|
||||
bch2_pr_time_units(out, sched_clock() - wp->last_used);
|
||||
|
||||
for (i = 0; i < WRITE_POINT_STATE_NR; i++) {
|
||||
pr_buf(out, " %s: ", bch2_write_point_states[i]);
|
||||
prt_printf(out, " %s: ", bch2_write_point_states[i]);
|
||||
bch2_pr_time_units(out, wp->time[i]);
|
||||
}
|
||||
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ static int empty_val_key_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (bkey_val_bytes(k.k)) {
|
||||
pr_buf(err, "incorrect value size (%zu != 0)",
|
||||
prt_printf(err, "incorrect value size (%zu != 0)",
|
||||
bkey_val_bytes(k.k));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -56,7 +56,7 @@ static int key_type_cookie_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_cookie)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_cookie));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -84,7 +84,7 @@ static void key_type_inline_data_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct bkey_s_c_inline_data d = bkey_s_c_to_inline_data(k);
|
||||
unsigned datalen = bkey_inline_data_bytes(k.k);
|
||||
|
||||
pr_buf(out, "datalen %u: %*phN",
|
||||
prt_printf(out, "datalen %u: %*phN",
|
||||
datalen, min(datalen, 32U), d.v->data);
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ static int key_type_set_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (bkey_val_bytes(k.k)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_cookie));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -126,7 +126,7 @@ int bch2_bkey_val_invalid(struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (k.k->type >= KEY_TYPE_MAX) {
|
||||
pr_buf(err, "invalid type (%u >= %u)", k.k->type, KEY_TYPE_MAX);
|
||||
prt_printf(err, "invalid type (%u >= %u)", k.k->type, KEY_TYPE_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -202,30 +202,30 @@ int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (k.k->u64s < BKEY_U64s) {
|
||||
pr_buf(err, "u64s too small (%u < %zu)", k.k->u64s, BKEY_U64s);
|
||||
prt_printf(err, "u64s too small (%u < %zu)", k.k->u64s, BKEY_U64s);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(bch2_key_types_allowed[type] & (1U << k.k->type))) {
|
||||
pr_buf(err, "invalid key type for this btree (%s)",
|
||||
prt_printf(err, "invalid key type for this btree (%s)",
|
||||
bch2_bkey_types[type]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (btree_node_type_is_extents(type) && !bkey_whiteout(k.k)) {
|
||||
if (k.k->size == 0) {
|
||||
pr_buf(err, "size == 0");
|
||||
prt_printf(err, "size == 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k.k->size > k.k->p.offset) {
|
||||
pr_buf(err, "size greater than offset (%u > %llu)",
|
||||
prt_printf(err, "size greater than offset (%u > %llu)",
|
||||
k.k->size, k.k->p.offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (k.k->size) {
|
||||
pr_buf(err, "size != 0");
|
||||
prt_printf(err, "size != 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -233,20 +233,20 @@ int __bch2_bkey_invalid(struct bch_fs *c, struct bkey_s_c k,
|
||||
if (type != BKEY_TYPE_btree &&
|
||||
!btree_type_has_snapshots(type) &&
|
||||
k.k->p.snapshot) {
|
||||
pr_buf(err, "nonzero snapshot");
|
||||
prt_printf(err, "nonzero snapshot");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type != BKEY_TYPE_btree &&
|
||||
btree_type_has_snapshots(type) &&
|
||||
!k.k->p.snapshot) {
|
||||
pr_buf(err, "snapshot == 0");
|
||||
prt_printf(err, "snapshot == 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type != BKEY_TYPE_btree &&
|
||||
!bkey_cmp(k.k->p, POS_MAX)) {
|
||||
pr_buf(err, "key at POS_MAX");
|
||||
prt_printf(err, "key at POS_MAX");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -265,12 +265,12 @@ int bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k,
|
||||
struct printbuf *err)
|
||||
{
|
||||
if (bpos_cmp(k.k->p, b->data->min_key) < 0) {
|
||||
pr_buf(err, "key before start of btree node");
|
||||
prt_printf(err, "key before start of btree node");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bpos_cmp(k.k->p, b->data->max_key) > 0) {
|
||||
pr_buf(err, "key past end of btree node");
|
||||
prt_printf(err, "key past end of btree node");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -280,44 +280,44 @@ int bch2_bkey_in_btree_node(struct btree *b, struct bkey_s_c k,
|
||||
void bch2_bpos_to_text(struct printbuf *out, struct bpos pos)
|
||||
{
|
||||
if (!bpos_cmp(pos, POS_MIN))
|
||||
pr_buf(out, "POS_MIN");
|
||||
prt_printf(out, "POS_MIN");
|
||||
else if (!bpos_cmp(pos, POS_MAX))
|
||||
pr_buf(out, "POS_MAX");
|
||||
prt_printf(out, "POS_MAX");
|
||||
else if (!bpos_cmp(pos, SPOS_MAX))
|
||||
pr_buf(out, "SPOS_MAX");
|
||||
prt_printf(out, "SPOS_MAX");
|
||||
else {
|
||||
if (pos.inode == U64_MAX)
|
||||
pr_buf(out, "U64_MAX");
|
||||
prt_printf(out, "U64_MAX");
|
||||
else
|
||||
pr_buf(out, "%llu", pos.inode);
|
||||
pr_buf(out, ":");
|
||||
prt_printf(out, "%llu", pos.inode);
|
||||
prt_printf(out, ":");
|
||||
if (pos.offset == U64_MAX)
|
||||
pr_buf(out, "U64_MAX");
|
||||
prt_printf(out, "U64_MAX");
|
||||
else
|
||||
pr_buf(out, "%llu", pos.offset);
|
||||
pr_buf(out, ":");
|
||||
prt_printf(out, "%llu", pos.offset);
|
||||
prt_printf(out, ":");
|
||||
if (pos.snapshot == U32_MAX)
|
||||
pr_buf(out, "U32_MAX");
|
||||
prt_printf(out, "U32_MAX");
|
||||
else
|
||||
pr_buf(out, "%u", pos.snapshot);
|
||||
prt_printf(out, "%u", pos.snapshot);
|
||||
}
|
||||
}
|
||||
|
||||
void bch2_bkey_to_text(struct printbuf *out, const struct bkey *k)
|
||||
{
|
||||
if (k) {
|
||||
pr_buf(out, "u64s %u type ", k->u64s);
|
||||
prt_printf(out, "u64s %u type ", k->u64s);
|
||||
|
||||
if (k->type < KEY_TYPE_MAX)
|
||||
pr_buf(out, "%s ", bch2_bkey_types[k->type]);
|
||||
prt_printf(out, "%s ", bch2_bkey_types[k->type]);
|
||||
else
|
||||
pr_buf(out, "%u ", k->type);
|
||||
prt_printf(out, "%u ", k->type);
|
||||
|
||||
bch2_bpos_to_text(out, k->p);
|
||||
|
||||
pr_buf(out, " len %u ver %llu", k->size, k->version.lo);
|
||||
prt_printf(out, " len %u ver %llu", k->size, k->version.lo);
|
||||
} else {
|
||||
pr_buf(out, "(null)");
|
||||
prt_printf(out, "(null)");
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,7 +330,7 @@ void bch2_val_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
if (likely(ops->val_to_text))
|
||||
ops->val_to_text(out, c, k);
|
||||
} else {
|
||||
pr_buf(out, "(invalid type %u)", k.k->type);
|
||||
prt_printf(out, "(invalid type %u)", k.k->type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -340,7 +340,7 @@ void bch2_bkey_val_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
bch2_bkey_to_text(out, k.k);
|
||||
|
||||
if (bkey_val_bytes(k.k)) {
|
||||
pr_buf(out, ": ");
|
||||
prt_printf(out, ": ");
|
||||
bch2_val_to_text(out, c, k);
|
||||
}
|
||||
}
|
||||
|
@ -1575,12 +1575,12 @@ void bch2_bfloat_to_text(struct printbuf *out, struct btree *b,
|
||||
switch (bkey_float(b, t, j)->exponent) {
|
||||
case BFLOAT_FAILED:
|
||||
uk = bkey_unpack_key(b, k);
|
||||
pr_buf(out,
|
||||
prt_printf(out,
|
||||
" failed unpacked at depth %u\n"
|
||||
"\t",
|
||||
ilog2(j));
|
||||
bch2_bpos_to_text(out, uk.p);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -772,20 +772,20 @@ static noinline void btree_bad_header(struct bch_fs *c, struct btree *b)
|
||||
if (!test_bit(BCH_FS_INITIAL_GC_DONE, &c->flags))
|
||||
return;
|
||||
|
||||
pr_buf(&buf,
|
||||
prt_printf(&buf,
|
||||
"btree node header doesn't match ptr\n"
|
||||
"btree %s level %u\n"
|
||||
"ptr: ",
|
||||
bch2_btree_ids[b->c.btree_id], b->c.level);
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
pr_buf(&buf, "\nheader: btree %s level %llu\n"
|
||||
prt_printf(&buf, "\nheader: btree %s level %llu\n"
|
||||
"min ",
|
||||
bch2_btree_ids[BTREE_NODE_ID(b->data)],
|
||||
BTREE_NODE_LEVEL(b->data));
|
||||
bch2_bpos_to_text(&buf, b->data->min_key);
|
||||
|
||||
pr_buf(&buf, "\nmax ");
|
||||
prt_printf(&buf, "\nmax ");
|
||||
bch2_bpos_to_text(&buf, b->data->max_key);
|
||||
|
||||
bch2_fs_inconsistent(c, "%s", buf.buf);
|
||||
@ -1108,15 +1108,15 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
|
||||
bch2_btree_keys_stats(b, &stats);
|
||||
|
||||
pr_buf(out, "l %u ", b->c.level);
|
||||
prt_printf(out, "l %u ", b->c.level);
|
||||
bch2_bpos_to_text(out, b->data->min_key);
|
||||
pr_buf(out, " - ");
|
||||
prt_printf(out, " - ");
|
||||
bch2_bpos_to_text(out, b->data->max_key);
|
||||
pr_buf(out, ":\n"
|
||||
prt_printf(out, ":\n"
|
||||
" ptrs: ");
|
||||
bch2_val_to_text(out, c, bkey_i_to_s_c(&b->key));
|
||||
|
||||
pr_buf(out, "\n"
|
||||
prt_printf(out, "\n"
|
||||
" format: u64s %u fields %u %u %u %u %u\n"
|
||||
" unpack fn len: %u\n"
|
||||
" bytes used %zu/%zu (%zu%% full)\n"
|
||||
@ -1146,7 +1146,7 @@ void bch2_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
|
||||
void bch2_btree_cache_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
{
|
||||
pr_buf(out, "nr nodes:\t\t%u\n", c->btree_cache.used);
|
||||
pr_buf(out, "nr dirty:\t\t%u\n", atomic_read(&c->btree_cache.dirty));
|
||||
pr_buf(out, "cannibalize lock:\t%p\n", c->btree_cache.alloc_lock);
|
||||
prt_printf(out, "nr nodes:\t\t%u\n", c->btree_cache.used);
|
||||
prt_printf(out, "nr dirty:\t\t%u\n", atomic_read(&c->btree_cache.dirty));
|
||||
prt_printf(out, "cannibalize lock:\t%p\n", c->btree_cache.alloc_lock);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ static int bch2_gc_check_topology(struct bch_fs *c,
|
||||
bch2_topology_error(c);
|
||||
|
||||
if (bkey_deleted(&prev->k->k)) {
|
||||
pr_buf(&buf1, "start of node: ");
|
||||
prt_printf(&buf1, "start of node: ");
|
||||
bch2_bpos_to_text(&buf1, node_start);
|
||||
} else {
|
||||
bch2_bkey_val_to_text(&buf1, c, bkey_i_to_s_c(prev->k));
|
||||
@ -264,7 +264,7 @@ static int btree_repair_node_boundaries(struct bch_fs *c, struct btree *b,
|
||||
int ret = 0;
|
||||
|
||||
if (!prev) {
|
||||
pr_buf(&buf1, "start of node: ");
|
||||
prt_printf(&buf1, "start of node: ");
|
||||
bch2_bpos_to_text(&buf1, b->data->min_key);
|
||||
} else {
|
||||
bch2_bkey_val_to_text(&buf1, c, bkey_i_to_s_c(&prev->key));
|
||||
|
@ -495,7 +495,7 @@ void bch2_btree_init_next(struct btree_trans *trans, struct btree *b)
|
||||
static void btree_pos_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct btree *b)
|
||||
{
|
||||
pr_buf(out, "%s level %u/%u\n ",
|
||||
prt_printf(out, "%s level %u/%u\n ",
|
||||
bch2_btree_ids[b->c.btree_id],
|
||||
b->c.level,
|
||||
c->btree_roots[b->c.btree_id].level);
|
||||
@ -507,17 +507,17 @@ static void btree_err_msg(struct printbuf *out, struct bch_fs *c,
|
||||
struct btree *b, struct bset *i,
|
||||
unsigned offset, int write)
|
||||
{
|
||||
pr_buf(out, "error validating btree node ");
|
||||
prt_printf(out, "error validating btree node ");
|
||||
if (write)
|
||||
pr_buf(out, "before write ");
|
||||
prt_printf(out, "before write ");
|
||||
if (ca)
|
||||
pr_buf(out, "on %s ", ca->name);
|
||||
pr_buf(out, "at btree ");
|
||||
prt_printf(out, "on %s ", ca->name);
|
||||
prt_printf(out, "at btree ");
|
||||
btree_pos_to_text(out, c, b);
|
||||
|
||||
pr_buf(out, "\n node offset %u", b->written);
|
||||
prt_printf(out, "\n node offset %u", b->written);
|
||||
if (i)
|
||||
pr_buf(out, " bset u64s %u", le16_to_cpu(i->u64s));
|
||||
prt_printf(out, " bset u64s %u", le16_to_cpu(i->u64s));
|
||||
}
|
||||
|
||||
enum btree_err_type {
|
||||
@ -537,7 +537,7 @@ enum btree_validate_ret {
|
||||
struct printbuf out = PRINTBUF; \
|
||||
\
|
||||
btree_err_msg(&out, c, ca, b, i, b->written, write); \
|
||||
pr_buf(&out, ": " msg, ##__VA_ARGS__); \
|
||||
prt_printf(&out, ": " msg, ##__VA_ARGS__); \
|
||||
\
|
||||
if (type == BTREE_ERR_FIXABLE && \
|
||||
write == READ && \
|
||||
@ -815,9 +815,9 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
|
||||
printbuf_reset(&buf);
|
||||
if (bset_key_invalid(c, b, u.s_c, updated_range, write, &buf)) {
|
||||
printbuf_reset(&buf);
|
||||
pr_buf(&buf, "invalid bkey: ");
|
||||
prt_printf(&buf, "invalid bkey: ");
|
||||
bset_key_invalid(c, b, u.s_c, updated_range, write, &buf);
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, u.s_c);
|
||||
|
||||
btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i, "%s", buf.buf);
|
||||
@ -837,9 +837,9 @@ static int validate_bset_keys(struct bch_fs *c, struct btree *b,
|
||||
struct bkey up = bkey_unpack_key(b, prev);
|
||||
|
||||
printbuf_reset(&buf);
|
||||
pr_buf(&buf, "keys out of order: ");
|
||||
prt_printf(&buf, "keys out of order: ");
|
||||
bch2_bkey_to_text(&buf, &up);
|
||||
pr_buf(&buf, " > ");
|
||||
prt_printf(&buf, " > ");
|
||||
bch2_bkey_to_text(&buf, u.k);
|
||||
|
||||
bch2_dump_bset(c, b, i, 0);
|
||||
@ -1076,9 +1076,9 @@ int bch2_btree_node_read_done(struct bch_fs *c, struct bch_dev *ca,
|
||||
!bversion_cmp(u.k->version, MAX_VERSION))) {
|
||||
printbuf_reset(&buf);
|
||||
|
||||
pr_buf(&buf, "invalid bkey: ");
|
||||
prt_printf(&buf, "invalid bkey: ");
|
||||
bch2_bkey_val_invalid(c, u.s_c, READ, &buf);
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, u.s_c);
|
||||
|
||||
btree_err(BTREE_ERR_FIXABLE, c, NULL, b, i, "%s", buf.buf);
|
||||
@ -1338,10 +1338,10 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
|
||||
sectors = vstruct_sectors(bne, c->block_bits);
|
||||
}
|
||||
|
||||
pr_buf(&buf, " %u-%u", offset, offset + sectors);
|
||||
prt_printf(&buf, " %u-%u", offset, offset + sectors);
|
||||
if (bne && bch2_journal_seq_is_blacklisted(c,
|
||||
le64_to_cpu(bne->keys.journal_seq), false))
|
||||
pr_buf(&buf, "*");
|
||||
prt_printf(&buf, "*");
|
||||
offset += sectors;
|
||||
}
|
||||
|
||||
@ -1349,14 +1349,14 @@ static void btree_node_read_all_replicas_done(struct closure *cl)
|
||||
bne = ra->buf[i] + (offset << 9);
|
||||
if (bne->keys.seq == bn->keys.seq) {
|
||||
if (!gap)
|
||||
pr_buf(&buf, " GAP");
|
||||
prt_printf(&buf, " GAP");
|
||||
gap = true;
|
||||
|
||||
sectors = vstruct_sectors(bne, c->block_bits);
|
||||
pr_buf(&buf, " %u-%u", offset, offset + sectors);
|
||||
prt_printf(&buf, " %u-%u", offset, offset + sectors);
|
||||
if (bch2_journal_seq_is_blacklisted(c,
|
||||
le64_to_cpu(bne->keys.journal_seq), false))
|
||||
pr_buf(&buf, "*");
|
||||
prt_printf(&buf, "*");
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
@ -1497,7 +1497,7 @@ void bch2_btree_node_read(struct bch_fs *c, struct btree *b,
|
||||
if (ret <= 0) {
|
||||
struct printbuf buf = PRINTBUF;
|
||||
|
||||
pr_buf(&buf, "btree node read error: no device to read from\n at ");
|
||||
prt_str(&buf, "btree node read error: no device to read from\n at ");
|
||||
btree_pos_to_text(&buf, c, b);
|
||||
bch_err(c, "%s", buf.buf);
|
||||
|
||||
|
@ -639,14 +639,14 @@ static void bch2_btree_path_verify_level(struct btree_trans *trans,
|
||||
struct bkey uk = bkey_unpack_key(l->b, p);
|
||||
bch2_bkey_to_text(&buf2, &uk);
|
||||
} else {
|
||||
pr_buf(&buf2, "(none)");
|
||||
prt_printf(&buf2, "(none)");
|
||||
}
|
||||
|
||||
if (k) {
|
||||
struct bkey uk = bkey_unpack_key(l->b, k);
|
||||
bch2_bkey_to_text(&buf3, &uk);
|
||||
} else {
|
||||
pr_buf(&buf3, "(none)");
|
||||
prt_printf(&buf3, "(none)");
|
||||
}
|
||||
|
||||
panic("path should be %s key at level %u:\n"
|
||||
@ -1821,30 +1821,30 @@ void bch2_trans_updates_to_text(struct printbuf *buf, struct btree_trans *trans)
|
||||
{
|
||||
struct btree_insert_entry *i;
|
||||
|
||||
pr_buf(buf, "transaction updates for %s journal seq %llu",
|
||||
prt_printf(buf, "transaction updates for %s journal seq %llu",
|
||||
trans->fn, trans->journal_res.seq);
|
||||
pr_newline(buf);
|
||||
pr_indent_push(buf, 2);
|
||||
prt_newline(buf);
|
||||
printbuf_indent_add(buf, 2);
|
||||
|
||||
trans_for_each_update(trans, i) {
|
||||
struct bkey_s_c old = { &i->old_k, i->old_v };
|
||||
|
||||
pr_buf(buf, "update: btree=%s cached=%u %pS",
|
||||
prt_printf(buf, "update: btree=%s cached=%u %pS",
|
||||
bch2_btree_ids[i->btree_id],
|
||||
i->cached,
|
||||
(void *) i->ip_allocated);
|
||||
pr_newline(buf);
|
||||
prt_newline(buf);
|
||||
|
||||
pr_buf(buf, " old ");
|
||||
prt_printf(buf, " old ");
|
||||
bch2_bkey_val_to_text(buf, trans->c, old);
|
||||
pr_newline(buf);
|
||||
prt_newline(buf);
|
||||
|
||||
pr_buf(buf, " new ");
|
||||
prt_printf(buf, " new ");
|
||||
bch2_bkey_val_to_text(buf, trans->c, bkey_i_to_s_c(i->k));
|
||||
pr_newline(buf);
|
||||
prt_newline(buf);
|
||||
}
|
||||
|
||||
pr_indent_pop(buf, 2);
|
||||
printbuf_indent_sub(buf, 2);
|
||||
}
|
||||
|
||||
noinline __cold
|
||||
@ -3365,7 +3365,7 @@ bch2_btree_path_node_to_text(struct printbuf *out,
|
||||
struct btree_bkey_cached_common *_b,
|
||||
bool cached)
|
||||
{
|
||||
pr_buf(out, " l=%u %s:",
|
||||
prt_printf(out, " l=%u %s:",
|
||||
_b->level, bch2_btree_ids[_b->btree_id]);
|
||||
bch2_bpos_to_text(out, btree_node_pos(_b, cached));
|
||||
}
|
||||
@ -3396,28 +3396,28 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
if (!trans_has_locks(trans))
|
||||
continue;
|
||||
|
||||
pr_buf(out, "%i %s\n", trans->pid, trans->fn);
|
||||
prt_printf(out, "%i %s\n", trans->pid, trans->fn);
|
||||
|
||||
trans_for_each_path(trans, path) {
|
||||
if (!path->nodes_locked)
|
||||
continue;
|
||||
|
||||
pr_buf(out, " path %u %c l=%u %s:",
|
||||
prt_printf(out, " path %u %c l=%u %s:",
|
||||
path->idx,
|
||||
path->cached ? 'c' : 'b',
|
||||
path->level,
|
||||
bch2_btree_ids[path->btree_id]);
|
||||
bch2_bpos_to_text(out, path->pos);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "\n");
|
||||
|
||||
for (l = 0; l < BTREE_MAX_DEPTH; l++) {
|
||||
if (btree_node_locked(path, l)) {
|
||||
pr_buf(out, " %s l=%u ",
|
||||
prt_printf(out, " %s l=%u ",
|
||||
btree_node_intent_locked(path, l) ? "i" : "r", l);
|
||||
bch2_btree_path_node_to_text(out,
|
||||
(void *) path->l[l].b,
|
||||
path->cached);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3425,7 +3425,7 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
b = READ_ONCE(trans->locking);
|
||||
if (b) {
|
||||
path = &trans->paths[trans->locking_path_idx];
|
||||
pr_buf(out, " locking path %u %c l=%u %c %s:",
|
||||
prt_printf(out, " locking path %u %c l=%u %c %s:",
|
||||
trans->locking_path_idx,
|
||||
path->cached ? 'c' : 'b',
|
||||
trans->locking_level,
|
||||
@ -3433,10 +3433,10 @@ void bch2_btree_trans_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
bch2_btree_ids[trans->locking_btree_id]);
|
||||
bch2_bpos_to_text(out, trans->locking_pos);
|
||||
|
||||
pr_buf(out, " node ");
|
||||
prt_printf(out, " node ");
|
||||
bch2_btree_path_node_to_text(out,
|
||||
(void *) b, path->cached);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "\n");
|
||||
}
|
||||
}
|
||||
mutex_unlock(&c->btree_trans_lock);
|
||||
|
@ -748,9 +748,9 @@ int bch2_fs_btree_key_cache_init(struct btree_key_cache *bc)
|
||||
|
||||
void bch2_btree_key_cache_to_text(struct printbuf *out, struct btree_key_cache *c)
|
||||
{
|
||||
pr_buf(out, "nr_freed:\t%zu\n", c->nr_freed);
|
||||
pr_buf(out, "nr_keys:\t%lu\n", atomic_long_read(&c->nr_keys));
|
||||
pr_buf(out, "nr_dirty:\t%lu\n", atomic_long_read(&c->nr_dirty));
|
||||
prt_printf(out, "nr_freed:\t%zu\n", c->nr_freed);
|
||||
prt_printf(out, "nr_keys:\t%lu\n", atomic_long_read(&c->nr_keys));
|
||||
prt_printf(out, "nr_dirty:\t%lu\n", atomic_long_read(&c->nr_dirty));
|
||||
}
|
||||
|
||||
void bch2_btree_key_cache_exit(void)
|
||||
|
@ -1189,9 +1189,9 @@ static void bch2_insert_fixup_btree_ptr(struct btree_update *as,
|
||||
btree_node_type(b), WRITE, &buf) ?:
|
||||
bch2_bkey_in_btree_node(b, bkey_i_to_s_c(insert), &buf)) {
|
||||
printbuf_reset(&buf);
|
||||
pr_buf(&buf, "inserting invalid bkey\n ");
|
||||
prt_printf(&buf, "inserting invalid bkey\n ");
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(insert));
|
||||
pr_buf(&buf, "\n ");
|
||||
prt_printf(&buf, "\n ");
|
||||
bch2_bkey_invalid(c, bkey_i_to_s_c(insert),
|
||||
btree_node_type(b), WRITE, &buf);
|
||||
bch2_bkey_in_btree_node(b, bkey_i_to_s_c(insert), &buf);
|
||||
@ -2163,7 +2163,7 @@ void bch2_btree_updates_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
|
||||
mutex_lock(&c->btree_interior_update_lock);
|
||||
list_for_each_entry(as, &c->btree_interior_update_list, list)
|
||||
pr_buf(out, "%p m %u w %u r %u j %llu\n",
|
||||
prt_printf(out, "%p m %u w %u r %u j %llu\n",
|
||||
as,
|
||||
as->mode,
|
||||
as->nodes_written,
|
||||
|
@ -868,13 +868,13 @@ static inline int do_bch2_trans_commit(struct btree_trans *trans,
|
||||
if (bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
|
||||
i->bkey_type, rw, &buf)) {
|
||||
printbuf_reset(&buf);
|
||||
pr_buf(&buf, "invalid bkey on insert from %s -> %ps",
|
||||
prt_printf(&buf, "invalid bkey on insert from %s -> %ps",
|
||||
trans->fn, (void *) i->ip_allocated);
|
||||
pr_newline(&buf);
|
||||
pr_indent_push(&buf, 2);
|
||||
prt_newline(&buf);
|
||||
printbuf_indent_add(&buf, 2);
|
||||
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(i->k));
|
||||
pr_newline(&buf);
|
||||
prt_newline(&buf);
|
||||
|
||||
bch2_bkey_invalid(c, bkey_i_to_s_c(i->k),
|
||||
i->bkey_type, rw, &buf);
|
||||
|
@ -201,26 +201,26 @@ void bch2_fs_usage_to_text(struct printbuf *out,
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
pr_buf(out, "capacity:\t\t\t%llu\n", c->capacity);
|
||||
prt_printf(out, "capacity:\t\t\t%llu\n", c->capacity);
|
||||
|
||||
pr_buf(out, "hidden:\t\t\t\t%llu\n",
|
||||
prt_printf(out, "hidden:\t\t\t\t%llu\n",
|
||||
fs_usage->u.hidden);
|
||||
pr_buf(out, "data:\t\t\t\t%llu\n",
|
||||
prt_printf(out, "data:\t\t\t\t%llu\n",
|
||||
fs_usage->u.data);
|
||||
pr_buf(out, "cached:\t\t\t\t%llu\n",
|
||||
prt_printf(out, "cached:\t\t\t\t%llu\n",
|
||||
fs_usage->u.cached);
|
||||
pr_buf(out, "reserved:\t\t\t%llu\n",
|
||||
prt_printf(out, "reserved:\t\t\t%llu\n",
|
||||
fs_usage->u.reserved);
|
||||
pr_buf(out, "nr_inodes:\t\t\t%llu\n",
|
||||
prt_printf(out, "nr_inodes:\t\t\t%llu\n",
|
||||
fs_usage->u.nr_inodes);
|
||||
pr_buf(out, "online reserved:\t\t%llu\n",
|
||||
prt_printf(out, "online reserved:\t\t%llu\n",
|
||||
fs_usage->online_reserved);
|
||||
|
||||
for (i = 0;
|
||||
i < ARRAY_SIZE(fs_usage->u.persistent_reserved);
|
||||
i++) {
|
||||
pr_buf(out, "%u replicas:\n", i + 1);
|
||||
pr_buf(out, "\treserved:\t\t%llu\n",
|
||||
prt_printf(out, "%u replicas:\n", i + 1);
|
||||
prt_printf(out, "\treserved:\t\t%llu\n",
|
||||
fs_usage->u.persistent_reserved[i]);
|
||||
}
|
||||
|
||||
@ -228,9 +228,9 @@ void bch2_fs_usage_to_text(struct printbuf *out,
|
||||
struct bch_replicas_entry *e =
|
||||
cpu_replicas_entry(&c->replicas, i);
|
||||
|
||||
pr_buf(out, "\t");
|
||||
prt_printf(out, "\t");
|
||||
bch2_replicas_entry_to_text(out, e);
|
||||
pr_buf(out, ":\t%llu\n", fs_usage->u.replicas[i]);
|
||||
prt_printf(out, ":\t%llu\n", fs_usage->u.replicas[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -493,13 +493,15 @@ static int __bch2_request_key(char *key_description, struct bch_key *key)
|
||||
|
||||
int bch2_request_key(struct bch_sb *sb, struct bch_key *key)
|
||||
{
|
||||
char key_description[60];
|
||||
char uuid[40];
|
||||
struct printbuf key_description = PRINTBUF;
|
||||
int ret;
|
||||
|
||||
uuid_unparse_lower(sb->user_uuid.b, uuid);
|
||||
sprintf(key_description, "bcachefs:%s", uuid);
|
||||
prt_printf(&key_description, "bcachefs:");
|
||||
pr_uuid(&key_description, sb->user_uuid.b);
|
||||
|
||||
return __bch2_request_key(key_description, key);
|
||||
ret = __bch2_request_key(key_description.buf, key);
|
||||
printbuf_exit(&key_description);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bch2_decrypt_sb_key(struct bch_fs *c,
|
||||
|
@ -162,7 +162,7 @@ void bch2_io_timers_to_text(struct printbuf *out, struct io_clock *clock)
|
||||
now = atomic64_read(&clock->now);
|
||||
|
||||
for (i = 0; i < clock->timers.used; i++)
|
||||
pr_buf(out, "%ps:\t%li\n",
|
||||
prt_printf(out, "%ps:\t%li\n",
|
||||
clock->timers.data[i]->fn,
|
||||
clock->timers.data[i]->expire - now);
|
||||
spin_unlock(&clock->timer_lock);
|
||||
|
@ -36,13 +36,13 @@ void bch2_sb_counters_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
if (i < BCH_COUNTER_NR)
|
||||
pr_buf(out, "%s", bch2_counter_names[i]);
|
||||
prt_printf(out, "%s", bch2_counter_names[i]);
|
||||
else
|
||||
pr_buf(out, "(unknown)");
|
||||
prt_printf(out, "(unknown)");
|
||||
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", le64_to_cpu(ctrs->d[i]));
|
||||
pr_newline(out);
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", le64_to_cpu(ctrs->d[i]));
|
||||
prt_newline(out);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -273,7 +273,7 @@ static ssize_t bch2_read_btree(struct file *file, char __user *buf,
|
||||
|
||||
while (k.k && !(err = bkey_err(k))) {
|
||||
bch2_bkey_val_to_text(&i->buf, i->c, k);
|
||||
pr_char(&i->buf, '\n');
|
||||
prt_char(&i->buf, '\n');
|
||||
|
||||
k = bch2_btree_iter_next(&iter);
|
||||
i->from = iter.pos;
|
||||
@ -425,55 +425,56 @@ static const struct file_operations bfloat_failed_debug_ops = {
|
||||
static void bch2_cached_btree_node_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct btree *b)
|
||||
{
|
||||
out->tabstops[0] = 32;
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 32);
|
||||
|
||||
pr_buf(out, "%px btree=%s l=%u ",
|
||||
prt_printf(out, "%px btree=%s l=%u ",
|
||||
b,
|
||||
bch2_btree_ids[b->c.btree_id],
|
||||
b->c.level);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_indent_push(out, 2);
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(&b->key));
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "flags: ");
|
||||
pr_tab(out);
|
||||
bch2_flags_to_text(out, bch2_btree_node_flags, b->flags);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "flags: ");
|
||||
prt_tab(out);
|
||||
prt_bitflags(out, bch2_btree_node_flags, b->flags);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "pcpu read locks: ");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", b->c.lock.readers != NULL);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "pcpu read locks: ");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", b->c.lock.readers != NULL);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "written:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", b->written);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "written:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", b->written);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "writes blocked:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", !list_empty_careful(&b->write_blocked));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "writes blocked:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", !list_empty_careful(&b->write_blocked));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "will make reachable:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%lx", b->will_make_reachable);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "will make reachable:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%lx", b->will_make_reachable);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "journal pin %px:", &b->writes[0].journal);
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", b->writes[0].journal.seq);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "journal pin %px:", &b->writes[0].journal);
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", b->writes[0].journal.seq);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "journal pin %px:", &b->writes[1].journal);
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", b->writes[1].journal.seq);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "journal pin %px:", &b->writes[1].journal);
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", b->writes[1].journal.seq);
|
||||
prt_newline(out);
|
||||
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
static ssize_t bch2_cached_btree_nodes_read(struct file *file, char __user *buf,
|
||||
|
@ -90,47 +90,47 @@ int bch2_dirent_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
unsigned len;
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(struct bch_dirent)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*d.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
len = bch2_dirent_name_bytes(d);
|
||||
if (!len) {
|
||||
pr_buf(err, "empty name");
|
||||
prt_printf(err, "empty name");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_u64s(k.k) > dirent_val_u64s(len)) {
|
||||
pr_buf(err, "value too big (%zu > %u)",
|
||||
prt_printf(err, "value too big (%zu > %u)",
|
||||
bkey_val_u64s(k.k),dirent_val_u64s(len));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len > BCH_NAME_MAX) {
|
||||
pr_buf(err, "dirent name too big (%u > %u)",
|
||||
prt_printf(err, "dirent name too big (%u > %u)",
|
||||
len, BCH_NAME_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len == 1 && !memcmp(d.v->d_name, ".", 1)) {
|
||||
pr_buf(err, "invalid name");
|
||||
prt_printf(err, "invalid name");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len == 2 && !memcmp(d.v->d_name, "..", 2)) {
|
||||
pr_buf(err, "invalid name");
|
||||
prt_printf(err, "invalid name");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (memchr(d.v->d_name, '/', len)) {
|
||||
pr_buf(err, "invalid name");
|
||||
prt_printf(err, "invalid name");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (d.v->d_type != DT_SUBVOL &&
|
||||
le64_to_cpu(d.v->d_inum) == d.k->p.inode) {
|
||||
pr_buf(err, "dirent points to own directory");
|
||||
prt_printf(err, "dirent points to own directory");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_dirent d = bkey_s_c_to_dirent(k);
|
||||
|
||||
pr_buf(out, "%.*s -> %llu type %s",
|
||||
prt_printf(out, "%.*s -> %llu type %s",
|
||||
bch2_dirent_name_bytes(d),
|
||||
d.v->d_name,
|
||||
d.v->d_type != DT_SUBVOL
|
||||
|
@ -39,13 +39,13 @@ static int bch2_sb_disk_groups_validate(struct bch_sb *sb,
|
||||
g = BCH_MEMBER_GROUP(m) - 1;
|
||||
|
||||
if (g >= nr_groups) {
|
||||
pr_buf(err, "disk %u has invalid label %u (have %u)",
|
||||
prt_printf(err, "disk %u has invalid label %u (have %u)",
|
||||
i, g, nr_groups);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (BCH_GROUP_DELETED(&groups->entries[g])) {
|
||||
pr_buf(err, "disk %u has deleted label %u", i, g);
|
||||
prt_printf(err, "disk %u has deleted label %u", i, g);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -61,7 +61,7 @@ static int bch2_sb_disk_groups_validate(struct bch_sb *sb,
|
||||
|
||||
len = strnlen(g->label, sizeof(g->label));
|
||||
if (!len) {
|
||||
pr_buf(err, "label %u empty", i);
|
||||
prt_printf(err, "label %u empty", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ 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.%.*s",
|
||||
prt_printf(err, "duplicate label %llu.%.*s",
|
||||
BCH_GROUP_PARENT(g),
|
||||
(int) sizeof(g->label), g->label);
|
||||
goto err;
|
||||
@ -101,12 +101,12 @@ static void bch2_sb_disk_groups_to_text(struct printbuf *out,
|
||||
g < groups->entries + nr_groups;
|
||||
g++) {
|
||||
if (g != groups->entries)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
|
||||
if (BCH_GROUP_DELETED(g))
|
||||
pr_buf(out, "[deleted]");
|
||||
prt_printf(out, "[deleted]");
|
||||
else
|
||||
pr_buf(out, "[parent %llu name %s]",
|
||||
prt_printf(out, "[parent %llu name %s]",
|
||||
BCH_GROUP_PARENT(g), g->label);
|
||||
}
|
||||
}
|
||||
@ -375,13 +375,13 @@ void bch2_disk_path_to_text(struct printbuf *out, struct bch_sb *sb, unsigned v)
|
||||
v = path[--nr];
|
||||
g = groups->entries + v;
|
||||
|
||||
pr_buf(out, "%.*s", (int) sizeof(g->label), g->label);
|
||||
prt_printf(out, "%.*s", (int) sizeof(g->label), g->label);
|
||||
if (nr)
|
||||
pr_buf(out, ".");
|
||||
prt_printf(out, ".");
|
||||
}
|
||||
return;
|
||||
inval:
|
||||
pr_buf(out, "invalid label %u", v);
|
||||
prt_printf(out, "invalid label %u", v);
|
||||
}
|
||||
|
||||
int bch2_dev_group_set(struct bch_fs *c, struct bch_dev *ca, const char *name)
|
||||
@ -454,7 +454,7 @@ void bch2_opt_target_to_text(struct printbuf *out,
|
||||
|
||||
switch (t.type) {
|
||||
case TARGET_NULL:
|
||||
pr_buf(out, "none");
|
||||
prt_printf(out, "none");
|
||||
break;
|
||||
case TARGET_DEV:
|
||||
if (c) {
|
||||
@ -466,12 +466,12 @@ void bch2_opt_target_to_text(struct printbuf *out,
|
||||
: NULL;
|
||||
|
||||
if (ca && percpu_ref_tryget(&ca->io_ref)) {
|
||||
pr_buf(out, "/dev/%pg", ca->disk_sb.bdev);
|
||||
prt_printf(out, "/dev/%pg", ca->disk_sb.bdev);
|
||||
percpu_ref_put(&ca->io_ref);
|
||||
} else if (ca) {
|
||||
pr_buf(out, "offline device %u", t.dev);
|
||||
prt_printf(out, "offline device %u", t.dev);
|
||||
} else {
|
||||
pr_buf(out, "invalid device %u", t.dev);
|
||||
prt_printf(out, "invalid device %u", t.dev);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
@ -480,11 +480,11 @@ void bch2_opt_target_to_text(struct printbuf *out,
|
||||
struct bch_member *m = mi->members + t.dev;
|
||||
|
||||
if (bch2_dev_exists(sb, mi, t.dev)) {
|
||||
pr_buf(out, "Device ");
|
||||
prt_printf(out, "Device ");
|
||||
pr_uuid(out, m->uuid.b);
|
||||
pr_buf(out, " (%u)", t.dev);
|
||||
prt_printf(out, " (%u)", t.dev);
|
||||
} else {
|
||||
pr_buf(out, "Bad device %u", t.dev);
|
||||
prt_printf(out, "Bad device %u", t.dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -108,23 +108,23 @@ int bch2_stripe_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
|
||||
|
||||
if (!bkey_cmp(k.k->p, POS_MIN)) {
|
||||
pr_buf(err, "stripe at POS_MIN");
|
||||
prt_printf(err, "stripe at POS_MIN");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k.k->p.inode) {
|
||||
pr_buf(err, "nonzero inode field");
|
||||
prt_printf(err, "nonzero inode field");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(*s)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*s));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_u64s(k.k) < stripe_val_u64s(s)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %u)",
|
||||
prt_printf(err, "incorrect value size (%zu < %u)",
|
||||
bkey_val_u64s(k.k), stripe_val_u64s(s));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -138,7 +138,7 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
|
||||
unsigned i;
|
||||
|
||||
pr_buf(out, "algo %u sectors %u blocks %u:%u csum %u gran %u",
|
||||
prt_printf(out, "algo %u sectors %u blocks %u:%u csum %u gran %u",
|
||||
s->algorithm,
|
||||
le16_to_cpu(s->sectors),
|
||||
s->nr_blocks - s->nr_redundant,
|
||||
@ -147,7 +147,7 @@ void bch2_stripe_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
1U << s->csum_granularity_bits);
|
||||
|
||||
for (i = 0; i < s->nr_blocks; i++)
|
||||
pr_buf(out, " %u:%llu:%u", s->ptrs[i].dev,
|
||||
prt_printf(out, " %u:%llu:%u", s->ptrs[i].dev,
|
||||
(u64) s->ptrs[i].offset,
|
||||
stripe_blockcount_get(s, i));
|
||||
}
|
||||
@ -1622,7 +1622,7 @@ void bch2_stripes_heap_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
for (i = 0; i < min_t(size_t, h->used, 20); i++) {
|
||||
m = genradix_ptr(&c->stripes, h->data[i].idx);
|
||||
|
||||
pr_buf(out, "%zu %u/%u+%u\n", h->data[i].idx,
|
||||
prt_printf(out, "%zu %u/%u+%u\n", h->data[i].idx,
|
||||
h->data[i].blocks_nonempty,
|
||||
m->nr_blocks - m->nr_redundant,
|
||||
m->nr_redundant);
|
||||
@ -1637,11 +1637,11 @@ void bch2_new_stripes_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
|
||||
mutex_lock(&c->ec_stripe_head_lock);
|
||||
list_for_each_entry(h, &c->ec_stripe_head_list, list) {
|
||||
pr_buf(out, "target %u algo %u redundancy %u:\n",
|
||||
prt_printf(out, "target %u algo %u redundancy %u:\n",
|
||||
h->target, h->algo, h->redundancy);
|
||||
|
||||
if (h->s)
|
||||
pr_buf(out, "\tpending: blocks %u+%u allocated %u\n",
|
||||
prt_printf(out, "\tpending: blocks %u+%u allocated %u\n",
|
||||
h->s->nr_data, h->s->nr_parity,
|
||||
bitmap_weight(h->s->blocks_allocated,
|
||||
h->s->nr_data));
|
||||
@ -1650,7 +1650,7 @@ void bch2_new_stripes_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
|
||||
mutex_lock(&c->ec_stripe_new_lock);
|
||||
list_for_each_entry(s, &c->ec_stripe_new_list, list) {
|
||||
pr_buf(out, "\tin flight: blocks %u+%u pin %u\n",
|
||||
prt_printf(out, "\tin flight: blocks %u+%u pin %u\n",
|
||||
s->nr_data, s->nr_parity,
|
||||
atomic_read(&s->pin));
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ int bch2_btree_ptr_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (bkey_val_u64s(k.k) > BCH_REPLICAS_MAX) {
|
||||
pr_buf(err, "value too big (%zu > %u)",
|
||||
prt_printf(err, "value too big (%zu > %u)",
|
||||
bkey_val_u64s(k.k), BCH_REPLICAS_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -179,20 +179,20 @@ int bch2_btree_ptr_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) <= sizeof(*bp.v)) {
|
||||
pr_buf(err, "value too small (%zu <= %zu)",
|
||||
prt_printf(err, "value too small (%zu <= %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*bp.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_u64s(k.k) > BKEY_BTREE_PTR_VAL_U64s_MAX) {
|
||||
pr_buf(err, "value too big (%zu > %zu)",
|
||||
prt_printf(err, "value too big (%zu > %zu)",
|
||||
bkey_val_u64s(k.k), BKEY_BTREE_PTR_VAL_U64s_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (c->sb.version < bcachefs_metadata_version_snapshot &&
|
||||
bp.v->min_key.snapshot) {
|
||||
pr_buf(err, "invalid min_key.snapshot (%u != 0)",
|
||||
prt_printf(err, "invalid min_key.snapshot (%u != 0)",
|
||||
bp.v->min_key.snapshot);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -205,13 +205,13 @@ void bch2_btree_ptr_v2_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_btree_ptr_v2 bp = bkey_s_c_to_btree_ptr_v2(k);
|
||||
|
||||
pr_buf(out, "seq %llx written %u min_key %s",
|
||||
prt_printf(out, "seq %llx written %u min_key %s",
|
||||
le64_to_cpu(bp.v->seq),
|
||||
le16_to_cpu(bp.v->sectors_written),
|
||||
BTREE_PTR_RANGE_UPDATED(bp.v) ? "R " : "");
|
||||
|
||||
bch2_bpos_to_text(out, bp.v->min_key);
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
bch2_bkey_ptrs_to_text(out, c, k);
|
||||
}
|
||||
|
||||
@ -383,13 +383,13 @@ int bch2_reservation_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_reservation r = bkey_s_c_to_reservation(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_reservation)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*r.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!r.v->nr_replicas || r.v->nr_replicas > BCH_REPLICAS_MAX) {
|
||||
pr_buf(err, "invalid nr_replicas (%u)",
|
||||
prt_printf(err, "invalid nr_replicas (%u)",
|
||||
r.v->nr_replicas);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -402,7 +402,7 @@ void bch2_reservation_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_reservation r = bkey_s_c_to_reservation(k);
|
||||
|
||||
pr_buf(out, "generation %u replicas %u",
|
||||
prt_printf(out, "generation %u replicas %u",
|
||||
le32_to_cpu(r.v->generation),
|
||||
r.v->nr_replicas);
|
||||
}
|
||||
@ -970,7 +970,7 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
|
||||
bkey_extent_entry_for_each(ptrs, entry) {
|
||||
if (!first)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
|
||||
switch (__extent_entry_type(entry)) {
|
||||
case BCH_EXTENT_ENTRY_ptr:
|
||||
@ -980,19 +980,19 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
: NULL;
|
||||
|
||||
if (!ca) {
|
||||
pr_buf(out, "ptr: %u:%llu gen %u%s", ptr->dev,
|
||||
prt_printf(out, "ptr: %u:%llu gen %u%s", ptr->dev,
|
||||
(u64) ptr->offset, ptr->gen,
|
||||
ptr->cached ? " cached" : "");
|
||||
} else {
|
||||
u32 offset;
|
||||
u64 b = sector_to_bucket_and_offset(ca, ptr->offset, &offset);
|
||||
|
||||
pr_buf(out, "ptr: %u:%llu:%u gen %u%s", ptr->dev,
|
||||
prt_printf(out, "ptr: %u:%llu:%u gen %u%s", ptr->dev,
|
||||
b, offset, ptr->gen,
|
||||
ptr->cached ? " cached" : "");
|
||||
|
||||
if (ca && ptr_stale(ca, ptr))
|
||||
pr_buf(out, " stale");
|
||||
prt_printf(out, " stale");
|
||||
}
|
||||
break;
|
||||
case BCH_EXTENT_ENTRY_crc32:
|
||||
@ -1000,7 +1000,7 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
case BCH_EXTENT_ENTRY_crc128:
|
||||
crc = bch2_extent_crc_unpack(k.k, entry_to_crc(entry));
|
||||
|
||||
pr_buf(out, "crc: c_size %u size %u offset %u nonce %u csum %s compress %s",
|
||||
prt_printf(out, "crc: c_size %u size %u offset %u nonce %u csum %s compress %s",
|
||||
crc.compressed_size,
|
||||
crc.uncompressed_size,
|
||||
crc.offset, crc.nonce,
|
||||
@ -1010,11 +1010,11 @@ void bch2_bkey_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
case BCH_EXTENT_ENTRY_stripe_ptr:
|
||||
ec = &entry->stripe_ptr;
|
||||
|
||||
pr_buf(out, "ec: idx %llu block %u",
|
||||
prt_printf(out, "ec: idx %llu block %u",
|
||||
(u64) ec->idx, ec->block);
|
||||
break;
|
||||
default:
|
||||
pr_buf(out, "(invalid extent entry %.16llx)", *((u64 *) entry));
|
||||
prt_printf(out, "(invalid extent entry %.16llx)", *((u64 *) entry));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1036,33 +1036,33 @@ static int extent_ptr_invalid(const struct bch_fs *c,
|
||||
struct bch_dev *ca;
|
||||
|
||||
if (!bch2_dev_exists2(c, ptr->dev)) {
|
||||
pr_buf(err, "pointer to invalid device (%u)", ptr->dev);
|
||||
prt_printf(err, "pointer to invalid device (%u)", ptr->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ca = bch_dev_bkey_exists(c, ptr->dev);
|
||||
bkey_for_each_ptr(ptrs, ptr2)
|
||||
if (ptr != ptr2 && ptr->dev == ptr2->dev) {
|
||||
pr_buf(err, "multiple pointers to same device (%u)", ptr->dev);
|
||||
prt_printf(err, "multiple pointers to same device (%u)", ptr->dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bucket = sector_to_bucket_and_offset(ca, ptr->offset, &bucket_offset);
|
||||
|
||||
if (bucket >= ca->mi.nbuckets) {
|
||||
pr_buf(err, "pointer past last bucket (%llu > %llu)",
|
||||
prt_printf(err, "pointer past last bucket (%llu > %llu)",
|
||||
bucket, ca->mi.nbuckets);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ptr->offset < bucket_to_sector(ca, ca->mi.first_bucket)) {
|
||||
pr_buf(err, "pointer before first bucket (%llu < %u)",
|
||||
prt_printf(err, "pointer before first bucket (%llu < %u)",
|
||||
bucket, ca->mi.first_bucket);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bucket_offset + size_ondisk > ca->mi.bucket_size) {
|
||||
pr_buf(err, "pointer spans multiple buckets (%u + %u > %u)",
|
||||
prt_printf(err, "pointer spans multiple buckets (%u + %u > %u)",
|
||||
bucket_offset, size_ondisk, ca->mi.bucket_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1085,14 +1085,14 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
bkey_extent_entry_for_each(ptrs, entry) {
|
||||
if (__extent_entry_type(entry) >= BCH_EXTENT_ENTRY_MAX) {
|
||||
pr_buf(err, "invalid extent entry type (got %u, max %u)",
|
||||
prt_printf(err, "invalid extent entry type (got %u, max %u)",
|
||||
__extent_entry_type(entry), BCH_EXTENT_ENTRY_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_is_btree_ptr(k.k) &&
|
||||
!extent_entry_is_ptr(entry)) {
|
||||
pr_buf(err, "has non ptr field");
|
||||
prt_printf(err, "has non ptr field");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1110,19 +1110,19 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
if (crc.offset + crc.live_size >
|
||||
crc.uncompressed_size) {
|
||||
pr_buf(err, "checksum offset + key size > uncompressed size");
|
||||
prt_printf(err, "checksum offset + key size > uncompressed size");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
size_ondisk = crc.compressed_size;
|
||||
|
||||
if (!bch2_checksum_type_valid(c, crc.csum_type)) {
|
||||
pr_buf(err, "invalid checksum type");
|
||||
prt_printf(err, "invalid checksum type");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (crc.compression_type >= BCH_COMPRESSION_TYPE_NR) {
|
||||
pr_buf(err, "invalid compression type");
|
||||
prt_printf(err, "invalid compression type");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1130,7 +1130,7 @@ int bch2_bkey_ptrs_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
if (nonce == UINT_MAX)
|
||||
nonce = crc.offset + crc.nonce;
|
||||
else if (nonce != crc.offset + crc.nonce) {
|
||||
pr_buf(err, "incorrect nonce");
|
||||
prt_printf(err, "incorrect nonce");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
@ -298,40 +298,40 @@ static int __bch2_inode_invalid(struct bkey_s_c k, struct printbuf *err)
|
||||
struct bch_inode_unpacked unpacked;
|
||||
|
||||
if (k.k->p.inode) {
|
||||
pr_buf(err, "nonzero k.p.inode");
|
||||
prt_printf(err, "nonzero k.p.inode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (k.k->p.offset < BLOCKDEV_INODE_MAX) {
|
||||
pr_buf(err, "fs inode in blockdev range");
|
||||
prt_printf(err, "fs inode in blockdev range");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bch2_inode_unpack(k, &unpacked)){
|
||||
pr_buf(err, "invalid variable length fields");
|
||||
prt_printf(err, "invalid variable length fields");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unpacked.bi_data_checksum >= BCH_CSUM_OPT_NR + 1) {
|
||||
pr_buf(err, "invalid data checksum type (%u >= %u",
|
||||
prt_printf(err, "invalid data checksum type (%u >= %u",
|
||||
unpacked.bi_data_checksum, BCH_CSUM_OPT_NR + 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unpacked.bi_compression >= BCH_COMPRESSION_OPT_NR + 1) {
|
||||
pr_buf(err, "invalid data checksum type (%u >= %u)",
|
||||
prt_printf(err, "invalid data checksum type (%u >= %u)",
|
||||
unpacked.bi_compression, BCH_COMPRESSION_OPT_NR + 1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((unpacked.bi_flags & BCH_INODE_UNLINKED) &&
|
||||
unpacked.bi_nlink != 0) {
|
||||
pr_buf(err, "flagged as unlinked but bi_nlink != 0");
|
||||
prt_printf(err, "flagged as unlinked but bi_nlink != 0");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unpacked.bi_subvol && !S_ISDIR(unpacked.bi_mode)) {
|
||||
pr_buf(err, "subvolume root but not a directory");
|
||||
prt_printf(err, "subvolume root but not a directory");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -344,13 +344,13 @@ int bch2_inode_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_inode inode = bkey_s_c_to_inode(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(*inode.v)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*inode.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (INODE_STR_HASH(inode.v) >= BCH_STR_HASH_NR) {
|
||||
pr_buf(err, "invalid str hash type (%llu >= %u)",
|
||||
prt_printf(err, "invalid str hash type (%llu >= %u)",
|
||||
INODE_STR_HASH(inode.v), BCH_STR_HASH_NR);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -364,13 +364,13 @@ int bch2_inode_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_inode_v2 inode = bkey_s_c_to_inode_v2(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(*inode.v)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*inode.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (INODEv2_STR_HASH(inode.v) >= BCH_STR_HASH_NR) {
|
||||
pr_buf(err, "invalid str hash type (%llu >= %u)",
|
||||
prt_printf(err, "invalid str hash type (%llu >= %u)",
|
||||
INODEv2_STR_HASH(inode.v), BCH_STR_HASH_NR);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -380,19 +380,19 @@ int bch2_inode_v2_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
static void __bch2_inode_unpacked_to_text(struct printbuf *out, struct bch_inode_unpacked *inode)
|
||||
{
|
||||
pr_buf(out, "mode %o flags %x journal_seq %llu",
|
||||
prt_printf(out, "mode %o flags %x journal_seq %llu",
|
||||
inode->bi_mode, inode->bi_flags,
|
||||
inode->bi_journal_seq);
|
||||
|
||||
#define x(_name, _bits) \
|
||||
pr_buf(out, " "#_name " %llu", (u64) inode->_name);
|
||||
prt_printf(out, " "#_name " %llu", (u64) inode->_name);
|
||||
BCH_INODE_FIELDS()
|
||||
#undef x
|
||||
}
|
||||
|
||||
void bch2_inode_unpacked_to_text(struct printbuf *out, struct bch_inode_unpacked *inode)
|
||||
{
|
||||
pr_buf(out, "inum: %llu ", inode->bi_inum);
|
||||
prt_printf(out, "inum: %llu ", inode->bi_inum);
|
||||
__bch2_inode_unpacked_to_text(out, inode);
|
||||
}
|
||||
|
||||
@ -402,7 +402,7 @@ void bch2_inode_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct bch_inode_unpacked inode;
|
||||
|
||||
if (bch2_inode_unpack(k, &inode)) {
|
||||
pr_buf(out, "(unpack error)");
|
||||
prt_printf(out, "(unpack error)");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -413,12 +413,12 @@ int bch2_inode_generation_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (k.k->p.inode) {
|
||||
pr_buf(err, "nonzero k.p.inode");
|
||||
prt_printf(err, "nonzero k.p.inode");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_inode_generation)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_inode_generation));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -431,7 +431,7 @@ void bch2_inode_generation_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_inode_generation gen = bkey_s_c_to_inode_generation(k);
|
||||
|
||||
pr_buf(out, "generation: %u", le32_to_cpu(gen.v->bi_generation));
|
||||
prt_printf(out, "generation: %u", le32_to_cpu(gen.v->bi_generation));
|
||||
}
|
||||
|
||||
void bch2_inode_init_early(struct bch_fs *c,
|
||||
|
@ -2094,18 +2094,18 @@ static noinline void read_from_stale_dirty_pointer(struct btree_trans *trans,
|
||||
PTR_BUCKET_POS(c, &ptr),
|
||||
BTREE_ITER_CACHED);
|
||||
|
||||
pr_buf(&buf, "Attempting to read from stale dirty pointer:");
|
||||
pr_indent_push(&buf, 2);
|
||||
pr_newline(&buf);
|
||||
prt_printf(&buf, "Attempting to read from stale dirty pointer:");
|
||||
printbuf_indent_add(&buf, 2);
|
||||
prt_newline(&buf);
|
||||
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
pr_newline(&buf);
|
||||
prt_newline(&buf);
|
||||
|
||||
pr_buf(&buf, "memory gen: %u", *bucket_gen(ca, iter.pos.offset));
|
||||
prt_printf(&buf, "memory gen: %u", *bucket_gen(ca, iter.pos.offset));
|
||||
|
||||
ret = lockrestart_do(trans, bkey_err(k = bch2_btree_iter_peek_slot(&iter)));
|
||||
if (!ret) {
|
||||
pr_newline(&buf);
|
||||
prt_newline(&buf);
|
||||
bch2_bkey_val_to_text(&buf, c, k);
|
||||
}
|
||||
|
||||
|
@ -1254,90 +1254,91 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
|
||||
u64 seq;
|
||||
unsigned i;
|
||||
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 24);
|
||||
out->atomic++;
|
||||
out->tabstops[0] = 24;
|
||||
|
||||
rcu_read_lock();
|
||||
s = READ_ONCE(j->reservations);
|
||||
|
||||
pr_buf(out, "dirty journal entries:\t%llu/%llu\n",fifo_used(&j->pin), j->pin.size);
|
||||
pr_buf(out, "seq:\t\t\t%llu\n", journal_cur_seq(j));
|
||||
pr_buf(out, "seq_ondisk:\t\t%llu\n", j->seq_ondisk);
|
||||
pr_buf(out, "last_seq:\t\t%llu\n", journal_last_seq(j));
|
||||
pr_buf(out, "last_seq_ondisk:\t%llu\n", j->last_seq_ondisk);
|
||||
pr_buf(out, "flushed_seq_ondisk:\t%llu\n", j->flushed_seq_ondisk);
|
||||
pr_buf(out, "prereserved:\t\t%u/%u\n", j->prereserved.reserved, j->prereserved.remaining);
|
||||
pr_buf(out, "watermark:\t\t%s\n", bch2_journal_watermarks[j->watermark]);
|
||||
pr_buf(out, "each entry reserved:\t%u\n", j->entry_u64s_reserved);
|
||||
pr_buf(out, "nr flush writes:\t%llu\n", j->nr_flush_writes);
|
||||
pr_buf(out, "nr noflush writes:\t%llu\n", j->nr_noflush_writes);
|
||||
pr_buf(out, "nr direct reclaim:\t%llu\n", j->nr_direct_reclaim);
|
||||
pr_buf(out, "nr background reclaim:\t%llu\n", j->nr_background_reclaim);
|
||||
pr_buf(out, "reclaim kicked:\t\t%u\n", j->reclaim_kicked);
|
||||
pr_buf(out, "reclaim runs in:\t%u ms\n", time_after(j->next_reclaim, now)
|
||||
prt_printf(out, "dirty journal entries:\t%llu/%llu\n",fifo_used(&j->pin), j->pin.size);
|
||||
prt_printf(out, "seq:\t\t\t%llu\n", journal_cur_seq(j));
|
||||
prt_printf(out, "seq_ondisk:\t\t%llu\n", j->seq_ondisk);
|
||||
prt_printf(out, "last_seq:\t\t%llu\n", journal_last_seq(j));
|
||||
prt_printf(out, "last_seq_ondisk:\t%llu\n", j->last_seq_ondisk);
|
||||
prt_printf(out, "flushed_seq_ondisk:\t%llu\n", j->flushed_seq_ondisk);
|
||||
prt_printf(out, "prereserved:\t\t%u/%u\n", j->prereserved.reserved, j->prereserved.remaining);
|
||||
prt_printf(out, "watermark:\t\t%s\n", bch2_journal_watermarks[j->watermark]);
|
||||
prt_printf(out, "each entry reserved:\t%u\n", j->entry_u64s_reserved);
|
||||
prt_printf(out, "nr flush writes:\t%llu\n", j->nr_flush_writes);
|
||||
prt_printf(out, "nr noflush writes:\t%llu\n", j->nr_noflush_writes);
|
||||
prt_printf(out, "nr direct reclaim:\t%llu\n", j->nr_direct_reclaim);
|
||||
prt_printf(out, "nr background reclaim:\t%llu\n", j->nr_background_reclaim);
|
||||
prt_printf(out, "reclaim kicked:\t\t%u\n", j->reclaim_kicked);
|
||||
prt_printf(out, "reclaim runs in:\t%u ms\n", time_after(j->next_reclaim, now)
|
||||
? jiffies_to_msecs(j->next_reclaim - jiffies) : 0);
|
||||
pr_buf(out, "current entry sectors:\t%u\n", j->cur_entry_sectors);
|
||||
pr_buf(out, "current entry error:\t%s\n", bch2_journal_errors[j->cur_entry_error]);
|
||||
pr_buf(out, "current entry:\t\t");
|
||||
prt_printf(out, "current entry sectors:\t%u\n", j->cur_entry_sectors);
|
||||
prt_printf(out, "current entry error:\t%s\n", bch2_journal_errors[j->cur_entry_error]);
|
||||
prt_printf(out, "current entry:\t\t");
|
||||
|
||||
switch (s.cur_entry_offset) {
|
||||
case JOURNAL_ENTRY_ERROR_VAL:
|
||||
pr_buf(out, "error");
|
||||
prt_printf(out, "error");
|
||||
break;
|
||||
case JOURNAL_ENTRY_CLOSED_VAL:
|
||||
pr_buf(out, "closed");
|
||||
prt_printf(out, "closed");
|
||||
break;
|
||||
default:
|
||||
pr_buf(out, "%u/%u", s.cur_entry_offset, j->cur_entry_u64s);
|
||||
prt_printf(out, "%u/%u", s.cur_entry_offset, j->cur_entry_u64s);
|
||||
break;
|
||||
}
|
||||
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
for (seq = journal_cur_seq(j);
|
||||
seq >= journal_last_unwritten_seq(j);
|
||||
--seq) {
|
||||
i = seq & JOURNAL_BUF_MASK;
|
||||
|
||||
pr_buf(out, "unwritten entry:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", seq);
|
||||
pr_newline(out);
|
||||
pr_indent_push(out, 2);
|
||||
prt_printf(out, "unwritten entry:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", seq);
|
||||
prt_newline(out);
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
pr_buf(out, "refcount:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", journal_state_count(s, i));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "refcount:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", journal_state_count(s, i));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "sectors:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", j->buf[i].sectors);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "sectors:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", j->buf[i].sectors);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "expires");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%li jiffies", j->buf[i].expires - jiffies);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "expires");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%li jiffies", j->buf[i].expires - jiffies);
|
||||
prt_newline(out);
|
||||
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
pr_buf(out,
|
||||
prt_printf(out,
|
||||
"replay done:\t\t%i\n",
|
||||
test_bit(JOURNAL_REPLAY_DONE, &j->flags));
|
||||
|
||||
pr_buf(out, "space:\n");
|
||||
pr_buf(out, "\tdiscarded\t%u:%u\n",
|
||||
prt_printf(out, "space:\n");
|
||||
prt_printf(out, "\tdiscarded\t%u:%u\n",
|
||||
j->space[journal_space_discarded].next_entry,
|
||||
j->space[journal_space_discarded].total);
|
||||
pr_buf(out, "\tclean ondisk\t%u:%u\n",
|
||||
prt_printf(out, "\tclean ondisk\t%u:%u\n",
|
||||
j->space[journal_space_clean_ondisk].next_entry,
|
||||
j->space[journal_space_clean_ondisk].total);
|
||||
pr_buf(out, "\tclean\t\t%u:%u\n",
|
||||
prt_printf(out, "\tclean\t\t%u:%u\n",
|
||||
j->space[journal_space_clean].next_entry,
|
||||
j->space[journal_space_clean].total);
|
||||
pr_buf(out, "\ttotal\t\t%u:%u\n",
|
||||
prt_printf(out, "\ttotal\t\t%u:%u\n",
|
||||
j->space[journal_space_total].next_entry,
|
||||
j->space[journal_space_total].total);
|
||||
|
||||
@ -1351,14 +1352,14 @@ void __bch2_journal_debug_to_text(struct printbuf *out, struct journal *j)
|
||||
if (!ja->nr)
|
||||
continue;
|
||||
|
||||
pr_buf(out, "dev %u:\n", i);
|
||||
pr_buf(out, "\tnr\t\t%u\n", ja->nr);
|
||||
pr_buf(out, "\tbucket size\t%u\n", ca->mi.bucket_size);
|
||||
pr_buf(out, "\tavailable\t%u:%u\n", bch2_journal_dev_buckets_available(j, ja, journal_space_discarded), ja->sectors_free);
|
||||
pr_buf(out, "\tdiscard_idx\t%u\n", ja->discard_idx);
|
||||
pr_buf(out, "\tdirty_ondisk\t%u (seq %llu)\n", ja->dirty_idx_ondisk, ja->bucket_seq[ja->dirty_idx_ondisk]);
|
||||
pr_buf(out, "\tdirty_idx\t%u (seq %llu)\n", ja->dirty_idx, ja->bucket_seq[ja->dirty_idx]);
|
||||
pr_buf(out, "\tcur_idx\t\t%u (seq %llu)\n", ja->cur_idx, ja->bucket_seq[ja->cur_idx]);
|
||||
prt_printf(out, "dev %u:\n", i);
|
||||
prt_printf(out, "\tnr\t\t%u\n", ja->nr);
|
||||
prt_printf(out, "\tbucket size\t%u\n", ca->mi.bucket_size);
|
||||
prt_printf(out, "\tavailable\t%u:%u\n", bch2_journal_dev_buckets_available(j, ja, journal_space_discarded), ja->sectors_free);
|
||||
prt_printf(out, "\tdiscard_idx\t%u\n", ja->discard_idx);
|
||||
prt_printf(out, "\tdirty_ondisk\t%u (seq %llu)\n", ja->dirty_idx_ondisk, ja->bucket_seq[ja->dirty_idx_ondisk]);
|
||||
prt_printf(out, "\tdirty_idx\t%u (seq %llu)\n", ja->dirty_idx, ja->bucket_seq[ja->dirty_idx]);
|
||||
prt_printf(out, "\tcur_idx\t\t%u (seq %llu)\n", ja->cur_idx, ja->bucket_seq[ja->cur_idx]);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
@ -1390,31 +1391,31 @@ bool bch2_journal_seq_pins_to_text(struct printbuf *out, struct journal *j, u64
|
||||
|
||||
pin_list = journal_seq_pin(j, *seq);
|
||||
|
||||
pr_buf(out, "%llu: count %u", *seq, atomic_read(&pin_list->count));
|
||||
pr_newline(out);
|
||||
pr_indent_push(out, 2);
|
||||
prt_printf(out, "%llu: count %u", *seq, atomic_read(&pin_list->count));
|
||||
prt_newline(out);
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
list_for_each_entry(pin, &pin_list->list, list) {
|
||||
pr_buf(out, "\t%px %ps", pin, pin->flush);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "\t%px %ps", pin, pin->flush);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
list_for_each_entry(pin, &pin_list->key_cache_list, list) {
|
||||
pr_buf(out, "\t%px %ps", pin, pin->flush);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "\t%px %ps", pin, pin->flush);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
if (!list_empty(&pin_list->flushed)) {
|
||||
pr_buf(out, "flushed:");
|
||||
pr_newline(out);
|
||||
prt_printf(out, "flushed:");
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
list_for_each_entry(pin, &pin_list->flushed, list) {
|
||||
pr_buf(out, "\t%px %ps", pin, pin->flush);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "\t%px %ps", pin, pin->flush);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
|
||||
--out->atomic;
|
||||
spin_unlock(&j->lock);
|
||||
|
@ -259,15 +259,15 @@ static int journal_validate_key(struct bch_fs *c, const char *where,
|
||||
if (bch2_bkey_invalid(c, bkey_i_to_s_c(k),
|
||||
__btree_node_type(level, btree_id), write, &buf)) {
|
||||
printbuf_reset(&buf);
|
||||
pr_buf(&buf, "invalid key in %s at %s offset %zi/%u:",
|
||||
prt_printf(&buf, "invalid key in %s at %s offset %zi/%u:",
|
||||
bch2_jset_entry_types[entry->type], where,
|
||||
(u64 *) k - entry->_data,
|
||||
le16_to_cpu(entry->u64s));
|
||||
pr_newline(&buf);
|
||||
pr_indent_push(&buf, 2);
|
||||
prt_newline(&buf);
|
||||
printbuf_indent_add(&buf, 2);
|
||||
|
||||
bch2_bkey_val_to_text(&buf, c, bkey_i_to_s_c(k));
|
||||
pr_newline(&buf);
|
||||
prt_newline(&buf);
|
||||
bch2_bkey_invalid(c, bkey_i_to_s_c(k),
|
||||
__btree_node_type(level, btree_id), write, &buf);
|
||||
|
||||
@ -318,10 +318,10 @@ static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs
|
||||
|
||||
vstruct_for_each(entry, k) {
|
||||
if (!first) {
|
||||
pr_newline(out);
|
||||
pr_buf(out, "%s: ", bch2_jset_entry_types[entry->type]);
|
||||
prt_newline(out);
|
||||
prt_printf(out, "%s: ", bch2_jset_entry_types[entry->type]);
|
||||
}
|
||||
pr_buf(out, "btree=%s l=%u ", bch2_btree_ids[entry->btree_id], entry->level);
|
||||
prt_printf(out, "btree=%s l=%u ", bch2_btree_ids[entry->btree_id], entry->level);
|
||||
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(k));
|
||||
first = false;
|
||||
}
|
||||
@ -396,7 +396,7 @@ static void journal_entry_blacklist_to_text(struct printbuf *out, struct bch_fs
|
||||
struct jset_entry_blacklist *bl =
|
||||
container_of(entry, struct jset_entry_blacklist, entry);
|
||||
|
||||
pr_buf(out, "seq=%llu", le64_to_cpu(bl->seq));
|
||||
prt_printf(out, "seq=%llu", le64_to_cpu(bl->seq));
|
||||
}
|
||||
|
||||
static int journal_entry_blacklist_v2_validate(struct bch_fs *c,
|
||||
@ -431,7 +431,7 @@ static void journal_entry_blacklist_v2_to_text(struct printbuf *out, struct bch_
|
||||
struct jset_entry_blacklist_v2 *bl =
|
||||
container_of(entry, struct jset_entry_blacklist_v2, entry);
|
||||
|
||||
pr_buf(out, "start=%llu end=%llu",
|
||||
prt_printf(out, "start=%llu end=%llu",
|
||||
le64_to_cpu(bl->start),
|
||||
le64_to_cpu(bl->end));
|
||||
}
|
||||
@ -463,7 +463,7 @@ static void journal_entry_usage_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct jset_entry_usage *u =
|
||||
container_of(entry, struct jset_entry_usage, entry);
|
||||
|
||||
pr_buf(out, "type=%s v=%llu",
|
||||
prt_printf(out, "type=%s v=%llu",
|
||||
bch2_fs_usage_types[u->entry.btree_id],
|
||||
le64_to_cpu(u->v));
|
||||
}
|
||||
@ -497,7 +497,7 @@ static void journal_entry_data_usage_to_text(struct printbuf *out, struct bch_fs
|
||||
container_of(entry, struct jset_entry_data_usage, entry);
|
||||
|
||||
bch2_replicas_entry_to_text(out, &u->r);
|
||||
pr_buf(out, "=%llu", le64_to_cpu(u->v));
|
||||
prt_printf(out, "=%llu", le64_to_cpu(u->v));
|
||||
}
|
||||
|
||||
static int journal_entry_clock_validate(struct bch_fs *c,
|
||||
@ -532,7 +532,7 @@ static void journal_entry_clock_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct jset_entry_clock *clock =
|
||||
container_of(entry, struct jset_entry_clock, entry);
|
||||
|
||||
pr_buf(out, "%s=%llu", clock->rw ? "write" : "read", le64_to_cpu(clock->time));
|
||||
prt_printf(out, "%s=%llu", clock->rw ? "write" : "read", le64_to_cpu(clock->time));
|
||||
}
|
||||
|
||||
static int journal_entry_dev_usage_validate(struct bch_fs *c,
|
||||
@ -579,20 +579,20 @@ static void journal_entry_dev_usage_to_text(struct printbuf *out, struct bch_fs
|
||||
container_of(entry, struct jset_entry_dev_usage, entry);
|
||||
unsigned i, nr_types = jset_entry_dev_usage_nr_types(u);
|
||||
|
||||
pr_buf(out, "dev=%u", le32_to_cpu(u->dev));
|
||||
prt_printf(out, "dev=%u", le32_to_cpu(u->dev));
|
||||
|
||||
for (i = 0; i < nr_types; i++) {
|
||||
if (i < BCH_DATA_NR)
|
||||
pr_buf(out, " %s", bch2_data_types[i]);
|
||||
prt_printf(out, " %s", bch2_data_types[i]);
|
||||
else
|
||||
pr_buf(out, " (unknown data type %u)", i);
|
||||
pr_buf(out, ": buckets=%llu sectors=%llu fragmented=%llu",
|
||||
prt_printf(out, " (unknown data type %u)", i);
|
||||
prt_printf(out, ": buckets=%llu sectors=%llu fragmented=%llu",
|
||||
le64_to_cpu(u->d[i].buckets),
|
||||
le64_to_cpu(u->d[i].sectors),
|
||||
le64_to_cpu(u->d[i].fragmented));
|
||||
}
|
||||
|
||||
pr_buf(out, " buckets_ec: %llu", le64_to_cpu(u->buckets_ec));
|
||||
prt_printf(out, " buckets_ec: %llu", le64_to_cpu(u->buckets_ec));
|
||||
}
|
||||
|
||||
static int journal_entry_log_validate(struct bch_fs *c,
|
||||
@ -609,7 +609,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);
|
||||
|
||||
pr_buf(out, "%.*s", bytes, l->d);
|
||||
prt_printf(out, "%.*s", bytes, l->d);
|
||||
}
|
||||
|
||||
static int journal_entry_overwrite_validate(struct bch_fs *c, const char *where,
|
||||
@ -655,10 +655,10 @@ void bch2_journal_entry_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
struct jset_entry *entry)
|
||||
{
|
||||
if (entry->type < BCH_JSET_ENTRY_NR) {
|
||||
pr_buf(out, "%s: ", bch2_jset_entry_types[entry->type]);
|
||||
prt_printf(out, "%s: ", bch2_jset_entry_types[entry->type]);
|
||||
bch2_jset_entry_ops[entry->type].to_text(out, c, entry);
|
||||
} else {
|
||||
pr_buf(out, "(unknown type %u)", entry->type);
|
||||
prt_printf(out, "(unknown type %u)", entry->type);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1039,8 +1039,8 @@ void bch2_journal_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
div64_u64_rem(j->ptrs[i].sector, ca->mi.bucket_size, &offset);
|
||||
|
||||
if (i)
|
||||
pr_buf(out, " ");
|
||||
pr_buf(out, "%u:%u:%u (sector %llu)",
|
||||
prt_printf(out, " ");
|
||||
prt_printf(out, "%u:%u:%u (sector %llu)",
|
||||
j->ptrs[i].dev,
|
||||
j->ptrs[i].bucket,
|
||||
j->ptrs[i].bucket_offset,
|
||||
@ -1172,9 +1172,9 @@ int bch2_journal_read(struct bch_fs *c, u64 *blacklist_seq, u64 *start_seq)
|
||||
|
||||
if (prev) {
|
||||
bch2_journal_ptrs_to_text(&buf1, c, prev);
|
||||
pr_buf(&buf1, " size %zu", vstruct_sectors(&prev->j, c->block_bits));
|
||||
prt_printf(&buf1, " size %zu", vstruct_sectors(&prev->j, c->block_bits));
|
||||
} else
|
||||
pr_buf(&buf1, "(none)");
|
||||
prt_printf(&buf1, "(none)");
|
||||
bch2_journal_ptrs_to_text(&buf2, c, i);
|
||||
|
||||
missing_end = seq - 1;
|
||||
|
@ -41,25 +41,25 @@ static int bch2_sb_journal_validate(struct bch_sb *sb,
|
||||
sort(b, nr, sizeof(u64), u64_cmp, NULL);
|
||||
|
||||
if (!b[0]) {
|
||||
pr_buf(err, "journal bucket at sector 0");
|
||||
prt_printf(err, "journal bucket at sector 0");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b[0] < le16_to_cpu(m->first_bucket)) {
|
||||
pr_buf(err, "journal bucket %llu before first bucket %u",
|
||||
prt_printf(err, "journal bucket %llu before first bucket %u",
|
||||
b[0], le16_to_cpu(m->first_bucket));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b[nr - 1] >= le64_to_cpu(m->nbuckets)) {
|
||||
pr_buf(err, "journal bucket %llu past end of device (nbuckets %llu)",
|
||||
prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
|
||||
b[nr - 1], le64_to_cpu(m->nbuckets));
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i + 1 < nr; i++)
|
||||
if (b[i] == b[i + 1]) {
|
||||
pr_buf(err, "duplicate journal buckets %llu", b[i]);
|
||||
prt_printf(err, "duplicate journal buckets %llu", b[i]);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -75,10 +75,10 @@ static void bch2_sb_journal_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
struct bch_sb_field_journal *journal = field_to_type(f, journal);
|
||||
unsigned i, nr = bch2_nr_journal_buckets(journal);
|
||||
|
||||
pr_buf(out, "Buckets: ");
|
||||
prt_printf(out, "Buckets: ");
|
||||
for (i = 0; i < nr; i++)
|
||||
pr_buf(out, " %llu", le64_to_cpu(journal->buckets[i]));
|
||||
pr_newline(out);
|
||||
prt_printf(out, " %llu", le64_to_cpu(journal->buckets[i]));
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_journal = {
|
||||
@ -126,25 +126,25 @@ static int bch2_sb_journal_v2_validate(struct bch_sb *sb,
|
||||
sort(b, nr, sizeof(*b), u64_range_cmp, NULL);
|
||||
|
||||
if (!b[0].start) {
|
||||
pr_buf(err, "journal bucket at sector 0");
|
||||
prt_printf(err, "journal bucket at sector 0");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b[0].start < le16_to_cpu(m->first_bucket)) {
|
||||
pr_buf(err, "journal bucket %llu before first bucket %u",
|
||||
prt_printf(err, "journal bucket %llu before first bucket %u",
|
||||
b[0].start, le16_to_cpu(m->first_bucket));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (b[nr - 1].end > le64_to_cpu(m->nbuckets)) {
|
||||
pr_buf(err, "journal bucket %llu past end of device (nbuckets %llu)",
|
||||
prt_printf(err, "journal bucket %llu past end of device (nbuckets %llu)",
|
||||
b[nr - 1].end - 1, le64_to_cpu(m->nbuckets));
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i + 1 < nr; i++) {
|
||||
if (b[i].end > b[i + 1].start) {
|
||||
pr_buf(err, "duplicate journal buckets in ranges %llu-%llu, %llu-%llu",
|
||||
prt_printf(err, "duplicate journal buckets in ranges %llu-%llu, %llu-%llu",
|
||||
b[i].start, b[i].end, b[i + 1].start, b[i + 1].end);
|
||||
goto err;
|
||||
}
|
||||
@ -162,12 +162,12 @@ static void bch2_sb_journal_v2_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
struct bch_sb_field_journal_v2 *journal = field_to_type(f, journal_v2);
|
||||
unsigned i, nr = bch2_sb_field_journal_v2_nr_entries(journal);
|
||||
|
||||
pr_buf(out, "Buckets: ");
|
||||
prt_printf(out, "Buckets: ");
|
||||
for (i = 0; i < nr; i++)
|
||||
pr_buf(out, " %llu-%llu",
|
||||
prt_printf(out, " %llu-%llu",
|
||||
le64_to_cpu(journal->d[i].start),
|
||||
le64_to_cpu(journal->d[i].start) + le64_to_cpu(journal->d[i].nr));
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_journal_v2 = {
|
||||
|
@ -201,7 +201,7 @@ static int bch2_sb_journal_seq_blacklist_validate(struct bch_sb *sb,
|
||||
|
||||
if (le64_to_cpu(e->start) >=
|
||||
le64_to_cpu(e->end)) {
|
||||
pr_buf(err, "entry %u start >= end (%llu >= %llu)",
|
||||
prt_printf(err, "entry %u start >= end (%llu >= %llu)",
|
||||
i, le64_to_cpu(e->start), le64_to_cpu(e->end));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -209,7 +209,7 @@ static int bch2_sb_journal_seq_blacklist_validate(struct bch_sb *sb,
|
||||
if (i + 1 < nr &&
|
||||
le64_to_cpu(e[0].end) >
|
||||
le64_to_cpu(e[1].start)) {
|
||||
pr_buf(err, "entry %u out of order with next entry (%llu > %llu)",
|
||||
prt_printf(err, "entry %u out of order with next entry (%llu > %llu)",
|
||||
i + 1, le64_to_cpu(e[0].end), le64_to_cpu(e[1].start));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -229,13 +229,13 @@ static void bch2_sb_journal_seq_blacklist_to_text(struct printbuf *out,
|
||||
|
||||
for (i = bl->start; i < bl->start + nr; i++) {
|
||||
if (i != bl->start)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
|
||||
pr_buf(out, "%llu-%llu",
|
||||
prt_printf(out, "%llu-%llu",
|
||||
le64_to_cpu(i->start),
|
||||
le64_to_cpu(i->end));
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_journal_seq_blacklist = {
|
||||
|
@ -14,7 +14,7 @@ int bch2_lru_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
const struct bch_lru *lru = bkey_s_c_to_lru(k).v;
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(*lru)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*lru));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -27,7 +27,7 @@ void bch2_lru_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
const struct bch_lru *lru = bkey_s_c_to_lru(k).v;
|
||||
|
||||
pr_buf(out, "idx %llu", le64_to_cpu(lru->idx));
|
||||
prt_printf(out, "idx %llu", le64_to_cpu(lru->idx));
|
||||
}
|
||||
|
||||
int bch2_lru_delete(struct btree_trans *trans, u64 id, u64 idx, u64 time,
|
||||
|
@ -228,28 +228,28 @@ int bch2_opt_validate(const struct bch_option *opt, u64 v, struct printbuf *err)
|
||||
{
|
||||
if (v < opt->min) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: too small (min %llu)",
|
||||
prt_printf(err, "%s: too small (min %llu)",
|
||||
opt->attr.name, opt->min);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if (opt->max && v >= opt->max) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: too big (max %llu)",
|
||||
prt_printf(err, "%s: too big (max %llu)",
|
||||
opt->attr.name, opt->max);
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
if ((opt->flags & OPT_SB_FIELD_SECTORS) && (v & 511)) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: not a multiple of 512",
|
||||
prt_printf(err, "%s: not a multiple of 512",
|
||||
opt->attr.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((opt->flags & OPT_MUST_BE_POW_2) && !is_power_of_2(v)) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: must be a power of two",
|
||||
prt_printf(err, "%s: must be a power of two",
|
||||
opt->attr.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -269,8 +269,8 @@ int bch2_opt_parse(struct bch_fs *c,
|
||||
ret = kstrtou64(val, 10, res);
|
||||
if (ret < 0 || (*res != 0 && *res != 1)) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: must be bool",
|
||||
opt->attr.name);
|
||||
prt_printf(err, "%s: must be bool",
|
||||
opt->attr.name);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
@ -280,8 +280,8 @@ int bch2_opt_parse(struct bch_fs *c,
|
||||
: kstrtou64(val, 10, res);
|
||||
if (ret < 0) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: must be a number",
|
||||
opt->attr.name);
|
||||
prt_printf(err, "%s: must be a number",
|
||||
opt->attr.name);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
@ -289,8 +289,8 @@ int bch2_opt_parse(struct bch_fs *c,
|
||||
ret = match_string(opt->choices, -1, val);
|
||||
if (ret < 0) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: invalid selection",
|
||||
opt->attr.name);
|
||||
prt_printf(err, "%s: invalid selection",
|
||||
opt->attr.name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -303,8 +303,8 @@ int bch2_opt_parse(struct bch_fs *c,
|
||||
ret = opt->parse(c, val, res);
|
||||
if (ret < 0) {
|
||||
if (err)
|
||||
pr_buf(err, "%s: parse error",
|
||||
opt->attr.name);
|
||||
prt_printf(err, "%s: parse error",
|
||||
opt->attr.name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@ -319,28 +319,28 @@ void bch2_opt_to_text(struct printbuf *out,
|
||||
{
|
||||
if (flags & OPT_SHOW_MOUNT_STYLE) {
|
||||
if (opt->type == BCH_OPT_BOOL) {
|
||||
pr_buf(out, "%s%s",
|
||||
prt_printf(out, "%s%s",
|
||||
v ? "" : "no",
|
||||
opt->attr.name);
|
||||
return;
|
||||
}
|
||||
|
||||
pr_buf(out, "%s=", opt->attr.name);
|
||||
prt_printf(out, "%s=", opt->attr.name);
|
||||
}
|
||||
|
||||
switch (opt->type) {
|
||||
case BCH_OPT_BOOL:
|
||||
case BCH_OPT_UINT:
|
||||
if (opt->flags & OPT_HUMAN_READABLE)
|
||||
bch2_hprint(out, v);
|
||||
prt_human_readable_u64(out, v);
|
||||
else
|
||||
pr_buf(out, "%lli", v);
|
||||
prt_printf(out, "%lli", v);
|
||||
break;
|
||||
case BCH_OPT_STR:
|
||||
if (flags & OPT_SHOW_FULL_LIST)
|
||||
bch2_string_opt_to_text(out, opt->choices, v);
|
||||
prt_string_option(out, opt->choices, v);
|
||||
else
|
||||
pr_buf(out, "%s", opt->choices[v]);
|
||||
prt_printf(out, "%s", opt->choices[v]);
|
||||
break;
|
||||
case BCH_OPT_FN:
|
||||
opt->to_text(out, c, sb, v);
|
||||
|
415
fs/bcachefs/printbuf.c
Normal file
415
fs/bcachefs/printbuf.c
Normal file
@ -0,0 +1,415 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1+
|
||||
/* Copyright (C) 2022 Kent Overstreet */
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string_helpers.h>
|
||||
|
||||
#include "printbuf.h"
|
||||
|
||||
static inline unsigned printbuf_linelen(struct printbuf *buf)
|
||||
{
|
||||
return buf->pos - buf->last_newline;
|
||||
}
|
||||
|
||||
int bch2_printbuf_make_room(struct printbuf *out, unsigned extra)
|
||||
{
|
||||
unsigned new_size;
|
||||
char *buf;
|
||||
|
||||
if (!out->heap_allocated)
|
||||
return 0;
|
||||
|
||||
/* Reserved space for terminating nul: */
|
||||
extra += 1;
|
||||
|
||||
if (out->pos + extra < out->size)
|
||||
return 0;
|
||||
|
||||
new_size = roundup_pow_of_two(out->size + extra);
|
||||
|
||||
/*
|
||||
* Note: output buffer must be freeable with kfree(), it's not required
|
||||
* that the user use printbuf_exit().
|
||||
*/
|
||||
buf = krealloc(out->buf, new_size, !out->atomic ? GFP_KERNEL : GFP_NOWAIT);
|
||||
|
||||
if (!buf) {
|
||||
out->allocation_failure = true;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
out->buf = buf;
|
||||
out->size = new_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bch2_prt_vprintf(struct printbuf *out, const char *fmt, va_list args)
|
||||
{
|
||||
int len;
|
||||
|
||||
do {
|
||||
va_list args2;
|
||||
|
||||
va_copy(args2, args);
|
||||
len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args2);
|
||||
} while (len + 1 >= printbuf_remaining(out) &&
|
||||
!bch2_printbuf_make_room(out, len + 1));
|
||||
|
||||
len = min_t(size_t, len,
|
||||
printbuf_remaining(out) ? printbuf_remaining(out) - 1 : 0);
|
||||
out->pos += len;
|
||||
}
|
||||
|
||||
void bch2_prt_printf(struct printbuf *out, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
do {
|
||||
va_start(args, fmt);
|
||||
len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args);
|
||||
va_end(args);
|
||||
} while (len + 1 >= printbuf_remaining(out) &&
|
||||
!bch2_printbuf_make_room(out, len + 1));
|
||||
|
||||
len = min_t(size_t, len,
|
||||
printbuf_remaining(out) ? printbuf_remaining(out) - 1 : 0);
|
||||
out->pos += len;
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_str - returns printbuf's buf as a C string, guaranteed to be null
|
||||
* terminated
|
||||
*/
|
||||
const char *bch2_printbuf_str(const struct printbuf *buf)
|
||||
{
|
||||
/*
|
||||
* If we've written to a printbuf then it's guaranteed to be a null
|
||||
* terminated string - but if we haven't, then we might not have
|
||||
* allocated a buffer at all:
|
||||
*/
|
||||
return buf->pos
|
||||
? buf->buf
|
||||
: "";
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_exit - exit a printbuf, freeing memory it owns and poisoning it
|
||||
* against accidental use.
|
||||
*/
|
||||
void bch2_printbuf_exit(struct printbuf *buf)
|
||||
{
|
||||
if (buf->heap_allocated) {
|
||||
kfree(buf->buf);
|
||||
buf->buf = ERR_PTR(-EINTR); /* poison value */
|
||||
}
|
||||
}
|
||||
|
||||
void bch2_printbuf_tabstops_reset(struct printbuf *buf)
|
||||
{
|
||||
buf->nr_tabstops = 0;
|
||||
}
|
||||
|
||||
void bch2_printbuf_tabstop_pop(struct printbuf *buf)
|
||||
{
|
||||
if (buf->nr_tabstops)
|
||||
--buf->nr_tabstops;
|
||||
}
|
||||
|
||||
/*
|
||||
* printbuf_tabstop_set - add a tabstop, n spaces from the previous tabstop
|
||||
*
|
||||
* @buf: printbuf to control
|
||||
* @spaces: number of spaces from previous tabpstop
|
||||
*
|
||||
* In the future this function may allocate memory if setting more than
|
||||
* PRINTBUF_INLINE_TABSTOPS or setting tabstops more than 255 spaces from start
|
||||
* of line.
|
||||
*/
|
||||
int bch2_printbuf_tabstop_push(struct printbuf *buf, unsigned spaces)
|
||||
{
|
||||
unsigned prev_tabstop = buf->nr_tabstops
|
||||
? buf->_tabstops[buf->nr_tabstops - 1]
|
||||
: 0;
|
||||
|
||||
if (WARN_ON(buf->nr_tabstops >= ARRAY_SIZE(buf->_tabstops)))
|
||||
return -EINVAL;
|
||||
|
||||
buf->_tabstops[buf->nr_tabstops++] = prev_tabstop + spaces;
|
||||
buf->has_indent_or_tabstops = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_indent_add - add to the current indent level
|
||||
*
|
||||
* @buf: printbuf to control
|
||||
* @spaces: number of spaces to add to the current indent level
|
||||
*
|
||||
* Subsequent lines, and the current line if the output position is at the start
|
||||
* of the current line, will be indented by @spaces more spaces.
|
||||
*/
|
||||
void bch2_printbuf_indent_add(struct printbuf *buf, unsigned spaces)
|
||||
{
|
||||
if (WARN_ON_ONCE(buf->indent + spaces < buf->indent))
|
||||
spaces = 0;
|
||||
|
||||
buf->indent += spaces;
|
||||
prt_chars(buf, ' ', spaces);
|
||||
|
||||
buf->has_indent_or_tabstops = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_indent_sub - subtract from the current indent level
|
||||
*
|
||||
* @buf: printbuf to control
|
||||
* @spaces: number of spaces to subtract from the current indent level
|
||||
*
|
||||
* Subsequent lines, and the current line if the output position is at the start
|
||||
* of the current line, will be indented by @spaces less spaces.
|
||||
*/
|
||||
void bch2_printbuf_indent_sub(struct printbuf *buf, unsigned spaces)
|
||||
{
|
||||
if (WARN_ON_ONCE(spaces > buf->indent))
|
||||
spaces = buf->indent;
|
||||
|
||||
if (buf->last_newline + buf->indent == buf->pos) {
|
||||
buf->pos -= spaces;
|
||||
printbuf_nul_terminate(buf);
|
||||
}
|
||||
buf->indent -= spaces;
|
||||
|
||||
if (!buf->indent && !buf->nr_tabstops)
|
||||
buf->has_indent_or_tabstops = false;
|
||||
}
|
||||
|
||||
void bch2_prt_newline(struct printbuf *buf)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
bch2_printbuf_make_room(buf, 1 + buf->indent);
|
||||
|
||||
__prt_char(buf, '\n');
|
||||
|
||||
buf->last_newline = buf->pos;
|
||||
|
||||
for (i = 0; i < buf->indent; i++)
|
||||
__prt_char(buf, ' ');
|
||||
|
||||
printbuf_nul_terminate(buf);
|
||||
|
||||
buf->last_field = buf->pos;
|
||||
buf->cur_tabstop = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns spaces from start of line, if set, or 0 if unset:
|
||||
*/
|
||||
static inline unsigned cur_tabstop(struct printbuf *buf)
|
||||
{
|
||||
return buf->cur_tabstop < buf->nr_tabstops
|
||||
? buf->_tabstops[buf->cur_tabstop]
|
||||
: 0;
|
||||
}
|
||||
|
||||
static void __prt_tab(struct printbuf *out)
|
||||
{
|
||||
int spaces = max_t(int, 0, cur_tabstop(out) - printbuf_linelen(out));
|
||||
|
||||
prt_chars(out, ' ', spaces);
|
||||
|
||||
out->last_field = out->pos;
|
||||
out->cur_tabstop++;
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_tab - Advance printbuf to the next tabstop
|
||||
*
|
||||
* @buf: printbuf to control
|
||||
*
|
||||
* Advance output to the next tabstop by printing spaces.
|
||||
*/
|
||||
void bch2_prt_tab(struct printbuf *out)
|
||||
{
|
||||
if (WARN_ON(!cur_tabstop(out)))
|
||||
return;
|
||||
|
||||
__prt_tab(out);
|
||||
}
|
||||
|
||||
static void __prt_tab_rjust(struct printbuf *buf)
|
||||
{
|
||||
unsigned move = buf->pos - buf->last_field;
|
||||
int pad = (int) cur_tabstop(buf) - (int) printbuf_linelen(buf);
|
||||
|
||||
if (pad > 0) {
|
||||
bch2_printbuf_make_room(buf, pad);
|
||||
|
||||
if (buf->last_field + pad < buf->size)
|
||||
memmove(buf->buf + buf->last_field + pad,
|
||||
buf->buf + buf->last_field,
|
||||
min(move, buf->size - 1 - buf->last_field - pad));
|
||||
|
||||
if (buf->last_field < buf->size)
|
||||
memset(buf->buf + buf->last_field, ' ',
|
||||
min((unsigned) pad, buf->size - buf->last_field));
|
||||
|
||||
buf->pos += pad;
|
||||
printbuf_nul_terminate(buf);
|
||||
}
|
||||
|
||||
buf->last_field = buf->pos;
|
||||
buf->cur_tabstop++;
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_tab_rjust - Advance printbuf to the next tabstop, right justifying
|
||||
* previous output
|
||||
*
|
||||
* @buf: printbuf to control
|
||||
*
|
||||
* Advance output to the next tabstop by inserting spaces immediately after the
|
||||
* previous tabstop, right justifying previously outputted text.
|
||||
*/
|
||||
void bch2_prt_tab_rjust(struct printbuf *buf)
|
||||
{
|
||||
if (WARN_ON(!cur_tabstop(buf)))
|
||||
return;
|
||||
|
||||
__prt_tab_rjust(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_bytes_indented - Print an array of chars, handling embedded control characters
|
||||
*
|
||||
* @out: printbuf to output to
|
||||
* @str: string to print
|
||||
* @count: number of bytes to print
|
||||
*
|
||||
* The following contol characters are handled as so:
|
||||
* \n: prt_newline newline that obeys current indent level
|
||||
* \t: prt_tab advance to next tabstop
|
||||
* \r: prt_tab_rjust advance to next tabstop, with right justification
|
||||
*/
|
||||
void bch2_prt_bytes_indented(struct printbuf *out, const char *str, unsigned count)
|
||||
{
|
||||
const char *unprinted_start = str;
|
||||
const char *end = str + count;
|
||||
|
||||
if (!out->has_indent_or_tabstops || out->suppress_indent_tabstop_handling) {
|
||||
prt_bytes(out, str, count);
|
||||
return;
|
||||
}
|
||||
|
||||
while (str != end) {
|
||||
switch (*str) {
|
||||
case '\n':
|
||||
prt_bytes(out, unprinted_start, str - unprinted_start);
|
||||
unprinted_start = str + 1;
|
||||
bch2_prt_newline(out);
|
||||
break;
|
||||
case '\t':
|
||||
if (likely(cur_tabstop(out))) {
|
||||
prt_bytes(out, unprinted_start, str - unprinted_start);
|
||||
unprinted_start = str + 1;
|
||||
__prt_tab(out);
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
if (likely(cur_tabstop(out))) {
|
||||
prt_bytes(out, unprinted_start, str - unprinted_start);
|
||||
unprinted_start = str + 1;
|
||||
__prt_tab_rjust(out);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
|
||||
prt_bytes(out, unprinted_start, str - unprinted_start);
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_human_readable_u64 - Print out a u64 in human readable units
|
||||
*
|
||||
* Units of 2^10 (default) or 10^3 are controlled via @buf->si_units
|
||||
*/
|
||||
void bch2_prt_human_readable_u64(struct printbuf *buf, u64 v)
|
||||
{
|
||||
bch2_printbuf_make_room(buf, 10);
|
||||
buf->pos += string_get_size(v, 1, !buf->si_units,
|
||||
buf->buf + buf->pos,
|
||||
printbuf_remaining_size(buf));
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_human_readable_s64 - Print out a s64 in human readable units
|
||||
*
|
||||
* Units of 2^10 (default) or 10^3 are controlled via @buf->si_units
|
||||
*/
|
||||
void bch2_prt_human_readable_s64(struct printbuf *buf, s64 v)
|
||||
{
|
||||
if (v < 0)
|
||||
prt_char(buf, '-');
|
||||
bch2_prt_human_readable_u64(buf, abs(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_units_u64 - Print out a u64 according to printbuf unit options
|
||||
*
|
||||
* Units are either raw (default), or human reabable units (controlled via
|
||||
* @buf->human_readable_units)
|
||||
*/
|
||||
void bch2_prt_units_u64(struct printbuf *out, u64 v)
|
||||
{
|
||||
if (out->human_readable_units)
|
||||
bch2_prt_human_readable_u64(out, v);
|
||||
else
|
||||
bch2_prt_printf(out, "%llu", v);
|
||||
}
|
||||
|
||||
/**
|
||||
* prt_units_s64 - Print out a s64 according to printbuf unit options
|
||||
*
|
||||
* Units are either raw (default), or human reabable units (controlled via
|
||||
* @buf->human_readable_units)
|
||||
*/
|
||||
void bch2_prt_units_s64(struct printbuf *out, s64 v)
|
||||
{
|
||||
if (v < 0)
|
||||
prt_char(out, '-');
|
||||
bch2_prt_units_u64(out, abs(v));
|
||||
}
|
||||
|
||||
void bch2_prt_string_option(struct printbuf *out,
|
||||
const char * const list[],
|
||||
size_t selected)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; list[i]; i++)
|
||||
bch2_prt_printf(out, i == selected ? "[%s] " : "%s ", list[i]);
|
||||
}
|
||||
|
||||
void bch2_prt_bitflags(struct printbuf *out,
|
||||
const char * const list[], u64 flags)
|
||||
{
|
||||
unsigned bit, nr = 0;
|
||||
bool first = true;
|
||||
|
||||
while (list[nr])
|
||||
nr++;
|
||||
|
||||
while (flags && (bit = __ffs(flags)) < nr) {
|
||||
if (!first)
|
||||
bch2_prt_printf(out, ",");
|
||||
first = false;
|
||||
bch2_prt_printf(out, "%s", list[bit]);
|
||||
flags ^= 1 << bit;
|
||||
}
|
||||
}
|
284
fs/bcachefs/printbuf.h
Normal file
284
fs/bcachefs/printbuf.h
Normal file
@ -0,0 +1,284 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/* Copyright (C) 2022 Kent Overstreet */
|
||||
|
||||
#ifndef _BCACHEFS_PRINTBUF_H
|
||||
#define _BCACHEFS_PRINTBUF_H
|
||||
|
||||
/*
|
||||
* Printbufs: Simple strings for printing to, with optional heap allocation
|
||||
*
|
||||
* This code has provisions for use in userspace, to aid in making other code
|
||||
* portable between kernelspace and userspace.
|
||||
*
|
||||
* Basic example:
|
||||
* struct printbuf buf = PRINTBUF;
|
||||
*
|
||||
* prt_printf(&buf, "foo=");
|
||||
* foo_to_text(&buf, foo);
|
||||
* printk("%s", buf.buf);
|
||||
* printbuf_exit(&buf);
|
||||
*
|
||||
* Or
|
||||
* struct printbuf buf = PRINTBUF_EXTERN(char_buf, char_buf_size)
|
||||
*
|
||||
* We can now write pretty printers instead of writing code that dumps
|
||||
* everything to the kernel log buffer, and then those pretty-printers can be
|
||||
* used by other code that outputs to kernel log, sysfs, debugfs, etc.
|
||||
*
|
||||
* Memory allocation: Outputing to a printbuf may allocate memory. This
|
||||
* allocation is done with GFP_KERNEL, by default: use the newer
|
||||
* memalloc_*_(save|restore) functions as needed.
|
||||
*
|
||||
* Since no equivalent yet exists for GFP_ATOMIC/GFP_NOWAIT, memory allocations
|
||||
* will be done with GFP_NOWAIT if printbuf->atomic is nonzero.
|
||||
*
|
||||
* It's allowed to grab the output buffer and free it later with kfree() instead
|
||||
* of using printbuf_exit(), if the user just needs a heap allocated string at
|
||||
* the end.
|
||||
*
|
||||
* Memory allocation failures: We don't return errors directly, because on
|
||||
* memory allocation failure we usually don't want to bail out and unwind - we
|
||||
* want to print what we've got, on a best-effort basis. But code that does want
|
||||
* to return -ENOMEM may check printbuf.allocation_failure.
|
||||
*
|
||||
* Indenting, tabstops:
|
||||
*
|
||||
* To aid is writing multi-line pretty printers spread across multiple
|
||||
* functions, printbufs track the current indent level.
|
||||
*
|
||||
* printbuf_indent_push() and printbuf_indent_pop() increase and decrease the current indent
|
||||
* level, respectively.
|
||||
*
|
||||
* To use tabstops, set printbuf->tabstops[]; they are in units of spaces, from
|
||||
* start of line. Once set, prt_tab() will output spaces up to the next tabstop.
|
||||
* prt_tab_rjust() will also advance the current line of text up to the next
|
||||
* tabstop, but it does so by shifting text since the previous tabstop up to the
|
||||
* next tabstop - right justifying it.
|
||||
*
|
||||
* Make sure you use prt_newline() instead of \n in the format string for indent
|
||||
* level and tabstops to work corretly.
|
||||
*
|
||||
* Output units: printbuf->units exists to tell pretty-printers how to output
|
||||
* numbers: a raw value (e.g. directly from a superblock field), as bytes, or as
|
||||
* human readable bytes. prt_units() obeys it.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
enum printbuf_si {
|
||||
PRINTBUF_UNITS_2, /* use binary powers of 2^10 */
|
||||
PRINTBUF_UNITS_10, /* use powers of 10^3 (standard SI) */
|
||||
};
|
||||
|
||||
#define PRINTBUF_INLINE_TABSTOPS 4
|
||||
|
||||
struct printbuf {
|
||||
char *buf;
|
||||
unsigned size;
|
||||
unsigned pos;
|
||||
unsigned last_newline;
|
||||
unsigned last_field;
|
||||
unsigned indent;
|
||||
/*
|
||||
* If nonzero, allocations will be done with GFP_ATOMIC:
|
||||
*/
|
||||
u8 atomic;
|
||||
bool allocation_failure:1;
|
||||
bool heap_allocated:1;
|
||||
enum printbuf_si si_units:1;
|
||||
bool human_readable_units:1;
|
||||
bool has_indent_or_tabstops:1;
|
||||
bool suppress_indent_tabstop_handling:1;
|
||||
u8 nr_tabstops;
|
||||
|
||||
/*
|
||||
* Do not modify directly: use printbuf_tabstop_add(),
|
||||
* printbuf_tabstop_get()
|
||||
*/
|
||||
u8 cur_tabstop;
|
||||
u8 _tabstops[PRINTBUF_INLINE_TABSTOPS];
|
||||
};
|
||||
|
||||
int bch2_printbuf_make_room(struct printbuf *, unsigned);
|
||||
__printf(2, 3) void bch2_prt_printf(struct printbuf *out, const char *fmt, ...);
|
||||
__printf(2, 0) void bch2_prt_vprintf(struct printbuf *out, const char *fmt, va_list);
|
||||
const char *bch2_printbuf_str(const struct printbuf *);
|
||||
void bch2_printbuf_exit(struct printbuf *);
|
||||
|
||||
void bch2_printbuf_tabstops_reset(struct printbuf *);
|
||||
void bch2_printbuf_tabstop_pop(struct printbuf *);
|
||||
int bch2_printbuf_tabstop_push(struct printbuf *, unsigned);
|
||||
|
||||
void bch2_printbuf_indent_add(struct printbuf *, unsigned);
|
||||
void bch2_printbuf_indent_sub(struct printbuf *, unsigned);
|
||||
|
||||
void bch2_prt_newline(struct printbuf *);
|
||||
void bch2_prt_tab(struct printbuf *);
|
||||
void bch2_prt_tab_rjust(struct printbuf *);
|
||||
|
||||
void bch2_prt_bytes_indented(struct printbuf *, const char *, unsigned);
|
||||
void bch2_prt_human_readable_u64(struct printbuf *, u64);
|
||||
void bch2_prt_human_readable_s64(struct printbuf *, s64);
|
||||
void bch2_prt_units_u64(struct printbuf *, u64);
|
||||
void bch2_prt_units_s64(struct printbuf *, s64);
|
||||
void bch2_prt_string_option(struct printbuf *, const char * const[], size_t);
|
||||
void bch2_prt_bitflags(struct printbuf *, const char * const[], u64);
|
||||
|
||||
/* Initializer for a heap allocated printbuf: */
|
||||
#define PRINTBUF ((struct printbuf) { .heap_allocated = true })
|
||||
|
||||
/* Initializer a printbuf that points to an external buffer: */
|
||||
#define PRINTBUF_EXTERN(_buf, _size) \
|
||||
((struct printbuf) { \
|
||||
.buf = _buf, \
|
||||
.size = _size, \
|
||||
})
|
||||
|
||||
/*
|
||||
* Returns size remaining of output buffer:
|
||||
*/
|
||||
static inline unsigned printbuf_remaining_size(struct printbuf *out)
|
||||
{
|
||||
return out->pos < out->size ? out->size - out->pos : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns number of characters we can print to the output buffer - i.e.
|
||||
* excluding the terminating nul:
|
||||
*/
|
||||
static inline unsigned printbuf_remaining(struct printbuf *out)
|
||||
{
|
||||
return out->pos < out->size ? out->size - out->pos - 1 : 0;
|
||||
}
|
||||
|
||||
static inline unsigned printbuf_written(struct printbuf *out)
|
||||
{
|
||||
return out->size ? min(out->pos, out->size - 1) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if output was truncated:
|
||||
*/
|
||||
static inline bool printbuf_overflowed(struct printbuf *out)
|
||||
{
|
||||
return out->pos >= out->size;
|
||||
}
|
||||
|
||||
static inline void printbuf_nul_terminate(struct printbuf *out)
|
||||
{
|
||||
bch2_printbuf_make_room(out, 1);
|
||||
|
||||
if (out->pos < out->size)
|
||||
out->buf[out->pos] = 0;
|
||||
else if (out->size)
|
||||
out->buf[out->size - 1] = 0;
|
||||
}
|
||||
|
||||
/* Doesn't call bch2_printbuf_make_room(), doesn't nul terminate: */
|
||||
static inline void __prt_char_reserved(struct printbuf *out, char c)
|
||||
{
|
||||
if (printbuf_remaining(out))
|
||||
out->buf[out->pos] = c;
|
||||
out->pos++;
|
||||
}
|
||||
|
||||
/* Doesn't nul terminate: */
|
||||
static inline void __prt_char(struct printbuf *out, char c)
|
||||
{
|
||||
bch2_printbuf_make_room(out, 1);
|
||||
__prt_char_reserved(out, c);
|
||||
}
|
||||
|
||||
static inline void prt_char(struct printbuf *out, char c)
|
||||
{
|
||||
__prt_char(out, c);
|
||||
printbuf_nul_terminate(out);
|
||||
}
|
||||
|
||||
static inline void __prt_chars_reserved(struct printbuf *out, char c, unsigned n)
|
||||
{
|
||||
unsigned i, can_print = min(n, printbuf_remaining(out));
|
||||
|
||||
for (i = 0; i < can_print; i++)
|
||||
out->buf[out->pos++] = c;
|
||||
out->pos += n - can_print;
|
||||
}
|
||||
|
||||
static inline void prt_chars(struct printbuf *out, char c, unsigned n)
|
||||
{
|
||||
bch2_printbuf_make_room(out, n);
|
||||
__prt_chars_reserved(out, c, n);
|
||||
printbuf_nul_terminate(out);
|
||||
}
|
||||
|
||||
static inline void prt_bytes(struct printbuf *out, const void *b, unsigned n)
|
||||
{
|
||||
unsigned i, can_print;
|
||||
|
||||
bch2_printbuf_make_room(out, n);
|
||||
|
||||
can_print = min(n, printbuf_remaining(out));
|
||||
|
||||
for (i = 0; i < can_print; i++)
|
||||
out->buf[out->pos++] = ((char *) b)[i];
|
||||
out->pos += n - can_print;
|
||||
|
||||
printbuf_nul_terminate(out);
|
||||
}
|
||||
|
||||
static inline void prt_str(struct printbuf *out, const char *str)
|
||||
{
|
||||
prt_bytes(out, str, strlen(str));
|
||||
}
|
||||
|
||||
static inline void prt_str_indented(struct printbuf *out, const char *str)
|
||||
{
|
||||
bch2_prt_bytes_indented(out, str, strlen(str));
|
||||
}
|
||||
|
||||
static inline void prt_hex_byte(struct printbuf *out, u8 byte)
|
||||
{
|
||||
bch2_printbuf_make_room(out, 2);
|
||||
__prt_char_reserved(out, hex_asc_hi(byte));
|
||||
__prt_char_reserved(out, hex_asc_lo(byte));
|
||||
printbuf_nul_terminate(out);
|
||||
}
|
||||
|
||||
static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte)
|
||||
{
|
||||
bch2_printbuf_make_room(out, 2);
|
||||
__prt_char_reserved(out, hex_asc_upper_hi(byte));
|
||||
__prt_char_reserved(out, hex_asc_upper_lo(byte));
|
||||
printbuf_nul_terminate(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_reset - re-use a printbuf without freeing and re-initializing it:
|
||||
*/
|
||||
static inline void printbuf_reset(struct printbuf *buf)
|
||||
{
|
||||
buf->pos = 0;
|
||||
buf->allocation_failure = 0;
|
||||
buf->indent = 0;
|
||||
buf->nr_tabstops = 0;
|
||||
buf->cur_tabstop = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_atomic_inc - mark as entering an atomic section
|
||||
*/
|
||||
static inline void printbuf_atomic_inc(struct printbuf *buf)
|
||||
{
|
||||
buf->atomic++;
|
||||
}
|
||||
|
||||
/**
|
||||
* printbuf_atomic_inc - mark as leaving an atomic section
|
||||
*/
|
||||
static inline void printbuf_atomic_dec(struct printbuf *buf)
|
||||
{
|
||||
buf->atomic--;
|
||||
}
|
||||
|
||||
#endif /* _BCACHEFS_PRINTBUF_H */
|
@ -23,7 +23,7 @@ static int bch2_sb_quota_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||
struct bch_sb_field_quota *q = field_to_type(f, quota);
|
||||
|
||||
if (vstruct_bytes(&q->field) < sizeof(*q)) {
|
||||
pr_buf(err, "wrong size (got %zu should be %zu)",
|
||||
prt_printf(err, "wrong size (got %zu should be %zu)",
|
||||
vstruct_bytes(&q->field), sizeof(*q));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -38,17 +38,17 @@ static void bch2_sb_quota_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
unsigned qtyp, counter;
|
||||
|
||||
for (qtyp = 0; qtyp < ARRAY_SIZE(q->q); qtyp++) {
|
||||
pr_buf(out, "%s: flags %llx",
|
||||
prt_printf(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",
|
||||
prt_printf(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);
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,13 +61,13 @@ int bch2_quota_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (k.k->p.inode >= QTYP_NR) {
|
||||
pr_buf(err, "invalid quota type (%llu >= %u)",
|
||||
prt_printf(err, "invalid quota type (%llu >= %u)",
|
||||
k.k->p.inode, QTYP_NR);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_quota)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_quota));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -82,7 +82,7 @@ void bch2_quota_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < Q_COUNTERS; i++)
|
||||
pr_buf(out, "%s hardlimit %llu softlimit %llu",
|
||||
prt_printf(out, "%s hardlimit %llu softlimit %llu",
|
||||
bch2_quota_counters[i],
|
||||
le64_to_cpu(dq.v->c[i].hardlimit),
|
||||
le64_to_cpu(dq.v->c[i].softlimit));
|
||||
|
@ -258,46 +258,47 @@ void bch2_rebalance_work_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
struct bch_fs_rebalance *r = &c->rebalance;
|
||||
struct rebalance_work w = rebalance_work(c);
|
||||
|
||||
out->tabstops[0] = 20;
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 20);
|
||||
|
||||
pr_buf(out, "fullest_dev (%i):", w.dev_most_full_idx);
|
||||
pr_tab(out);
|
||||
prt_printf(out, "fullest_dev (%i):", w.dev_most_full_idx);
|
||||
prt_tab(out);
|
||||
|
||||
bch2_hprint(out, w.dev_most_full_work << 9);
|
||||
pr_buf(out, "/");
|
||||
bch2_hprint(out, w.dev_most_full_capacity << 9);
|
||||
pr_newline(out);
|
||||
prt_human_readable_u64(out, w.dev_most_full_work << 9);
|
||||
prt_printf(out, "/");
|
||||
prt_human_readable_u64(out, w.dev_most_full_capacity << 9);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "total work:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "total work:");
|
||||
prt_tab(out);
|
||||
|
||||
bch2_hprint(out, w.total_work << 9);
|
||||
pr_buf(out, "/");
|
||||
bch2_hprint(out, c->capacity << 9);
|
||||
pr_newline(out);
|
||||
prt_human_readable_u64(out, w.total_work << 9);
|
||||
prt_printf(out, "/");
|
||||
prt_human_readable_u64(out, c->capacity << 9);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "rate:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", r->pd.rate.rate);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "rate:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", r->pd.rate.rate);
|
||||
prt_newline(out);
|
||||
|
||||
switch (r->state) {
|
||||
case REBALANCE_WAITING:
|
||||
pr_buf(out, "waiting");
|
||||
prt_printf(out, "waiting");
|
||||
break;
|
||||
case REBALANCE_THROTTLED:
|
||||
pr_buf(out, "throttled for %lu sec or ",
|
||||
prt_printf(out, "throttled for %lu sec or ",
|
||||
(r->throttled_until_cputime - jiffies) / HZ);
|
||||
bch2_hprint(out,
|
||||
prt_human_readable_u64(out,
|
||||
(r->throttled_until_iotime -
|
||||
atomic64_read(&c->io_clock[WRITE].now)) << 9);
|
||||
pr_buf(out, " io");
|
||||
prt_printf(out, " io");
|
||||
break;
|
||||
case REBALANCE_RUNNING:
|
||||
pr_buf(out, "running");
|
||||
prt_printf(out, "running");
|
||||
break;
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
void bch2_rebalance_stop(struct bch_fs *c)
|
||||
|
@ -862,12 +862,12 @@ static int verify_superblock_clean(struct bch_fs *c,
|
||||
if (k1)
|
||||
bch2_bkey_val_to_text(&buf1, c, bkey_i_to_s_c(k1));
|
||||
else
|
||||
pr_buf(&buf1, "(none)");
|
||||
prt_printf(&buf1, "(none)");
|
||||
|
||||
if (k2)
|
||||
bch2_bkey_val_to_text(&buf2, c, bkey_i_to_s_c(k2));
|
||||
else
|
||||
pr_buf(&buf2, "(none)");
|
||||
prt_printf(&buf2, "(none)");
|
||||
|
||||
mustfix_fsck_err_on(!k1 || !k2 ||
|
||||
IS_ERR(k1) ||
|
||||
|
@ -31,14 +31,14 @@ int bch2_reflink_p_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
|
||||
if (bkey_val_bytes(p.k) != sizeof(*p.v)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(p.k), sizeof(*p.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (c->sb.version >= bcachefs_metadata_version_reflink_p_fix &&
|
||||
le64_to_cpu(p.v->idx) < le32_to_cpu(p.v->front_pad)) {
|
||||
pr_buf(err, "idx < front_pad (%llu < %u)",
|
||||
prt_printf(err, "idx < front_pad (%llu < %u)",
|
||||
le64_to_cpu(p.v->idx), le32_to_cpu(p.v->front_pad));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -51,7 +51,7 @@ void bch2_reflink_p_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
|
||||
pr_buf(out, "idx %llu front_pad %u back_pad %u",
|
||||
prt_printf(out, "idx %llu front_pad %u back_pad %u",
|
||||
le64_to_cpu(p.v->idx),
|
||||
le32_to_cpu(p.v->front_pad),
|
||||
le32_to_cpu(p.v->back_pad));
|
||||
@ -83,7 +83,7 @@ int bch2_reflink_v_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
|
||||
|
||||
if (bkey_val_bytes(r.k) < sizeof(*r.v)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(r.k), sizeof(*r.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -96,7 +96,7 @@ void bch2_reflink_v_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v(k);
|
||||
|
||||
pr_buf(out, "refcount: %llu ", le64_to_cpu(r.v->refcount));
|
||||
prt_printf(out, "refcount: %llu ", le64_to_cpu(r.v->refcount));
|
||||
|
||||
bch2_bkey_ptrs_to_text(out, c, k);
|
||||
}
|
||||
@ -134,7 +134,7 @@ int bch2_indirect_inline_data_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
int rw, struct printbuf *err)
|
||||
{
|
||||
if (bkey_val_bytes(k.k) < sizeof(struct bch_indirect_inline_data)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_indirect_inline_data));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -148,7 +148,7 @@ void bch2_indirect_inline_data_to_text(struct printbuf *out,
|
||||
struct bkey_s_c_indirect_inline_data d = bkey_s_c_to_indirect_inline_data(k);
|
||||
unsigned datalen = bkey_inline_data_bytes(k.k);
|
||||
|
||||
pr_buf(out, "refcount %llu datalen %u: %*phN",
|
||||
prt_printf(out, "refcount %llu datalen %u: %*phN",
|
||||
le64_to_cpu(d.v->refcount), datalen,
|
||||
min(datalen, 32U), d.v->data);
|
||||
}
|
||||
|
@ -42,14 +42,14 @@ void bch2_replicas_entry_v0_to_text(struct printbuf *out,
|
||||
unsigned i;
|
||||
|
||||
if (e->data_type < BCH_DATA_NR)
|
||||
pr_buf(out, "%s", bch2_data_types[e->data_type]);
|
||||
prt_printf(out, "%s", bch2_data_types[e->data_type]);
|
||||
else
|
||||
pr_buf(out, "(invalid data type %u)", e->data_type);
|
||||
prt_printf(out, "(invalid data type %u)", e->data_type);
|
||||
|
||||
pr_buf(out, ": %u [", e->nr_devs);
|
||||
prt_printf(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, "]");
|
||||
prt_printf(out, i ? " %u" : "%u", e->devs[i]);
|
||||
prt_printf(out, "]");
|
||||
}
|
||||
|
||||
void bch2_replicas_entry_to_text(struct printbuf *out,
|
||||
@ -58,14 +58,14 @@ void bch2_replicas_entry_to_text(struct printbuf *out,
|
||||
unsigned i;
|
||||
|
||||
if (e->data_type < BCH_DATA_NR)
|
||||
pr_buf(out, "%s", bch2_data_types[e->data_type]);
|
||||
prt_printf(out, "%s", bch2_data_types[e->data_type]);
|
||||
else
|
||||
pr_buf(out, "(invalid data type %u)", e->data_type);
|
||||
prt_printf(out, "(invalid data type %u)", e->data_type);
|
||||
|
||||
pr_buf(out, ": %u/%u [", e->nr_required, e->nr_devs);
|
||||
prt_printf(out, ": %u/%u [", e->nr_required, e->nr_devs);
|
||||
for (i = 0; i < e->nr_devs; i++)
|
||||
pr_buf(out, i ? " %u" : "%u", e->devs[i]);
|
||||
pr_buf(out, "]");
|
||||
prt_printf(out, i ? " %u" : "%u", e->devs[i]);
|
||||
prt_printf(out, "]");
|
||||
}
|
||||
|
||||
void bch2_cpu_replicas_to_text(struct printbuf *out,
|
||||
@ -76,7 +76,7 @@ void bch2_cpu_replicas_to_text(struct printbuf *out,
|
||||
|
||||
for_each_cpu_replicas_entry(r, e) {
|
||||
if (!first)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
first = false;
|
||||
|
||||
bch2_replicas_entry_to_text(out, e);
|
||||
@ -841,27 +841,27 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
|
||||
cpu_replicas_entry(cpu_r, i);
|
||||
|
||||
if (e->data_type >= BCH_DATA_NR) {
|
||||
pr_buf(err, "invalid data type in entry ");
|
||||
prt_printf(err, "invalid data type in entry ");
|
||||
bch2_replicas_entry_to_text(err, e);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!e->nr_devs) {
|
||||
pr_buf(err, "no devices in entry ");
|
||||
prt_printf(err, "no devices in entry ");
|
||||
bch2_replicas_entry_to_text(err, e);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (e->nr_required > 1 &&
|
||||
e->nr_required >= e->nr_devs) {
|
||||
pr_buf(err, "bad nr_required in entry ");
|
||||
prt_printf(err, "bad nr_required in entry ");
|
||||
bch2_replicas_entry_to_text(err, e);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (j = 0; j < e->nr_devs; j++)
|
||||
if (!bch2_dev_exists(sb, mi, e->devs[j])) {
|
||||
pr_buf(err, "invalid device %u in entry ", e->devs[j]);
|
||||
prt_printf(err, "invalid device %u in entry ", e->devs[j]);
|
||||
bch2_replicas_entry_to_text(err, e);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -873,7 +873,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
|
||||
BUG_ON(memcmp(e, n, cpu_r->entry_size) > 0);
|
||||
|
||||
if (!memcmp(e, n, cpu_r->entry_size)) {
|
||||
pr_buf(err, "duplicate replicas entry ");
|
||||
prt_printf(err, "duplicate replicas entry ");
|
||||
bch2_replicas_entry_to_text(err, e);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -908,12 +908,12 @@ static void bch2_sb_replicas_to_text(struct printbuf *out,
|
||||
|
||||
for_each_replicas_entry(r, e) {
|
||||
if (!first)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
first = false;
|
||||
|
||||
bch2_replicas_entry_to_text(out, e);
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_replicas = {
|
||||
@ -946,12 +946,12 @@ static void bch2_sb_replicas_v0_to_text(struct printbuf *out,
|
||||
|
||||
for_each_replicas_entry(sb_r, e) {
|
||||
if (!first)
|
||||
pr_buf(out, " ");
|
||||
prt_printf(out, " ");
|
||||
first = false;
|
||||
|
||||
bch2_replicas_entry_v0_to_text(out, e);
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
const struct bch_sb_field_ops bch_sb_field_ops_replicas_v0 = {
|
||||
|
@ -17,7 +17,7 @@ void bch2_snapshot_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_snapshot s = bkey_s_c_to_snapshot(k);
|
||||
|
||||
pr_buf(out, "is_subvol %llu deleted %llu parent %u children %u %u subvol %u",
|
||||
prt_printf(out, "is_subvol %llu deleted %llu parent %u children %u %u subvol %u",
|
||||
BCH_SNAPSHOT_SUBVOL(s.v),
|
||||
BCH_SNAPSHOT_DELETED(s.v),
|
||||
le32_to_cpu(s.v->parent),
|
||||
@ -34,12 +34,12 @@ int bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
if (bkey_cmp(k.k->p, POS(0, U32_MAX)) > 0 ||
|
||||
bkey_cmp(k.k->p, POS(0, 1)) < 0) {
|
||||
pr_buf(err, "bad pos");
|
||||
prt_printf(err, "bad pos");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_snapshot)) {
|
||||
pr_buf(err, "bad val size (%zu != %zu)",
|
||||
prt_printf(err, "bad val size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_snapshot));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -48,19 +48,19 @@ int bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
id = le32_to_cpu(s.v->parent);
|
||||
if (id && id <= k.k->p.offset) {
|
||||
pr_buf(err, "bad parent node (%u <= %llu)",
|
||||
prt_printf(err, "bad parent node (%u <= %llu)",
|
||||
id, k.k->p.offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (le32_to_cpu(s.v->children[0]) < le32_to_cpu(s.v->children[1])) {
|
||||
pr_buf(err, "children not normalized");
|
||||
prt_printf(err, "children not normalized");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (s.v->children[0] &&
|
||||
s.v->children[0] == s.v->children[1]) {
|
||||
pr_buf(err, "duplicate child nodes");
|
||||
prt_printf(err, "duplicate child nodes");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ int bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
id = le32_to_cpu(s.v->children[i]);
|
||||
|
||||
if (id >= k.k->p.offset) {
|
||||
pr_buf(err, "bad child node (%u >= %llu)",
|
||||
prt_printf(err, "bad child node (%u >= %llu)",
|
||||
id, k.k->p.offset);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -750,12 +750,12 @@ int bch2_subvolume_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
{
|
||||
if (bkey_cmp(k.k->p, SUBVOL_POS_MIN) < 0 ||
|
||||
bkey_cmp(k.k->p, SUBVOL_POS_MAX) > 0) {
|
||||
pr_buf(err, "invalid pos");
|
||||
prt_printf(err, "invalid pos");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bkey_val_bytes(k.k) != sizeof(struct bch_subvolume)) {
|
||||
pr_buf(err, "incorrect value size (%zu != %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu != %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(struct bch_subvolume));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -768,7 +768,7 @@ void bch2_subvolume_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
{
|
||||
struct bkey_s_c_subvolume s = bkey_s_c_to_subvolume(k);
|
||||
|
||||
pr_buf(out, "root %llu snapshot id %u",
|
||||
prt_printf(out, "root %llu snapshot id %u",
|
||||
le64_to_cpu(s.v->inode),
|
||||
le32_to_cpu(s.v->snapshot));
|
||||
}
|
||||
|
@ -217,23 +217,23 @@ static int validate_sb_layout(struct bch_sb_layout *layout, struct printbuf *out
|
||||
|
||||
if (!uuid_equal(&layout->magic, &BCACHE_MAGIC) &&
|
||||
!uuid_equal(&layout->magic, &BCHFS_MAGIC)) {
|
||||
pr_buf(out, "Not a bcachefs superblock layout");
|
||||
prt_printf(out, "Not a bcachefs superblock layout");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (layout->layout_type != 0) {
|
||||
pr_buf(out, "Invalid superblock layout type %u",
|
||||
prt_printf(out, "Invalid superblock layout type %u",
|
||||
layout->layout_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!layout->nr_superblocks) {
|
||||
pr_buf(out, "Invalid superblock layout: no superblocks");
|
||||
prt_printf(out, "Invalid superblock layout: no superblocks");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (layout->nr_superblocks > ARRAY_SIZE(layout->sb_offset)) {
|
||||
pr_buf(out, "Invalid superblock layout: too many superblocks");
|
||||
prt_printf(out, "Invalid superblock layout: too many superblocks");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -245,7 +245,7 @@ static int validate_sb_layout(struct bch_sb_layout *layout, struct printbuf *out
|
||||
offset = le64_to_cpu(layout->sb_offset[i]);
|
||||
|
||||
if (offset < prev_offset + max_sectors) {
|
||||
pr_buf(out, "Invalid superblock layout: superblocks overlap\n"
|
||||
prt_printf(out, "Invalid superblock layout: superblocks overlap\n"
|
||||
" (sb %u ends at %llu next starts at %llu",
|
||||
i - 1, prev_offset + max_sectors, offset);
|
||||
return -EINVAL;
|
||||
@ -273,63 +273,63 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
||||
: version;
|
||||
|
||||
if (version >= bcachefs_metadata_version_max) {
|
||||
pr_buf(out, "Unsupported superblock version %u (min %u, max %u)",
|
||||
prt_printf(out, "Unsupported superblock version %u (min %u, max %u)",
|
||||
version, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (version_min < bcachefs_metadata_version_min) {
|
||||
pr_buf(out, "Unsupported superblock version %u (min %u, max %u)",
|
||||
prt_printf(out, "Unsupported superblock version %u (min %u, max %u)",
|
||||
version_min, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (version_min > version) {
|
||||
pr_buf(out, "Bad minimum version %u, greater than version field %u",
|
||||
prt_printf(out, "Bad minimum version %u, greater than version field %u",
|
||||
version_min, version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sb->features[1] ||
|
||||
(le64_to_cpu(sb->features[0]) & (~0ULL << BCH_FEATURE_NR))) {
|
||||
pr_buf(out, "Filesystem has incompatible features");
|
||||
prt_printf(out, "Filesystem has incompatible features");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
block_size = le16_to_cpu(sb->block_size);
|
||||
|
||||
if (block_size > PAGE_SECTORS) {
|
||||
pr_buf(out, "Block size too big (got %u, max %u)",
|
||||
prt_printf(out, "Block size too big (got %u, max %u)",
|
||||
block_size, PAGE_SECTORS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bch2_is_zero(sb->user_uuid.b, sizeof(sb->user_uuid))) {
|
||||
pr_buf(out, "Bad user UUID (got zeroes)");
|
||||
prt_printf(out, "Bad user UUID (got zeroes)");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bch2_is_zero(sb->uuid.b, sizeof(sb->uuid))) {
|
||||
pr_buf(out, "Bad intenal UUID (got zeroes)");
|
||||
prt_printf(out, "Bad intenal UUID (got zeroes)");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sb->nr_devices ||
|
||||
sb->nr_devices > BCH_SB_MEMBERS_MAX) {
|
||||
pr_buf(out, "Bad number of member devices %u (max %u)",
|
||||
prt_printf(out, "Bad number of member devices %u (max %u)",
|
||||
sb->nr_devices, BCH_SB_MEMBERS_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sb->dev_idx >= sb->nr_devices) {
|
||||
pr_buf(out, "Bad dev_idx (got %u, nr_devices %u)",
|
||||
prt_printf(out, "Bad dev_idx (got %u, nr_devices %u)",
|
||||
sb->dev_idx, sb->nr_devices);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sb->time_precision ||
|
||||
le32_to_cpu(sb->time_precision) > NSEC_PER_SEC) {
|
||||
pr_buf(out, "Invalid time precision: %u (min 1, max %lu)",
|
||||
prt_printf(out, "Invalid time precision: %u (min 1, max %lu)",
|
||||
le32_to_cpu(sb->time_precision), NSEC_PER_SEC);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -352,7 +352,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
||||
if (opt->get_sb != BCH2_NO_SB_OPT) {
|
||||
u64 v = bch2_opt_from_sb(sb, opt_id);
|
||||
|
||||
pr_buf(out, "Invalid option ");
|
||||
prt_printf(out, "Invalid option ");
|
||||
ret = bch2_opt_validate(opt, v, out);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -368,13 +368,13 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
||||
|
||||
vstruct_for_each(sb, f) {
|
||||
if (!f->u64s) {
|
||||
pr_buf(out, "Invalid superblock: optional with size 0 (type %u)",
|
||||
prt_printf(out, "Invalid superblock: optional with size 0 (type %u)",
|
||||
le32_to_cpu(f->type));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (vstruct_next(f) > vstruct_last(sb)) {
|
||||
pr_buf(out, "Invalid superblock: optional field extends past end of superblock (type %u)",
|
||||
prt_printf(out, "Invalid superblock: optional field extends past end of superblock (type %u)",
|
||||
le32_to_cpu(f->type));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -383,7 +383,7 @@ static int bch2_sb_validate(struct bch_sb_handle *disk_sb, struct printbuf *out,
|
||||
/* members must be validated first: */
|
||||
mi = bch2_sb_get_members(sb);
|
||||
if (!mi) {
|
||||
pr_buf(out, "Invalid superblock: member info area missing");
|
||||
prt_printf(out, "Invalid superblock: member info area missing");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -539,13 +539,13 @@ static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf
|
||||
|
||||
ret = submit_bio_wait(sb->bio);
|
||||
if (ret) {
|
||||
pr_buf(err, "IO error: %i", ret);
|
||||
prt_printf(err, "IO error: %i", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!uuid_equal(&sb->sb->magic, &BCACHE_MAGIC) &&
|
||||
!uuid_equal(&sb->sb->magic, &BCHFS_MAGIC)) {
|
||||
pr_buf(err, "Not a bcachefs superblock");
|
||||
prt_printf(err, "Not a bcachefs superblock");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -555,13 +555,13 @@ static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf
|
||||
: version;
|
||||
|
||||
if (version >= bcachefs_metadata_version_max) {
|
||||
pr_buf(err, "Unsupported superblock version %u (min %u, max %u)",
|
||||
prt_printf(err, "Unsupported superblock version %u (min %u, max %u)",
|
||||
version, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (version_min < bcachefs_metadata_version_min) {
|
||||
pr_buf(err, "Unsupported superblock version %u (min %u, max %u)",
|
||||
prt_printf(err, "Unsupported superblock version %u (min %u, max %u)",
|
||||
version_min, bcachefs_metadata_version_min, bcachefs_metadata_version_max);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -569,7 +569,7 @@ static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf
|
||||
bytes = vstruct_bytes(sb->sb);
|
||||
|
||||
if (bytes > 512 << sb->sb->layout.sb_max_size_bits) {
|
||||
pr_buf(err, "Invalid superblock: too big (got %zu bytes, layout max %lu)",
|
||||
prt_printf(err, "Invalid superblock: too big (got %zu bytes, layout max %lu)",
|
||||
bytes, 512UL << sb->sb->layout.sb_max_size_bits);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -581,7 +581,7 @@ static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf
|
||||
}
|
||||
|
||||
if (BCH_SB_CSUM_TYPE(sb->sb) >= BCH_CSUM_NR) {
|
||||
pr_buf(err, "unknown checksum type %llu", BCH_SB_CSUM_TYPE(sb->sb));
|
||||
prt_printf(err, "unknown checksum type %llu", BCH_SB_CSUM_TYPE(sb->sb));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -590,7 +590,7 @@ static int read_one_super(struct bch_sb_handle *sb, u64 offset, struct printbuf
|
||||
null_nonce(), sb->sb);
|
||||
|
||||
if (bch2_crc_cmp(csum, sb->sb->csum)) {
|
||||
pr_buf(err, "bad checksum");
|
||||
prt_printf(err, "bad checksum");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -641,12 +641,12 @@ int bch2_read_super(const char *path, struct bch_opts *opts,
|
||||
|
||||
ret = bch2_sb_realloc(sb, 0);
|
||||
if (ret) {
|
||||
pr_buf(&err, "error allocating memory for superblock");
|
||||
prt_printf(&err, "error allocating memory for superblock");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (bch2_fs_init_fault("read_super")) {
|
||||
pr_buf(&err, "dynamic fault");
|
||||
prt_printf(&err, "dynamic fault");
|
||||
ret = -EFAULT;
|
||||
goto err;
|
||||
}
|
||||
@ -676,7 +676,7 @@ int bch2_read_super(const char *path, struct bch_opts *opts,
|
||||
|
||||
ret = submit_bio_wait(sb->bio);
|
||||
if (ret) {
|
||||
pr_buf(&err, "IO error: %i", ret);
|
||||
prt_printf(&err, "IO error: %i", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -702,7 +702,7 @@ int bch2_read_super(const char *path, struct bch_opts *opts,
|
||||
got_super:
|
||||
if (le16_to_cpu(sb->sb->block_size) << 9 <
|
||||
bdev_logical_block_size(sb->bdev)) {
|
||||
pr_buf(&err, "block size (%u) smaller than device block size (%u)",
|
||||
prt_printf(&err, "block size (%u) smaller than device block size (%u)",
|
||||
le16_to_cpu(sb->sb->block_size) << 9,
|
||||
bdev_logical_block_size(sb->bdev));
|
||||
ret = -EINVAL;
|
||||
@ -954,7 +954,7 @@ static int bch2_sb_members_validate(struct bch_sb *sb,
|
||||
|
||||
if ((void *) (mi->members + sb->nr_devices) >
|
||||
vstruct_end(&mi->field)) {
|
||||
pr_buf(err, "too many devices for section size");
|
||||
prt_printf(err, "too many devices for section size");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -965,28 +965,28 @@ static int bch2_sb_members_validate(struct bch_sb *sb,
|
||||
continue;
|
||||
|
||||
if (le64_to_cpu(m->nbuckets) > LONG_MAX) {
|
||||
pr_buf(err, "device %u: too many buckets (got %llu, max %lu)",
|
||||
prt_printf(err, "device %u: too many buckets (got %llu, max %lu)",
|
||||
i, le64_to_cpu(m->nbuckets), LONG_MAX);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (le64_to_cpu(m->nbuckets) -
|
||||
le16_to_cpu(m->first_bucket) < BCH_MIN_NR_NBUCKETS) {
|
||||
pr_buf(err, "device %u: not enough buckets (got %llu, max %u)",
|
||||
prt_printf(err, "device %u: not enough buckets (got %llu, max %u)",
|
||||
i, le64_to_cpu(m->nbuckets), BCH_MIN_NR_NBUCKETS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(m->bucket_size) <
|
||||
le16_to_cpu(sb->block_size)) {
|
||||
pr_buf(err, "device %u: bucket size %u smaller than block size %u",
|
||||
prt_printf(err, "device %u: bucket size %u smaller than block size %u",
|
||||
i, le16_to_cpu(m->bucket_size), le16_to_cpu(sb->block_size));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (le16_to_cpu(m->bucket_size) <
|
||||
BCH_SB_BTREE_NODE_SIZE(sb)) {
|
||||
pr_buf(err, "device %u: bucket size %u smaller than btree node size %llu",
|
||||
prt_printf(err, "device %u: bucket size %u smaller than btree node size %llu",
|
||||
i, le16_to_cpu(m->bucket_size), BCH_SB_BTREE_NODE_SIZE(sb));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1011,97 +1011,96 @@ static void bch2_sb_members_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
if (!bch2_member_exists(m))
|
||||
continue;
|
||||
|
||||
pr_buf(out, "Device:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", i);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Device:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", i);
|
||||
prt_newline(out);
|
||||
|
||||
pr_indent_push(out, 2);
|
||||
printbuf_indent_add(out, 2);
|
||||
|
||||
pr_buf(out, "UUID:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "UUID:");
|
||||
prt_tab(out);
|
||||
pr_uuid(out, m->uuid.b);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Size:");
|
||||
pr_tab(out);
|
||||
pr_units(out, device_size, device_size << 9);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Size:");
|
||||
prt_tab(out);
|
||||
prt_units_u64(out, device_size << 9);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Bucket size:");
|
||||
pr_tab(out);
|
||||
pr_units(out, bucket_size, bucket_size << 9);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Bucket size:");
|
||||
prt_tab(out);
|
||||
prt_units_u64(out, bucket_size << 9);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "First bucket:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", le16_to_cpu(m->first_bucket));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "First bucket:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", le16_to_cpu(m->first_bucket));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Buckets:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", le64_to_cpu(m->nbuckets));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Buckets:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", le64_to_cpu(m->nbuckets));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Last mount:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Last mount:");
|
||||
prt_tab(out);
|
||||
if (m->last_mount)
|
||||
pr_time(out, le64_to_cpu(m->last_mount));
|
||||
else
|
||||
pr_buf(out, "(never)");
|
||||
pr_newline(out);
|
||||
prt_printf(out, "(never)");
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "State:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%s",
|
||||
prt_printf(out, "State:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%s",
|
||||
BCH_MEMBER_STATE(m) < BCH_MEMBER_STATE_NR
|
||||
? bch2_member_states[BCH_MEMBER_STATE(m)]
|
||||
: "unknown");
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Label:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Label:");
|
||||
prt_tab(out);
|
||||
if (BCH_MEMBER_GROUP(m)) {
|
||||
unsigned idx = BCH_MEMBER_GROUP(m) - 1;
|
||||
|
||||
if (idx < disk_groups_nr(gi))
|
||||
pr_buf(out, "%s (%u)",
|
||||
prt_printf(out, "%s (%u)",
|
||||
gi->entries[idx].label, idx);
|
||||
else
|
||||
pr_buf(out, "(bad disk labels section)");
|
||||
prt_printf(out, "(bad disk labels section)");
|
||||
} else {
|
||||
pr_buf(out, "(none)");
|
||||
prt_printf(out, "(none)");
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Data allowed:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Data allowed:");
|
||||
prt_tab(out);
|
||||
if (BCH_MEMBER_DATA_ALLOWED(m))
|
||||
bch2_flags_to_text(out, bch2_data_types,
|
||||
BCH_MEMBER_DATA_ALLOWED(m));
|
||||
prt_bitflags(out, bch2_data_types, BCH_MEMBER_DATA_ALLOWED(m));
|
||||
else
|
||||
pr_buf(out, "(none)");
|
||||
pr_newline(out);
|
||||
prt_printf(out, "(none)");
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Has data:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Has data:");
|
||||
prt_tab(out);
|
||||
if (data_have)
|
||||
bch2_flags_to_text(out, bch2_data_types, data_have);
|
||||
prt_bitflags(out, bch2_data_types, data_have);
|
||||
else
|
||||
pr_buf(out, "(none)");
|
||||
pr_newline(out);
|
||||
prt_printf(out, "(none)");
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Discard:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", BCH_MEMBER_DISCARD(m));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Discard:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", BCH_MEMBER_DISCARD(m));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Freespace initialized:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", BCH_MEMBER_FREESPACE_INITIALIZED(m));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Freespace initialized:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", BCH_MEMBER_FREESPACE_INITIALIZED(m));
|
||||
prt_newline(out);
|
||||
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1119,13 +1118,13 @@ static int bch2_sb_crypt_validate(struct bch_sb *sb,
|
||||
struct bch_sb_field_crypt *crypt = field_to_type(f, crypt);
|
||||
|
||||
if (vstruct_bytes(&crypt->field) < sizeof(*crypt)) {
|
||||
pr_buf(err, "wrong size (got %zu should be %zu)",
|
||||
prt_printf(err, "wrong size (got %zu should be %zu)",
|
||||
vstruct_bytes(&crypt->field), sizeof(*crypt));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (BCH_CRYPT_KDF_TYPE(crypt)) {
|
||||
pr_buf(err, "bad kdf type %llu", BCH_CRYPT_KDF_TYPE(crypt));
|
||||
prt_printf(err, "bad kdf type %llu", BCH_CRYPT_KDF_TYPE(crypt));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1137,14 +1136,14 @@ static void bch2_sb_crypt_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
{
|
||||
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);
|
||||
prt_printf(out, "KFD: %llu", BCH_CRYPT_KDF_TYPE(crypt));
|
||||
prt_newline(out);
|
||||
prt_printf(out, "scrypt n: %llu", BCH_KDF_SCRYPT_N(crypt));
|
||||
prt_newline(out);
|
||||
prt_printf(out, "scrypt r: %llu", BCH_KDF_SCRYPT_R(crypt));
|
||||
prt_newline(out);
|
||||
prt_printf(out, "scrypt p: %llu", BCH_KDF_SCRYPT_P(crypt));
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
static const struct bch_sb_field_ops bch_sb_field_ops_crypt = {
|
||||
@ -1361,7 +1360,7 @@ static int bch2_sb_clean_validate(struct bch_sb *sb,
|
||||
struct bch_sb_field_clean *clean = field_to_type(f, clean);
|
||||
|
||||
if (vstruct_bytes(&clean->field) < sizeof(*clean)) {
|
||||
pr_buf(err, "wrong size (got %zu should be %zu)",
|
||||
prt_printf(err, "wrong size (got %zu should be %zu)",
|
||||
vstruct_bytes(&clean->field), sizeof(*clean));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1375,10 +1374,10 @@ static void bch2_sb_clean_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
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);
|
||||
prt_printf(out, "flags: %x", le32_to_cpu(clean->flags));
|
||||
prt_newline(out);
|
||||
prt_printf(out, "journal_seq: %llu", le64_to_cpu(clean->journal_seq));
|
||||
prt_newline(out);
|
||||
|
||||
for (entry = clean->start;
|
||||
entry != vstruct_end(&clean->field);
|
||||
@ -1388,7 +1387,7 @@ static void bch2_sb_clean_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
continue;
|
||||
|
||||
bch2_journal_entry_to_text(out, NULL, entry);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1416,10 +1415,10 @@ static int bch2_sb_field_validate(struct bch_sb *sb, struct bch_sb_field *f,
|
||||
|
||||
ret = bch2_sb_field_ops[type]->validate(sb, f, &field_err);
|
||||
if (ret) {
|
||||
pr_buf(err, "Invalid superblock section %s: %s",
|
||||
prt_printf(err, "Invalid superblock section %s: %s",
|
||||
bch2_sb_fields[type],
|
||||
field_err.buf);
|
||||
pr_newline(err);
|
||||
prt_newline(err);
|
||||
bch2_sb_field_to_text(err, sb, f);
|
||||
}
|
||||
|
||||
@ -1434,21 +1433,21 @@ void bch2_sb_field_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
const struct bch_sb_field_ops *ops = type < BCH_SB_FIELD_NR
|
||||
? bch2_sb_field_ops[type] : NULL;
|
||||
|
||||
if (!out->tabstops[0])
|
||||
out->tabstops[0] = 32;
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 32);
|
||||
|
||||
if (ops)
|
||||
pr_buf(out, "%s", bch2_sb_fields[type]);
|
||||
prt_printf(out, "%s", bch2_sb_fields[type]);
|
||||
else
|
||||
pr_buf(out, "(unknown field %u)", type);
|
||||
prt_printf(out, "(unknown field %u)", type);
|
||||
|
||||
pr_buf(out, " (size %zu):", vstruct_bytes(f));
|
||||
pr_newline(out);
|
||||
prt_printf(out, " (size %zu):", vstruct_bytes(f));
|
||||
prt_newline(out);
|
||||
|
||||
if (ops && ops->to_text) {
|
||||
pr_indent_push(out, 2);
|
||||
printbuf_indent_add(out, 2);
|
||||
bch2_sb_field_ops[type]->to_text(out, sb, f);
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1456,25 +1455,23 @@ 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);
|
||||
prt_printf(out, "Type: %u", l->layout_type);
|
||||
prt_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);
|
||||
prt_str(out, "Superblock max size: ");
|
||||
prt_units_u64(out, 512 << l->sb_max_size_bits);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Nr superblocks: %u", l->nr_superblocks);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Nr superblocks: %u", l->nr_superblocks);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Offsets: ");
|
||||
prt_str(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]));
|
||||
prt_str(out, ", ");
|
||||
prt_printf(out, "%llu", le64_to_cpu(l->sb_offset[i]));
|
||||
}
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
@ -1485,8 +1482,8 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
u64 fields_have = 0;
|
||||
unsigned nr_devices = 0;
|
||||
|
||||
if (!out->tabstops[0])
|
||||
out->tabstops[0] = 32;
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 32);
|
||||
|
||||
mi = bch2_sb_get_members(sb);
|
||||
if (mi) {
|
||||
@ -1498,87 +1495,85 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
nr_devices += bch2_member_exists(m);
|
||||
}
|
||||
|
||||
pr_buf(out, "External UUID:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "External UUID:");
|
||||
prt_tab(out);
|
||||
pr_uuid(out, sb->user_uuid.b);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Internal UUID:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Internal UUID:");
|
||||
prt_tab(out);
|
||||
pr_uuid(out, sb->uuid.b);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Device index:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", sb->dev_idx);
|
||||
pr_newline(out);
|
||||
prt_str(out, "Device index:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", sb->dev_idx);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Label:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%.*s", (int) sizeof(sb->label), sb->label);
|
||||
pr_newline(out);
|
||||
prt_str(out, "Label:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%.*s", (int) sizeof(sb->label), sb->label);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Version:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%s", bch2_metadata_versions[le16_to_cpu(sb->version)]);
|
||||
pr_newline(out);
|
||||
prt_str(out, "Version:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%s", bch2_metadata_versions[le16_to_cpu(sb->version)]);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Oldest version on disk:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%s", bch2_metadata_versions[le16_to_cpu(sb->version_min)]);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Oldest version on disk:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%s", bch2_metadata_versions[le16_to_cpu(sb->version_min)]);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Created:");
|
||||
pr_tab(out);
|
||||
prt_printf(out, "Created:");
|
||||
prt_tab(out);
|
||||
if (sb->time_base_lo)
|
||||
pr_time(out, div_u64(le64_to_cpu(sb->time_base_lo), NSEC_PER_SEC));
|
||||
else
|
||||
pr_buf(out, "(not set)");
|
||||
pr_newline(out);
|
||||
prt_printf(out, "(not set)");
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Sequence number:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", le64_to_cpu(sb->seq));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Sequence number:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", le64_to_cpu(sb->seq));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Superblock size:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%zu", vstruct_bytes(sb));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Superblock size:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%zu", vstruct_bytes(sb));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Clean:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llu", BCH_SB_CLEAN(sb));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Clean:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llu", BCH_SB_CLEAN(sb));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Devices:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%u", nr_devices);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Devices:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%u", nr_devices);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Sections:");
|
||||
prt_printf(out, "Sections:");
|
||||
vstruct_for_each(sb, f)
|
||||
fields_have |= 1 << le32_to_cpu(f->type);
|
||||
pr_tab(out);
|
||||
bch2_flags_to_text(out, bch2_sb_fields, fields_have);
|
||||
pr_newline(out);
|
||||
prt_tab(out);
|
||||
prt_bitflags(out, bch2_sb_fields, fields_have);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Features:");
|
||||
pr_tab(out);
|
||||
bch2_flags_to_text(out, bch2_sb_features,
|
||||
le64_to_cpu(sb->features[0]));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Features:");
|
||||
prt_tab(out);
|
||||
prt_bitflags(out, bch2_sb_features, le64_to_cpu(sb->features[0]));
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "Compat features:");
|
||||
pr_tab(out);
|
||||
bch2_flags_to_text(out, bch2_sb_compat,
|
||||
le64_to_cpu(sb->compat[0]));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "Compat features:");
|
||||
prt_tab(out);
|
||||
prt_bitflags(out, bch2_sb_compat, le64_to_cpu(sb->compat[0]));
|
||||
prt_newline(out);
|
||||
|
||||
pr_newline(out);
|
||||
pr_buf(out, "Options:");
|
||||
pr_newline(out);
|
||||
pr_indent_push(out, 2);
|
||||
prt_newline(out);
|
||||
prt_printf(out, "Options:");
|
||||
prt_newline(out);
|
||||
printbuf_indent_add(out, 2);
|
||||
{
|
||||
enum bch_opt_id id;
|
||||
|
||||
@ -1588,29 +1583,29 @@ void bch2_sb_to_text(struct printbuf *out, struct bch_sb *sb,
|
||||
if (opt->get_sb != BCH2_NO_SB_OPT) {
|
||||
u64 v = bch2_opt_from_sb(sb, id);
|
||||
|
||||
pr_buf(out, "%s:", opt->attr.name);
|
||||
pr_tab(out);
|
||||
prt_printf(out, "%s:", opt->attr.name);
|
||||
prt_tab(out);
|
||||
bch2_opt_to_text(out, NULL, sb, opt, v,
|
||||
OPT_HUMAN_READABLE|OPT_SHOW_FULL_LIST);
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
|
||||
if (print_layout) {
|
||||
pr_newline(out);
|
||||
pr_buf(out, "layout:");
|
||||
pr_newline(out);
|
||||
pr_indent_push(out, 2);
|
||||
prt_newline(out);
|
||||
prt_printf(out, "layout:");
|
||||
prt_newline(out);
|
||||
printbuf_indent_add(out, 2);
|
||||
bch2_sb_layout_to_text(out, &sb->layout);
|
||||
pr_indent_pop(out, 2);
|
||||
printbuf_indent_sub(out, 2);
|
||||
}
|
||||
|
||||
vstruct_for_each(sb, f)
|
||||
if (fields & (1 << le32_to_cpu(f->type))) {
|
||||
pr_newline(out);
|
||||
prt_newline(out);
|
||||
bch2_sb_field_to_text(out, sb, f);
|
||||
}
|
||||
}
|
||||
|
@ -605,6 +605,7 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
|
||||
{
|
||||
struct bch_sb_field_members *mi;
|
||||
struct bch_fs *c;
|
||||
struct printbuf name = PRINTBUF;
|
||||
unsigned i, iter_size;
|
||||
int ret = 0;
|
||||
|
||||
@ -708,7 +709,13 @@ static struct bch_fs *bch2_fs_alloc(struct bch_sb *sb, struct bch_opts opts)
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
uuid_unparse_lower(c->sb.user_uuid.b, c->name);
|
||||
pr_uuid(&name, c->sb.user_uuid.b);
|
||||
strlcpy(c->name, name.buf, sizeof(c->name));
|
||||
printbuf_exit(&name);
|
||||
|
||||
ret = name.allocation_failure ? -ENOMEM : 0;
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* Compat: */
|
||||
if (sb->version <= bcachefs_metadata_version_inode_v2 &&
|
||||
@ -830,7 +837,7 @@ static void print_mount_opts(struct bch_fs *c)
|
||||
bool first = true;
|
||||
|
||||
if (c->opts.read_only) {
|
||||
pr_buf(&p, "ro");
|
||||
prt_printf(&p, "ro");
|
||||
first = false;
|
||||
}
|
||||
|
||||
@ -845,13 +852,13 @@ static void print_mount_opts(struct bch_fs *c)
|
||||
continue;
|
||||
|
||||
if (!first)
|
||||
pr_buf(&p, ",");
|
||||
prt_printf(&p, ",");
|
||||
first = false;
|
||||
bch2_opt_to_text(&p, c, c->disk_sb.sb, opt, v, OPT_SHOW_MOUNT_STYLE);
|
||||
}
|
||||
|
||||
if (!p.pos)
|
||||
pr_buf(&p, "(null)");
|
||||
prt_printf(&p, "(null)");
|
||||
|
||||
bch_info(c, "mounted version=%s opts=%s", bch2_metadata_versions[c->sb.version], p.buf);
|
||||
printbuf_exit(&p);
|
||||
@ -1482,7 +1489,7 @@ int bch2_dev_remove(struct bch_fs *c, struct bch_dev *ca, int flags)
|
||||
if (data) {
|
||||
struct printbuf data_has = PRINTBUF;
|
||||
|
||||
bch2_flags_to_text(&data_has, bch2_data_types, data);
|
||||
prt_bitflags(&data_has, bch2_data_types, data);
|
||||
bch_err(ca, "Remove failed, still has data (%s)", data_has.buf);
|
||||
printbuf_exit(&data_has);
|
||||
ret = -EBUSY;
|
||||
|
@ -56,7 +56,7 @@ static ssize_t fn ## _show(struct kobject *kobj, struct attribute *attr,\
|
||||
ssize_t ret = fn ## _to_text(&out, kobj, attr); \
|
||||
\
|
||||
if (out.pos && out.buf[out.pos - 1] != '\n') \
|
||||
pr_newline(&out); \
|
||||
prt_newline(&out); \
|
||||
\
|
||||
if (!ret && out.allocation_failure) \
|
||||
ret = -ENOMEM; \
|
||||
@ -87,7 +87,7 @@ static ssize_t fn ## _store(struct kobject *kobj, struct attribute *attr,\
|
||||
#define sysfs_printf(file, fmt, ...) \
|
||||
do { \
|
||||
if (attr == &sysfs_ ## file) \
|
||||
pr_buf(out, fmt "\n", __VA_ARGS__); \
|
||||
prt_printf(out, fmt "\n", __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define sysfs_print(file, var) \
|
||||
@ -99,7 +99,7 @@ do { \
|
||||
#define sysfs_hprint(file, val) \
|
||||
do { \
|
||||
if (attr == &sysfs_ ## file) \
|
||||
bch2_hprint(out, val); \
|
||||
prt_human_readable_s64(out, val); \
|
||||
} while (0)
|
||||
|
||||
#define var_printf(_var, fmt) sysfs_printf(_var, fmt, var(_var))
|
||||
@ -260,12 +260,12 @@ static long data_progress_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
|
||||
mutex_lock(&c->data_progress_lock);
|
||||
list_for_each_entry(stats, &c->data_progress_list, list) {
|
||||
pr_buf(out, "%s: data type %s btree_id %s position: ",
|
||||
prt_printf(out, "%s: data type %s btree_id %s position: ",
|
||||
stats->name,
|
||||
bch2_data_types[stats->data_type],
|
||||
bch2_btree_ids[stats->btree_id]);
|
||||
bch2_bpos_to_text(out, stats->pos);
|
||||
pr_buf(out, "%s", "\n");
|
||||
prt_printf(out, "%s", "\n");
|
||||
}
|
||||
|
||||
mutex_unlock(&c->data_progress_lock);
|
||||
@ -338,34 +338,34 @@ static int bch2_compression_stats_to_text(struct printbuf *out, struct bch_fs *c
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
pr_buf(out, "uncompressed:\n");
|
||||
pr_buf(out, " nr extents: %llu\n", nr_uncompressed_extents);
|
||||
pr_buf(out, " size: ");
|
||||
bch2_hprint(out, uncompressed_sectors << 9);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "uncompressed:\n");
|
||||
prt_printf(out, " nr extents: %llu\n", nr_uncompressed_extents);
|
||||
prt_printf(out, " size: ");
|
||||
prt_human_readable_u64(out, uncompressed_sectors << 9);
|
||||
prt_printf(out, "\n");
|
||||
|
||||
pr_buf(out, "compressed:\n");
|
||||
pr_buf(out, " nr extents: %llu\n", nr_compressed_extents);
|
||||
pr_buf(out, " compressed size: ");
|
||||
bch2_hprint(out, compressed_sectors_compressed << 9);
|
||||
pr_buf(out, "\n");
|
||||
pr_buf(out, " uncompressed size: ");
|
||||
bch2_hprint(out, compressed_sectors_uncompressed << 9);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "compressed:\n");
|
||||
prt_printf(out, " nr extents: %llu\n", nr_compressed_extents);
|
||||
prt_printf(out, " compressed size: ");
|
||||
prt_human_readable_u64(out, compressed_sectors_compressed << 9);
|
||||
prt_printf(out, "\n");
|
||||
prt_printf(out, " uncompressed size: ");
|
||||
prt_human_readable_u64(out, compressed_sectors_uncompressed << 9);
|
||||
prt_printf(out, "\n");
|
||||
|
||||
pr_buf(out, "incompressible:\n");
|
||||
pr_buf(out, " nr extents: %llu\n", nr_incompressible_extents);
|
||||
pr_buf(out, " size: ");
|
||||
bch2_hprint(out, incompressible_sectors << 9);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "incompressible:\n");
|
||||
prt_printf(out, " nr extents: %llu\n", nr_incompressible_extents);
|
||||
prt_printf(out, " size: ");
|
||||
prt_human_readable_u64(out, incompressible_sectors << 9);
|
||||
prt_printf(out, "\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bch2_gc_gens_pos_to_text(struct printbuf *out, struct bch_fs *c)
|
||||
{
|
||||
pr_buf(out, "%s: ", bch2_btree_ids[c->gc_gens_btree]);
|
||||
prt_printf(out, "%s: ", bch2_btree_ids[c->gc_gens_btree]);
|
||||
bch2_bpos_to_text(out, c->gc_gens_pos);
|
||||
pr_buf(out, "\n");
|
||||
prt_printf(out, "\n");
|
||||
}
|
||||
|
||||
SHOW(bch2_fs)
|
||||
@ -563,20 +563,21 @@ SHOW(bch2_fs_counters)
|
||||
u64 counter = 0;
|
||||
u64 counter_since_mount = 0;
|
||||
|
||||
out->tabstops[0] = 32;
|
||||
printbuf_tabstop_push(out, 32);
|
||||
|
||||
#define x(t, ...) \
|
||||
if (attr == &sysfs_##t) { \
|
||||
counter = percpu_u64_get(&c->counters[BCH_COUNTER_##t]);\
|
||||
counter_since_mount = counter - c->counters_on_mount[BCH_COUNTER_##t];\
|
||||
pr_buf(out, "since mount:"); \
|
||||
pr_tab(out); \
|
||||
bch2_hprint(out, counter_since_mount << 9); \
|
||||
pr_newline(out); \
|
||||
prt_printf(out, "since mount:"); \
|
||||
prt_tab(out); \
|
||||
prt_human_readable_u64(out, counter_since_mount << 9); \
|
||||
prt_newline(out); \
|
||||
\
|
||||
pr_buf(out, "since filesystem creation:"); \
|
||||
pr_tab(out); \
|
||||
bch2_hprint(out, counter << 9); \
|
||||
pr_newline(out); \
|
||||
prt_printf(out, "since filesystem creation:"); \
|
||||
prt_tab(out); \
|
||||
prt_human_readable_u64(out, counter << 9); \
|
||||
prt_newline(out); \
|
||||
}
|
||||
BCH_PERSISTENT_COUNTERS()
|
||||
#undef x
|
||||
@ -658,7 +659,7 @@ SHOW(bch2_fs_opts_dir)
|
||||
u64 v = bch2_opt_get_by_id(&c->opts, id);
|
||||
|
||||
bch2_opt_to_text(out, c, c->disk_sb.sb, opt, v, OPT_SHOW_FULL_LIST);
|
||||
pr_char(out, '\n');
|
||||
prt_char(out, '\n');
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -771,17 +772,17 @@ static void dev_alloc_debug_to_text(struct printbuf *out, struct bch_dev *ca)
|
||||
for (i = 0; i < ARRAY_SIZE(c->open_buckets); i++)
|
||||
nr[c->open_buckets[i].data_type]++;
|
||||
|
||||
pr_buf(out,
|
||||
prt_printf(out,
|
||||
"\t\t\t buckets\t sectors fragmented\n"
|
||||
"capacity\t%16llu\n",
|
||||
ca->mi.nbuckets - ca->mi.first_bucket);
|
||||
|
||||
for (i = 0; i < BCH_DATA_NR; i++)
|
||||
pr_buf(out, "%-16s%16llu%16llu%16llu\n",
|
||||
prt_printf(out, "%-16s%16llu%16llu%16llu\n",
|
||||
bch2_data_types[i], stats.d[i].buckets,
|
||||
stats.d[i].sectors, stats.d[i].fragmented);
|
||||
|
||||
pr_buf(out,
|
||||
prt_printf(out,
|
||||
"ec\t\t%16llu\n"
|
||||
"\n"
|
||||
"freelist_wait\t\t%s\n"
|
||||
@ -814,10 +815,10 @@ static void dev_iodone_to_text(struct printbuf *out, struct bch_dev *ca)
|
||||
int rw, i;
|
||||
|
||||
for (rw = 0; rw < 2; rw++) {
|
||||
pr_buf(out, "%s:\n", bch2_rw[rw]);
|
||||
prt_printf(out, "%s:\n", bch2_rw[rw]);
|
||||
|
||||
for (i = 1; i < BCH_DATA_NR; i++)
|
||||
pr_buf(out, "%-12s:%12llu\n",
|
||||
prt_printf(out, "%-12s:%12llu\n",
|
||||
bch2_data_types[i],
|
||||
percpu_u64_get(&ca->io_done->sectors[rw][i]) << 9);
|
||||
}
|
||||
@ -844,19 +845,17 @@ SHOW(bch2_dev)
|
||||
mutex_unlock(&c->sb_lock);
|
||||
}
|
||||
|
||||
pr_char(out, '\n');
|
||||
prt_char(out, '\n');
|
||||
}
|
||||
|
||||
if (attr == &sysfs_has_data) {
|
||||
bch2_flags_to_text(out, bch2_data_types,
|
||||
bch2_dev_has_data(c, ca));
|
||||
pr_char(out, '\n');
|
||||
prt_bitflags(out, bch2_data_types, bch2_dev_has_data(c, ca));
|
||||
prt_char(out, '\n');
|
||||
}
|
||||
|
||||
if (attr == &sysfs_state_rw) {
|
||||
bch2_string_opt_to_text(out, bch2_member_states,
|
||||
ca->mi.state);
|
||||
pr_char(out, '\n');
|
||||
prt_string_option(out, bch2_member_states, ca->mi.state);
|
||||
prt_char(out, '\n');
|
||||
}
|
||||
|
||||
if (attr == &sysfs_iodone)
|
||||
|
@ -932,8 +932,8 @@ int bch2_btree_perf_test(struct bch_fs *c, const char *testname,
|
||||
time = j.finish - j.start;
|
||||
|
||||
scnprintf(name_buf, sizeof(name_buf), "%s:", testname);
|
||||
bch2_hprint(&nr_buf, nr);
|
||||
bch2_hprint(&per_sec_buf, div64_u64(nr * NSEC_PER_SEC, time));
|
||||
prt_human_readable_u64(&nr_buf, nr);
|
||||
prt_human_readable_u64(&per_sec_buf, div64_u64(nr * NSEC_PER_SEC, time));
|
||||
printk(KERN_INFO "%-12s %s with %u threads in %5llu sec, %5llu nsec per iter, %5s per sec\n",
|
||||
name_buf, nr_buf.buf, nr_threads,
|
||||
div_u64(time, NSEC_PER_SEC),
|
||||
|
@ -99,135 +99,6 @@ STRTO_H(strtoll, long long)
|
||||
STRTO_H(strtoull, unsigned long long)
|
||||
STRTO_H(strtou64, u64)
|
||||
|
||||
static int bch2_printbuf_realloc(struct printbuf *out, unsigned extra)
|
||||
{
|
||||
unsigned new_size;
|
||||
char *buf;
|
||||
|
||||
if (out->pos + extra + 1 < out->size)
|
||||
return 0;
|
||||
|
||||
new_size = roundup_pow_of_two(out->size + extra);
|
||||
buf = krealloc(out->buf, new_size, !out->atomic ? GFP_KERNEL : GFP_ATOMIC);
|
||||
|
||||
if (!buf) {
|
||||
out->allocation_failure = true;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
out->buf = buf;
|
||||
out->size = new_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bch2_pr_buf(struct printbuf *out, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int len;
|
||||
|
||||
do {
|
||||
va_start(args, fmt);
|
||||
len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args);
|
||||
va_end(args);
|
||||
} while (len + 1 >= printbuf_remaining(out) &&
|
||||
!bch2_printbuf_realloc(out, len + 1));
|
||||
|
||||
len = min_t(size_t, len,
|
||||
printbuf_remaining(out) ? printbuf_remaining(out) - 1 : 0);
|
||||
out->pos += len;
|
||||
}
|
||||
|
||||
void bch2_pr_tab_rjust(struct printbuf *buf)
|
||||
{
|
||||
BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops));
|
||||
|
||||
if (printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) {
|
||||
unsigned move = buf->pos - buf->last_field;
|
||||
unsigned shift = buf->tabstops[buf->tabstop] -
|
||||
printbuf_linelen(buf);
|
||||
|
||||
bch2_printbuf_realloc(buf, shift);
|
||||
|
||||
if (buf->last_field + shift + 1 < buf->size) {
|
||||
move = min(move, buf->size - 1 - buf->last_field - shift);
|
||||
|
||||
memmove(buf->buf + buf->last_field + shift,
|
||||
buf->buf + buf->last_field,
|
||||
move);
|
||||
memset(buf->buf + buf->last_field, ' ', shift);
|
||||
buf->pos += shift;
|
||||
buf->buf[buf->pos] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
buf->last_field = buf->pos;
|
||||
buf->tabstop++;
|
||||
}
|
||||
|
||||
void bch2_hprint(struct printbuf *buf, s64 v)
|
||||
{
|
||||
int u, t = 0;
|
||||
|
||||
for (u = 0; v >= 1024 || v <= -1024; u++) {
|
||||
t = v & ~(~0U << 10);
|
||||
v >>= 10;
|
||||
}
|
||||
|
||||
pr_buf(buf, "%lli", v);
|
||||
|
||||
/*
|
||||
* 103 is magic: t is in the range [-1023, 1023] and we want
|
||||
* to turn it into [-9, 9]
|
||||
*/
|
||||
if (u && t && v < 100 && v > -100)
|
||||
pr_buf(buf, ".%i", t / 103);
|
||||
if (u)
|
||||
pr_char(buf, si_units[u]);
|
||||
}
|
||||
|
||||
void bch2_pr_units(struct printbuf *out, s64 raw, s64 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)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; list[i]; i++)
|
||||
pr_buf(out, i == selected ? "[%s] " : "%s ", list[i]);
|
||||
}
|
||||
|
||||
void bch2_flags_to_text(struct printbuf *out,
|
||||
const char * const list[], u64 flags)
|
||||
{
|
||||
unsigned bit, nr = 0;
|
||||
bool first = true;
|
||||
|
||||
while (list[nr])
|
||||
nr++;
|
||||
|
||||
while (flags && (bit = __ffs(flags)) < nr) {
|
||||
if (!first)
|
||||
pr_buf(out, ",");
|
||||
first = false;
|
||||
pr_buf(out, "%s", list[bit]);
|
||||
flags ^= 1 << bit;
|
||||
}
|
||||
}
|
||||
|
||||
u64 bch2_read_flag_list(char *opt, const char * const list[])
|
||||
{
|
||||
u64 ret = 0;
|
||||
@ -394,7 +265,7 @@ void bch2_pr_time_units(struct printbuf *out, u64 ns)
|
||||
{
|
||||
const struct time_unit *u = pick_time_units(ns);
|
||||
|
||||
pr_buf(out, "%llu %s", div_u64(ns, u->nsecs), u->name);
|
||||
prt_printf(out, "%llu %s", div_u64(ns, u->nsecs), u->name);
|
||||
}
|
||||
|
||||
void bch2_time_stats_to_text(struct printbuf *out, struct bch2_time_stats *stats)
|
||||
@ -404,29 +275,29 @@ void bch2_time_stats_to_text(struct printbuf *out, struct bch2_time_stats *stats
|
||||
u64 q, last_q = 0;
|
||||
int i;
|
||||
|
||||
pr_buf(out, "count:\t\t%llu\n",
|
||||
prt_printf(out, "count:\t\t%llu\n",
|
||||
stats->count);
|
||||
pr_buf(out, "rate:\t\t%llu/sec\n",
|
||||
prt_printf(out, "rate:\t\t%llu/sec\n",
|
||||
freq ? div64_u64(NSEC_PER_SEC, freq) : 0);
|
||||
|
||||
pr_buf(out, "frequency:\t");
|
||||
prt_printf(out, "frequency:\t");
|
||||
bch2_pr_time_units(out, freq);
|
||||
|
||||
pr_buf(out, "\navg duration:\t");
|
||||
prt_printf(out, "\navg duration:\t");
|
||||
bch2_pr_time_units(out, stats->average_duration);
|
||||
|
||||
pr_buf(out, "\nmax duration:\t");
|
||||
prt_printf(out, "\nmax duration:\t");
|
||||
bch2_pr_time_units(out, stats->max_duration);
|
||||
|
||||
i = eytzinger0_first(NR_QUANTILES);
|
||||
u = pick_time_units(stats->quantiles.entries[i].m);
|
||||
|
||||
pr_buf(out, "\nquantiles (%s):\t", u->name);
|
||||
prt_printf(out, "\nquantiles (%s):\t", u->name);
|
||||
eytzinger0_for_each(i, NR_QUANTILES) {
|
||||
bool is_last = eytzinger0_next(i, NR_QUANTILES) == -1;
|
||||
|
||||
q = max(stats->quantiles.entries[i].m, last_q);
|
||||
pr_buf(out, "%llu%s",
|
||||
prt_printf(out, "%llu%s",
|
||||
div_u64(q, u->nsecs),
|
||||
is_last ? "\n" : " ");
|
||||
last_q = q;
|
||||
@ -548,42 +419,43 @@ void bch2_pd_controller_init(struct bch_pd_controller *pd)
|
||||
|
||||
void bch2_pd_controller_debug_to_text(struct printbuf *out, struct bch_pd_controller *pd)
|
||||
{
|
||||
out->tabstops[0] = 20;
|
||||
if (!out->nr_tabstops)
|
||||
printbuf_tabstop_push(out, 20);
|
||||
|
||||
pr_buf(out, "rate:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->rate.rate);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "rate:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_s64(out, pd->rate.rate);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "target:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->last_target);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "target:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_u64(out, pd->last_target);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "actual:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->last_actual);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "actual:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_u64(out, pd->last_actual);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "proportional:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->last_proportional);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "proportional:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_s64(out, pd->last_proportional);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "derivative:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->last_derivative);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "derivative:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_s64(out, pd->last_derivative);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "change:");
|
||||
pr_tab(out);
|
||||
bch2_hprint(out, pd->last_change);
|
||||
pr_newline(out);
|
||||
prt_printf(out, "change:");
|
||||
prt_tab(out);
|
||||
prt_human_readable_s64(out, pd->last_change);
|
||||
prt_newline(out);
|
||||
|
||||
pr_buf(out, "next io:");
|
||||
pr_tab(out);
|
||||
pr_buf(out, "%llims", div64_s64(pd->rate.next - local_clock(), NSEC_PER_MSEC));
|
||||
pr_newline(out);
|
||||
prt_printf(out, "next io:");
|
||||
prt_tab(out);
|
||||
prt_printf(out, "%llims", div64_s64(pd->rate.next - local_clock(), NSEC_PER_MSEC));
|
||||
prt_newline(out);
|
||||
}
|
||||
|
||||
/* misc: */
|
||||
|
@ -237,127 +237,39 @@ 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,
|
||||
};
|
||||
#include "printbuf.h"
|
||||
|
||||
struct printbuf {
|
||||
char *buf;
|
||||
unsigned size;
|
||||
unsigned pos;
|
||||
unsigned last_newline;
|
||||
unsigned last_field;
|
||||
unsigned indent;
|
||||
enum printbuf_units units:8;
|
||||
u8 atomic;
|
||||
bool allocation_failure:1;
|
||||
u8 tabstop;
|
||||
u8 tabstops[4];
|
||||
};
|
||||
#define prt_vprintf(_out, ...) bch2_prt_vprintf(_out, __VA_ARGS__)
|
||||
#define prt_printf(_out, ...) bch2_prt_printf(_out, __VA_ARGS__)
|
||||
#define printbuf_str(_buf) bch2_printbuf_str(_buf)
|
||||
#define printbuf_exit(_buf) bch2_printbuf_exit(_buf)
|
||||
|
||||
#define PRINTBUF ((struct printbuf) { NULL })
|
||||
#define printbuf_tabstops_reset(_buf) bch2_printbuf_tabstops_reset(_buf)
|
||||
#define printbuf_tabstop_pop(_buf) bch2_printbuf_tabstop_pop(_buf)
|
||||
#define printbuf_tabstop_push(_buf, _n) bch2_printbuf_tabstop_push(_buf, _n)
|
||||
|
||||
static inline void printbuf_exit(struct printbuf *buf)
|
||||
{
|
||||
kfree(buf->buf);
|
||||
buf->buf = ERR_PTR(-EINTR); /* poison value */
|
||||
}
|
||||
#define printbuf_indent_add(_out, _n) bch2_printbuf_indent_add(_out, _n)
|
||||
#define printbuf_indent_sub(_out, _n) bch2_printbuf_indent_sub(_out, _n)
|
||||
|
||||
static inline void printbuf_reset(struct printbuf *buf)
|
||||
{
|
||||
buf->pos = 0;
|
||||
buf->last_newline = 0;
|
||||
buf->last_field = 0;
|
||||
buf->indent = 0;
|
||||
buf->tabstop = 0;
|
||||
}
|
||||
#define prt_newline(_out) bch2_prt_newline(_out)
|
||||
#define prt_tab(_out) bch2_prt_tab(_out)
|
||||
#define prt_tab_rjust(_out) bch2_prt_tab_rjust(_out)
|
||||
|
||||
static inline size_t printbuf_remaining(struct printbuf *buf)
|
||||
{
|
||||
return buf->size - buf->pos;
|
||||
}
|
||||
|
||||
static inline size_t printbuf_linelen(struct printbuf *buf)
|
||||
{
|
||||
return buf->pos - buf->last_newline;
|
||||
}
|
||||
|
||||
void bch2_pr_buf(struct printbuf *out, const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
#define pr_buf(_out, ...) bch2_pr_buf(_out, __VA_ARGS__)
|
||||
|
||||
static inline void pr_char(struct printbuf *out, char c)
|
||||
{
|
||||
bch2_pr_buf(out, "%c", c);
|
||||
}
|
||||
|
||||
static inline void pr_indent_push(struct printbuf *buf, unsigned spaces)
|
||||
{
|
||||
buf->indent += spaces;
|
||||
while (spaces--)
|
||||
pr_char(buf, ' ');
|
||||
}
|
||||
|
||||
static inline void pr_indent_pop(struct printbuf *buf, unsigned spaces)
|
||||
{
|
||||
if (buf->last_newline + buf->indent == buf->pos) {
|
||||
buf->pos -= spaces;
|
||||
buf->buf[buf->pos] = '\0';
|
||||
}
|
||||
buf->indent -= spaces;
|
||||
}
|
||||
|
||||
static inline void pr_newline(struct printbuf *buf)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
pr_char(buf, '\n');
|
||||
|
||||
buf->last_newline = buf->pos;
|
||||
|
||||
for (i = 0; i < buf->indent; i++)
|
||||
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++;
|
||||
}
|
||||
|
||||
void bch2_pr_tab_rjust(struct printbuf *);
|
||||
|
||||
static inline void pr_tab_rjust(struct printbuf *buf)
|
||||
{
|
||||
bch2_pr_tab_rjust(buf);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
#define prt_bytes_indented(...) bch2_prt_bytes_indented(__VA_ARGS__)
|
||||
#define prt_u64(_out, _v) prt_printf(_out, "%llu", _v)
|
||||
#define prt_human_readable_u64(...) bch2_prt_human_readable_u64(__VA_ARGS__)
|
||||
#define prt_human_readable_s64(...) bch2_prt_human_readable_s64(__VA_ARGS__)
|
||||
#define prt_units_u64(...) bch2_prt_units_u64(__VA_ARGS__)
|
||||
#define prt_units_s64(...) bch2_prt_units_s64(__VA_ARGS__)
|
||||
#define prt_string_option(...) bch2_prt_string_option(__VA_ARGS__)
|
||||
#define prt_bitflags(...) bch2_prt_bitflags(__VA_ARGS__)
|
||||
|
||||
void bch2_pr_time_units(struct printbuf *, u64);
|
||||
|
||||
#ifdef __KERNEL__
|
||||
static inline void pr_time(struct printbuf *out, u64 time)
|
||||
{
|
||||
pr_buf(out, "%llu", time);
|
||||
prt_printf(out, "%llu", time);
|
||||
}
|
||||
#else
|
||||
#include <time.h>
|
||||
@ -368,9 +280,9 @@ static inline void pr_time(struct printbuf *out, u64 _time)
|
||||
struct tm *tm = localtime(&time);
|
||||
size_t err = strftime(time_str, sizeof(time_str), "%c", tm);
|
||||
if (!err)
|
||||
pr_buf(out, "(formatting error)");
|
||||
prt_printf(out, "(formatting error)");
|
||||
else
|
||||
pr_buf(out, "%s", time_str);
|
||||
prt_printf(out, "%s", time_str);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -388,7 +300,7 @@ static inline void pr_uuid(struct printbuf *out, u8 *uuid)
|
||||
char uuid_str[40];
|
||||
|
||||
uuid_unparse_lower(uuid, uuid_str);
|
||||
pr_buf(out, "%s", uuid_str);
|
||||
prt_printf(out, "%s", uuid_str);
|
||||
}
|
||||
|
||||
int bch2_strtoint_h(const char *, int *);
|
||||
@ -454,7 +366,7 @@ static inline int bch2_strtoul_h(const char *cp, long *res)
|
||||
})
|
||||
|
||||
#define snprint(out, var) \
|
||||
pr_buf(out, \
|
||||
prt_printf(out, \
|
||||
type_is(var, int) ? "%i\n" \
|
||||
: type_is(var, unsigned) ? "%u\n" \
|
||||
: type_is(var, long) ? "%li\n" \
|
||||
@ -464,14 +376,8 @@ static inline int bch2_strtoul_h(const char *cp, long *res)
|
||||
: type_is(var, char *) ? "%s\n" \
|
||||
: "%i\n", var)
|
||||
|
||||
void bch2_hprint(struct printbuf *, s64);
|
||||
|
||||
bool bch2_is_zero(const void *, size_t);
|
||||
|
||||
void bch2_string_opt_to_text(struct printbuf *,
|
||||
const char * const [], size_t);
|
||||
|
||||
void bch2_flags_to_text(struct printbuf *, const char * const[], u64);
|
||||
u64 bch2_read_flag_list(char *, const char * const[]);
|
||||
|
||||
#define NR_QUANTILES 15
|
||||
|
@ -76,7 +76,7 @@ int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
struct bkey_s_c_xattr xattr = bkey_s_c_to_xattr(k);
|
||||
|
||||
if (bkey_val_bytes(k.k) < sizeof(struct bch_xattr)) {
|
||||
pr_buf(err, "incorrect value size (%zu < %zu)",
|
||||
prt_printf(err, "incorrect value size (%zu < %zu)",
|
||||
bkey_val_bytes(k.k), sizeof(*xattr.v));
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -84,7 +84,7 @@ int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
if (bkey_val_u64s(k.k) <
|
||||
xattr_val_u64s(xattr.v->x_name_len,
|
||||
le16_to_cpu(xattr.v->x_val_len))) {
|
||||
pr_buf(err, "value too small (%zu < %u)",
|
||||
prt_printf(err, "value too small (%zu < %u)",
|
||||
bkey_val_u64s(k.k),
|
||||
xattr_val_u64s(xattr.v->x_name_len,
|
||||
le16_to_cpu(xattr.v->x_val_len)));
|
||||
@ -95,7 +95,7 @@ int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
if (bkey_val_u64s(k.k) >
|
||||
xattr_val_u64s(xattr.v->x_name_len,
|
||||
le16_to_cpu(xattr.v->x_val_len) + 4)) {
|
||||
pr_buf(err, "value too big (%zu > %u)",
|
||||
prt_printf(err, "value too big (%zu > %u)",
|
||||
bkey_val_u64s(k.k),
|
||||
xattr_val_u64s(xattr.v->x_name_len,
|
||||
le16_to_cpu(xattr.v->x_val_len) + 4));
|
||||
@ -104,12 +104,12 @@ int bch2_xattr_invalid(const struct bch_fs *c, struct bkey_s_c k,
|
||||
|
||||
handler = bch2_xattr_type_to_handler(xattr.v->x_type);
|
||||
if (!handler) {
|
||||
pr_buf(err, "invalid type (%u)", xattr.v->x_type);
|
||||
prt_printf(err, "invalid type (%u)", xattr.v->x_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (memchr(xattr.v->x_name, '\0', xattr.v->x_name_len)) {
|
||||
pr_buf(err, "xattr name has invalid characters");
|
||||
prt_printf(err, "xattr name has invalid characters");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -124,13 +124,13 @@ void bch2_xattr_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
|
||||
handler = bch2_xattr_type_to_handler(xattr.v->x_type);
|
||||
if (handler && handler->prefix)
|
||||
pr_buf(out, "%s", handler->prefix);
|
||||
prt_printf(out, "%s", handler->prefix);
|
||||
else if (handler)
|
||||
pr_buf(out, "(type %u)", xattr.v->x_type);
|
||||
prt_printf(out, "(type %u)", xattr.v->x_type);
|
||||
else
|
||||
pr_buf(out, "(unknown type %u)", xattr.v->x_type);
|
||||
prt_printf(out, "(unknown type %u)", xattr.v->x_type);
|
||||
|
||||
pr_buf(out, "%.*s:%.*s",
|
||||
prt_printf(out, "%.*s:%.*s",
|
||||
xattr.v->x_name_len,
|
||||
xattr.v->x_name,
|
||||
le16_to_cpu(xattr.v->x_val_len),
|
||||
|
Loading…
Reference in New Issue
Block a user