Update bcachefs sources to 9d28e4a535 bcachefs: bch2_journal_entry_to_text()

This commit is contained in:
Kent Overstreet 2021-12-31 17:23:40 -05:00
parent 12fe5797ad
commit d08291637f
12 changed files with 229 additions and 44 deletions

View File

@ -1 +1 @@
916d92b6b46b13873118a608ff16212f966375ba
9d28e4a535cac3b88104a4525dd39fc16175f38c

View File

@ -76,6 +76,7 @@
#include <asm/byteorder.h>
#include <linux/kernel.h>
#include <linux/uuid.h>
#include "vstructs.h"
#define LE_BITMASK(_bits, name, type, field, offset, end) \
static const unsigned name##_OFFSET = offset; \
@ -1660,7 +1661,8 @@ static inline __u64 __bset_magic(struct bch_sb *sb)
x(usage, 5) \
x(data_usage, 6) \
x(clock, 7) \
x(dev_usage, 8)
x(dev_usage, 8) \
x(log, 9)
enum {
#define x(f, nr) BCH_JSET_ENTRY_##f = nr,
@ -1690,11 +1692,16 @@ struct jset_entry_blacklist_v2 {
__le64 end;
};
#define BCH_FS_USAGE_TYPES() \
x(reserved, 0) \
x(inodes, 1) \
x(key_version, 2)
enum {
FS_USAGE_RESERVED = 0,
FS_USAGE_INODES = 1,
FS_USAGE_KEY_VERSION = 2,
FS_USAGE_NR = 3
#define x(f, nr) BCH_FS_USAGE_##f = nr,
BCH_FS_USAGE_TYPES()
#undef x
BCH_FS_USAGE_NR
};
struct jset_entry_usage {
@ -1732,6 +1739,17 @@ struct jset_entry_dev_usage {
struct jset_entry_dev_usage_type d[];
} __attribute__((packed));
static inline unsigned jset_entry_dev_usage_nr_types(struct jset_entry_dev_usage *u)
{
return (vstruct_bytes(&u->entry) - sizeof(struct jset_entry_dev_usage)) /
sizeof(struct jset_entry_dev_usage_type);
}
struct jset_entry_log {
struct jset_entry entry;
u8 d[];
} __attribute__((packed));
/*
* On disk format for a journal entry:
* seq is monotonically increasing; every journal entry has its own unique

View File

@ -1547,10 +1547,6 @@ static inline void __bch2_btree_node_iter_advance(struct btree_node_iter *iter,
EBUG_ON(iter->data->k > iter->data->end);
while (!__btree_node_iter_set_end(iter, 0) &&
!__bch2_btree_node_iter_peek_all(iter, b)->u64s)
iter->data->k++;
if (unlikely(__btree_node_iter_set_end(iter, 0))) {
bch2_btree_node_iter_set_drop(iter, iter->data);
return;

View File

@ -382,6 +382,7 @@ struct btree_trans {
bool used_mempool:1;
bool in_traverse_all:1;
bool restarted:1;
bool journal_transaction_names:1;
/*
* For when bch2_trans_update notices we'll be splitting a compressed
* extent:

View File

@ -290,6 +290,31 @@ static inline int bch2_trans_journal_res_get(struct btree_trans *trans,
return ret == -EAGAIN ? BTREE_INSERT_NEED_JOURNAL_RES : ret;
}
#define JSET_ENTRY_LOG_U64s 4
static noinline void journal_transaction_name(struct btree_trans *trans)
{
struct bch_fs *c = trans->c;
struct jset_entry *entry = journal_res_entry(&c->journal, &trans->journal_res);
struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
unsigned u64s = JSET_ENTRY_LOG_U64s - 1;
unsigned b, buflen = u64s * sizeof(u64);
l->entry.u64s = cpu_to_le16(u64s);
l->entry.btree_id = 0;
l->entry.level = 0;
l->entry.type = BCH_JSET_ENTRY_log;
l->entry.pad[0] = 0;
l->entry.pad[1] = 0;
l->entry.pad[2] = 0;
b = snprintf(l->d, buflen, "%ps", (void *) trans->ip);
while (b < buflen)
l->d[b++] = '\0';
trans->journal_res.offset += JSET_ENTRY_LOG_U64s;
trans->journal_res.u64s -= JSET_ENTRY_LOG_U64s;
}
static inline enum btree_insert_ret
btree_key_can_insert(struct btree_trans *trans,
struct btree *b,
@ -454,6 +479,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
trans->journal_res.seq = c->journal.replay_journal_seq;
}
if (unlikely(trans->journal_transaction_names))
journal_transaction_name(trans);
if (unlikely(trans->extra_journal_entry_u64s)) {
memcpy_u64s_small(journal_res_entry(&c->journal, &trans->journal_res),
trans->extra_journal_entries,
@ -910,6 +938,7 @@ static int bch2_trans_commit_run_triggers(struct btree_trans *trans)
int __bch2_trans_commit(struct btree_trans *trans)
{
struct bch_fs *c = trans->c;
struct btree_insert_entry *i = NULL;
unsigned u64s;
int ret = 0;
@ -919,15 +948,20 @@ int __bch2_trans_commit(struct btree_trans *trans)
goto out_reset;
if (trans->flags & BTREE_INSERT_GC_LOCK_HELD)
lockdep_assert_held(&trans->c->gc_lock);
lockdep_assert_held(&c->gc_lock);
memset(&trans->journal_preres, 0, sizeof(trans->journal_preres));
trans->journal_u64s = trans->extra_journal_entry_u64s;
trans->journal_preres_u64s = 0;
trans->journal_transaction_names = READ_ONCE(c->opts.journal_transaction_names);
if (trans->journal_transaction_names)
trans->journal_u64s += JSET_ENTRY_LOG_U64s;
if (!(trans->flags & BTREE_INSERT_NOCHECK_RW) &&
unlikely(!percpu_ref_tryget(&trans->c->writes))) {
unlikely(!percpu_ref_tryget(&c->writes))) {
ret = bch2_trans_commit_get_rw_cold(trans);
if (ret)
goto out_reset;
@ -969,7 +1003,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
}
if (trans->extra_journal_res) {
ret = bch2_disk_reservation_add(trans->c, trans->disk_res,
ret = bch2_disk_reservation_add(c, trans->disk_res,
trans->extra_journal_res,
(trans->flags & BTREE_INSERT_NOFAIL)
? BCH_DISK_RESERVATION_NOFAIL : 0);
@ -988,10 +1022,10 @@ retry:
if (ret)
goto err;
out:
bch2_journal_preres_put(&trans->c->journal, &trans->journal_preres);
bch2_journal_preres_put(&c->journal, &trans->journal_preres);
if (likely(!(trans->flags & BTREE_INSERT_NOCHECK_RW)))
percpu_ref_put(&trans->c->writes);
percpu_ref_put(&c->writes);
out_reset:
trans_for_each_update(trans, i)
bch2_path_put(trans, i->path, true);

View File

@ -358,13 +358,6 @@ static void bch2_dev_usage_update(struct bch_fs *c, struct bch_dev *ca,
struct bch_fs_usage *fs_usage;
struct bch_dev_usage *u;
/*
* Hack for bch2_fs_initialize path, where we're first marking sb and
* journal non-transactionally:
*/
if (!journal_seq && !test_bit(BCH_FS_INITIALIZED, &c->flags))
journal_seq = 1;
preempt_disable();
fs_usage = fs_usage_ptr(c, journal_seq, gc);
u = dev_usage_ptr(ca, journal_seq, gc);

View File

@ -274,7 +274,7 @@ fsck_err:
return ret;
}
static int journal_entry_validate_btree_keys(struct bch_fs *c,
static int journal_entry_btree_keys_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -295,7 +295,18 @@ static int journal_entry_validate_btree_keys(struct bch_fs *c,
return 0;
}
static int journal_entry_validate_btree_root(struct bch_fs *c,
static void journal_entry_btree_keys_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct bkey_i *k;
pr_buf(out, "btree=%s l=%u ", bch2_btree_ids[entry->btree_id], entry->level);
vstruct_for_each(entry, k)
bch2_bkey_val_to_text(out, c, bkey_i_to_s_c(k));
}
static int journal_entry_btree_root_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -323,7 +334,13 @@ fsck_err:
return ret;
}
static int journal_entry_validate_prio_ptrs(struct bch_fs *c,
static void journal_entry_btree_root_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
journal_entry_btree_keys_to_text(out, c, entry);
}
static int journal_entry_prio_ptrs_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -332,7 +349,12 @@ static int journal_entry_validate_prio_ptrs(struct bch_fs *c,
return 0;
}
static int journal_entry_validate_blacklist(struct bch_fs *c,
static void journal_entry_prio_ptrs_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
}
static int journal_entry_blacklist_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -347,7 +369,16 @@ fsck_err:
return ret;
}
static int journal_entry_validate_blacklist_v2(struct bch_fs *c,
static void journal_entry_blacklist_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_blacklist *bl =
container_of(entry, struct jset_entry_blacklist, entry);
pr_buf(out, "seq=%llu", le64_to_cpu(bl->seq));
}
static int journal_entry_blacklist_v2_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -373,7 +404,18 @@ fsck_err:
return ret;
}
static int journal_entry_validate_usage(struct bch_fs *c,
static void journal_entry_blacklist_v2_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_blacklist_v2 *bl =
container_of(entry, struct jset_entry_blacklist_v2, entry);
pr_buf(out, "start=%llu end=%llu",
le64_to_cpu(bl->start),
le64_to_cpu(bl->end));
}
static int journal_entry_usage_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -394,7 +436,18 @@ fsck_err:
return ret;
}
static int journal_entry_validate_data_usage(struct bch_fs *c,
static void journal_entry_usage_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_usage *u =
container_of(entry, struct jset_entry_usage, entry);
pr_buf(out, "type=%s v=%llu",
bch2_fs_usage_types[u->entry.btree_id],
le64_to_cpu(u->v));
}
static int journal_entry_data_usage_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -416,7 +469,17 @@ fsck_err:
return ret;
}
static int journal_entry_validate_clock(struct bch_fs *c,
static void journal_entry_data_usage_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_data_usage *u =
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));
}
static int journal_entry_clock_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -442,7 +505,16 @@ fsck_err:
return ret;
}
static int journal_entry_validate_dev_usage(struct bch_fs *c,
static void journal_entry_clock_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
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));
}
static int journal_entry_dev_usage_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
@ -479,15 +551,59 @@ fsck_err:
return ret;
}
static void journal_entry_dev_usage_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_dev_usage *u =
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));
for (i = 0; i < nr_types; i++) {
if (i < BCH_DATA_NR)
pr_buf(out, "%s", bch2_data_types[i]);
else
pr_buf(out, "(unknown data type %u)", i);
pr_buf(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 buckets_unavailable: %llu",
le64_to_cpu(u->buckets_ec),
le64_to_cpu(u->buckets_unavailable));
}
static int journal_entry_log_validate(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
{
return 0;
}
static void journal_entry_log_to_text(struct printbuf *out, struct bch_fs *c,
struct jset_entry *entry)
{
struct jset_entry_log *l = container_of(entry, struct jset_entry_log, entry);
unsigned bytes = vstruct_bytes(entry) - offsetof(struct jset_entry_log, d);
bch_scnmemcpy(out, l->d, strnlen(l->d, bytes));
}
struct jset_entry_ops {
int (*validate)(struct bch_fs *, const char *,
struct jset_entry *, unsigned, int, int);
void (*to_text)(struct printbuf *, struct bch_fs *, struct jset_entry *);
};
static const struct jset_entry_ops bch2_jset_entry_ops[] = {
#define x(f, nr) \
[BCH_JSET_ENTRY_##f] = (struct jset_entry_ops) { \
.validate = journal_entry_validate_##f, \
.validate = journal_entry_##f##_validate, \
.to_text = journal_entry_##f##_to_text, \
},
BCH_JSET_ENTRY_TYPES()
#undef x
@ -503,6 +619,17 @@ int bch2_journal_entry_validate(struct bch_fs *c, const char *where,
: 0;
}
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]);
bch2_jset_entry_ops[entry->type].to_text(out, c, entry);
} else {
pr_buf(out, "(unknown type %u)", entry->type);
}
}
static int jset_validate_entries(struct bch_fs *c, struct jset *jset,
int write)
{

View File

@ -40,8 +40,10 @@ static inline struct jset_entry *__jset_entry_type_next(struct jset *jset,
for_each_jset_entry_type(entry, jset, BCH_JSET_ENTRY_btree_keys) \
vstruct_for_each_safe(entry, k, _n)
int bch2_journal_entry_validate(struct bch_fs *, const char *, struct jset_entry *,
unsigned, int, int);
int bch2_journal_entry_validate(struct bch_fs *, const char *,
struct jset_entry *, unsigned, int, int);
void bch2_journal_entry_to_text(struct printbuf *, struct bch_fs *,
struct jset_entry *);
int bch2_journal_read(struct bch_fs *, struct list_head *, u64 *, u64 *);

View File

@ -71,6 +71,16 @@ const char * const bch2_member_states[] = {
NULL
};
const char * const bch2_jset_entry_types[] = {
BCH_JSET_ENTRY_TYPES()
NULL
};
const char * const bch2_fs_usage_types[] = {
BCH_FS_USAGE_TYPES()
NULL
};
#undef x
const char * const bch2_d_types[BCH_DT_MAX] = {

View File

@ -20,6 +20,8 @@ extern const char * const bch2_str_hash_types[];
extern const char * const bch2_str_hash_opts[];
extern const char * const bch2_data_types[];
extern const char * const bch2_member_states[];
extern const char * const bch2_jset_entry_types[];
extern const char * const bch2_fs_usage_types[];
extern const char * const bch2_d_types[];
static inline const char *bch2_d_type_str(unsigned d_type)
@ -327,6 +329,11 @@ enum opt_type {
OPT_BOOL(), \
NO_SB_OPT, false, \
NULL, "Read all journal entries, not just dirty ones")\
x(journal_transaction_names, u8, \
OPT_FS|OPT_MOUNT|OPT_RUNTIME, \
OPT_BOOL(), \
NO_SB_OPT, false, \
NULL, "Log transaction function names in journal") \
x(noexcl, u8, \
OPT_FS|OPT_MOUNT, \
OPT_BOOL(), \

View File

@ -714,15 +714,15 @@ static int journal_replay_entry_early(struct bch_fs *c,
container_of(entry, struct jset_entry_usage, entry);
switch (entry->btree_id) {
case FS_USAGE_RESERVED:
case BCH_FS_USAGE_reserved:
if (entry->level < BCH_REPLICAS_MAX)
c->usage_base->persistent_reserved[entry->level] =
le64_to_cpu(u->v);
break;
case FS_USAGE_INODES:
case BCH_FS_USAGE_inodes:
c->usage_base->nr_inodes = le64_to_cpu(u->v);
break;
case FS_USAGE_KEY_VERSION:
case BCH_FS_USAGE_key_version:
atomic64_set(&c->key_version,
le64_to_cpu(u->v));
break;
@ -742,10 +742,7 @@ static int journal_replay_entry_early(struct bch_fs *c,
struct jset_entry_dev_usage *u =
container_of(entry, struct jset_entry_dev_usage, entry);
struct bch_dev *ca = bch_dev_bkey_exists(c, le32_to_cpu(u->dev));
unsigned bytes = jset_u64s(le16_to_cpu(entry->u64s)) * sizeof(u64);
unsigned nr_types = (bytes - sizeof(struct jset_entry_dev_usage)) /
sizeof(struct jset_entry_dev_usage_type);
unsigned i;
unsigned i, nr_types = jset_entry_dev_usage_nr_types(u);
ca->usage_base->buckets_ec = le64_to_cpu(u->buckets_ec);
ca->usage_base->buckets_unavailable = le64_to_cpu(u->buckets_unavailable);

View File

@ -1027,7 +1027,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
struct jset_entry_usage, entry);
u->entry.type = BCH_JSET_ENTRY_usage;
u->entry.btree_id = FS_USAGE_INODES;
u->entry.btree_id = BCH_FS_USAGE_inodes;
u->v = cpu_to_le64(c->usage_base->nr_inodes);
}
@ -1037,7 +1037,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
struct jset_entry_usage, entry);
u->entry.type = BCH_JSET_ENTRY_usage;
u->entry.btree_id = FS_USAGE_KEY_VERSION;
u->entry.btree_id = BCH_FS_USAGE_key_version;
u->v = cpu_to_le64(atomic64_read(&c->key_version));
}
@ -1047,7 +1047,7 @@ void bch2_journal_super_entries_add_common(struct bch_fs *c,
struct jset_entry_usage, entry);
u->entry.type = BCH_JSET_ENTRY_usage;
u->entry.btree_id = FS_USAGE_RESERVED;
u->entry.btree_id = BCH_FS_USAGE_reserved;
u->entry.level = i;
u->v = cpu_to_le64(c->usage_base->persistent_reserved[i]);
}