Commit fb64f3fd authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: BCH_JSET_ENTRY_log

Add a journal entry type for logging messages, and add an option to use
it to log the transaction name - this makes for a very handy debugging
tool, as with it we can use the 'bcachefs list_journal' command to see
not only what updates were done, but what was doing them.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent f0f41a6d
...@@ -1430,6 +1430,7 @@ LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30); ...@@ -1430,6 +1430,7 @@ LE64_BITMASK(BCH_SB_INODES_USE_KEY_CACHE,struct bch_sb, flags[3], 29, 30);
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DELAY,struct bch_sb, flags[3], 30, 62);
LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63); LE64_BITMASK(BCH_SB_JOURNAL_FLUSH_DISABLED,struct bch_sb, flags[3], 62, 63);
LE64_BITMASK(BCH_SB_JOURNAL_RECLAIM_DELAY,struct bch_sb, flags[4], 0, 32); LE64_BITMASK(BCH_SB_JOURNAL_RECLAIM_DELAY,struct bch_sb, flags[4], 0, 32);
LE64_BITMASK(BCH_SB_JOURNAL_TRANSACTION_NAMES,struct bch_sb, flags[4], 32, 33);
/* /*
* Features: * Features:
...@@ -1667,7 +1668,8 @@ static inline __u64 __bset_magic(struct bch_sb *sb) ...@@ -1667,7 +1668,8 @@ static inline __u64 __bset_magic(struct bch_sb *sb)
x(usage, 5) \ x(usage, 5) \
x(data_usage, 6) \ x(data_usage, 6) \
x(clock, 7) \ x(clock, 7) \
x(dev_usage, 8) x(dev_usage, 8) \
x(log, 9)
enum { enum {
#define x(f, nr) BCH_JSET_ENTRY_##f = nr, #define x(f, nr) BCH_JSET_ENTRY_##f = nr,
...@@ -1739,6 +1741,11 @@ struct jset_entry_dev_usage { ...@@ -1739,6 +1741,11 @@ struct jset_entry_dev_usage {
struct jset_entry_dev_usage_type d[]; struct jset_entry_dev_usage_type d[];
} __attribute__((packed)); } __attribute__((packed));
struct jset_entry_log {
struct jset_entry entry;
u8 d[];
} __attribute__((packed));
/* /*
* On disk format for a journal entry: * On disk format for a journal entry:
* seq is monotonically increasing; every journal entry has its own unique * seq is monotonically increasing; every journal entry has its own unique
......
...@@ -380,6 +380,7 @@ struct btree_trans { ...@@ -380,6 +380,7 @@ struct btree_trans {
bool in_traverse_all:1; bool in_traverse_all:1;
bool restarted:1; bool restarted:1;
bool paths_sorted:1; bool paths_sorted:1;
bool journal_transaction_names:1;
/* /*
* For when bch2_trans_update notices we'll be splitting a compressed * For when bch2_trans_update notices we'll be splitting a compressed
* extent: * extent:
......
...@@ -290,6 +290,31 @@ static inline int bch2_trans_journal_res_get(struct btree_trans *trans, ...@@ -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; 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 static inline enum btree_insert_ret
btree_key_can_insert(struct btree_trans *trans, btree_key_can_insert(struct btree_trans *trans,
struct btree *b, struct btree *b,
...@@ -451,6 +476,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans, ...@@ -451,6 +476,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
JOURNAL_RES_GET_NONBLOCK); JOURNAL_RES_GET_NONBLOCK);
if (ret) if (ret)
return ret; return ret;
if (unlikely(trans->journal_transaction_names))
journal_transaction_name(trans);
} else { } else {
trans->journal_res.seq = c->journal.replay_journal_seq; trans->journal_res.seq = c->journal.replay_journal_seq;
} }
...@@ -911,6 +939,7 @@ static int bch2_trans_commit_run_triggers(struct btree_trans *trans) ...@@ -911,6 +939,7 @@ static int bch2_trans_commit_run_triggers(struct btree_trans *trans)
int __bch2_trans_commit(struct btree_trans *trans) int __bch2_trans_commit(struct btree_trans *trans)
{ {
struct bch_fs *c = trans->c;
struct btree_insert_entry *i = NULL; struct btree_insert_entry *i = NULL;
unsigned u64s; unsigned u64s;
int ret = 0; int ret = 0;
...@@ -920,15 +949,20 @@ int __bch2_trans_commit(struct btree_trans *trans) ...@@ -920,15 +949,20 @@ int __bch2_trans_commit(struct btree_trans *trans)
goto out_reset; goto out_reset;
if (trans->flags & BTREE_INSERT_GC_LOCK_HELD) 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)); memset(&trans->journal_preres, 0, sizeof(trans->journal_preres));
trans->journal_u64s = trans->extra_journal_entry_u64s; trans->journal_u64s = trans->extra_journal_entry_u64s;
trans->journal_preres_u64s = 0; 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) && 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); ret = bch2_trans_commit_get_rw_cold(trans);
if (ret) if (ret)
goto out_reset; goto out_reset;
...@@ -972,7 +1006,7 @@ int __bch2_trans_commit(struct btree_trans *trans) ...@@ -972,7 +1006,7 @@ int __bch2_trans_commit(struct btree_trans *trans)
} }
if (trans->extra_journal_res) { 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->extra_journal_res,
(trans->flags & BTREE_INSERT_NOFAIL) (trans->flags & BTREE_INSERT_NOFAIL)
? BCH_DISK_RESERVATION_NOFAIL : 0); ? BCH_DISK_RESERVATION_NOFAIL : 0);
...@@ -991,10 +1025,10 @@ int __bch2_trans_commit(struct btree_trans *trans) ...@@ -991,10 +1025,10 @@ int __bch2_trans_commit(struct btree_trans *trans)
if (ret) if (ret)
goto err; goto err;
out: 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))) if (likely(!(trans->flags & BTREE_INSERT_NOCHECK_RW)))
percpu_ref_put(&trans->c->writes); percpu_ref_put(&c->writes);
out_reset: out_reset:
trans_for_each_update(trans, i) trans_for_each_update(trans, i)
bch2_path_put(trans, i->path, true); bch2_path_put(trans, i->path, true);
......
...@@ -478,6 +478,14 @@ static int journal_entry_validate_dev_usage(struct bch_fs *c, ...@@ -478,6 +478,14 @@ static int journal_entry_validate_dev_usage(struct bch_fs *c,
return ret; return ret;
} }
static int journal_entry_validate_log(struct bch_fs *c,
const char *where,
struct jset_entry *entry,
unsigned version, int big_endian, int write)
{
return 0;
}
struct jset_entry_ops { struct jset_entry_ops {
int (*validate)(struct bch_fs *, const char *, int (*validate)(struct bch_fs *, const char *,
struct jset_entry *, unsigned, int, int); struct jset_entry *, unsigned, int, int);
......
...@@ -327,6 +327,11 @@ enum opt_type { ...@@ -327,6 +327,11 @@ enum opt_type {
OPT_BOOL(), \ OPT_BOOL(), \
NO_SB_OPT, false, \ NO_SB_OPT, false, \
NULL, "Read all journal entries, not just dirty ones")\ NULL, "Read all journal entries, not just dirty ones")\
x(journal_transaction_names, u8, \
OPT_FS|OPT_FORMAT|OPT_MOUNT|OPT_RUNTIME, \
OPT_BOOL(), \
BCH_SB_JOURNAL_TRANSACTION_NAMES, true, \
NULL, "Log transaction function names in journal") \
x(noexcl, u8, \ x(noexcl, u8, \
OPT_FS|OPT_MOUNT, \ OPT_FS|OPT_MOUNT, \
OPT_BOOL(), \ OPT_BOOL(), \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment