mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 16:44:58 +02:00
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: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
8b22abb4c8
commit
fb8c835b18
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user