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

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
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -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_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_TRANSACTION_NAMES,struct bch_sb, flags[4], 32, 33);

/*
 * Features:
@@ -1667,7 +1668,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,
@@ -1739,6 +1741,11 @@ struct jset_entry_dev_usage {
	struct jset_entry_dev_usage_type d[];
} __attribute__((packed));

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
+1 −0
Original line number Diff line number Diff line
@@ -380,6 +380,7 @@ struct btree_trans {
	bool			in_traverse_all:1;
	bool			restarted:1;
	bool			paths_sorted:1;
	bool			journal_transaction_names:1;
	/*
	 * For when bch2_trans_update notices we'll be splitting a compressed
	 * extent:
+39 −5
Original line number Diff line number Diff line
@@ -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,
@@ -451,6 +476,9 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
				JOURNAL_RES_GET_NONBLOCK);
		if (ret)
			return ret;

		if (unlikely(trans->journal_transaction_names))
			journal_transaction_name(trans);
	} else {
		trans->journal_res.seq = c->journal.replay_journal_seq;
	}
@@ -911,6 +939,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;
@@ -920,15 +949,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;
@@ -972,7 +1006,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);
@@ -991,10 +1025,10 @@ int __bch2_trans_commit(struct btree_trans *trans)
	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);
+8 −0
Original line number Diff line number Diff line
@@ -478,6 +478,14 @@ static int journal_entry_validate_dev_usage(struct bch_fs *c,
	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 {
	int (*validate)(struct bch_fs *, const char *,
			struct jset_entry *, unsigned, int, int);
+5 −0
Original line number Diff line number Diff line
@@ -327,6 +327,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_FORMAT|OPT_MOUNT|OPT_RUNTIME,			\
	  OPT_BOOL(),							\
	  BCH_SB_JOURNAL_TRANSACTION_NAMES, true,			\
	  NULL,		"Log transaction function names in journal")	\
	x(noexcl,			u8,				\
	  OPT_FS|OPT_MOUNT,						\
	  OPT_BOOL(),							\