Commit fb8c835b authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: bch2_journal_meta() takes ref on c->writes

This part of addressing
https://github.com/koverstreet/bcachefs/issues/656



where we're getting stuck in bch2_journal_meta() in the dump tool.

We shouldn't be invoking the journal without a ref on c->writes (if
we're not RW), and there's no reason for the dump tool to be going
read-write.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent 8b22abb4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -688,6 +688,7 @@ struct btree_trans_buf {
	((subvol_inum) { BCACHEFS_ROOT_SUBVOL,	BCACHEFS_ROOT_INO })

#define BCH_WRITE_REFS()						\
	x(journal)							\
	x(trans)							\
	x(write)							\
	x(promote)							\
+17 −10
Original line number Diff line number Diff line
@@ -831,19 +831,14 @@ bool bch2_journal_noflush_seq(struct journal *j, u64 seq)
	return ret;
}

int bch2_journal_meta(struct journal *j)
static int __bch2_journal_meta(struct journal *j)
{
	struct journal_buf *buf;
	struct journal_res res;
	int ret;

	memset(&res, 0, sizeof(res));

	ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
	struct journal_res res = {};
	int ret = bch2_journal_res_get(j, &res, jset_u64s(0), 0);
	if (ret)
		return ret;

	buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
	struct journal_buf *buf = j->buf + (res.seq & JOURNAL_BUF_MASK);
	buf->must_flush = true;

	if (!buf->flush_time) {
@@ -856,6 +851,18 @@ int bch2_journal_meta(struct journal *j)
	return bch2_journal_flush_seq(j, res.seq, TASK_UNINTERRUPTIBLE);
}

int bch2_journal_meta(struct journal *j)
{
	struct bch_fs *c = container_of(j, struct bch_fs, journal);

	if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_journal))
		return -EROFS;

	int ret = __bch2_journal_meta(j);
	bch2_write_ref_put(c, BCH_WRITE_REF_journal);
	return ret;
}

/* block/unlock the journal: */

void bch2_journal_unblock(struct journal *j)
@@ -1193,7 +1200,7 @@ void bch2_fs_journal_stop(struct journal *j)
	 * Always write a new journal entry, to make sure the clock hands are up
	 * to date (and match the superblock)
	 */
	bch2_journal_meta(j);
	__bch2_journal_meta(j);

	journal_quiesce(j);
	cancel_delayed_work_sync(&j->write_work);
+1 −3
Original line number Diff line number Diff line
@@ -910,11 +910,9 @@ int bch2_fs_recovery(struct bch_fs *c)
	set_bit(BCH_FS_accounting_replay_done, &c->flags);

	/* fsync if we fixed errors */
	if (test_bit(BCH_FS_errors_fixed, &c->flags) &&
	    bch2_write_ref_tryget(c, BCH_WRITE_REF_fsync)) {
	if (test_bit(BCH_FS_errors_fixed, &c->flags)) {
		bch2_journal_flush_all_pins(&c->journal);
		bch2_journal_meta(&c->journal);
		bch2_write_ref_put(c, BCH_WRITE_REF_fsync);
	}

	/* If we fixed errors, verify that fs is actually clean now: */