mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
bcachefs: Fix refcounting in discard path
bch_dev->io_ref does not protect against the filesystem going away; bch_fs->writes does. Thus the filesystem write ref needs to be the last ref we release. Reported-by: syzbot+9e0404b505e604f67e41@syzkaller.appspotmail.com Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
8ed823b192
commit
0b50b7313e
1 changed files with 6 additions and 6 deletions
|
@ -1874,26 +1874,26 @@ static void bch2_do_discards_work(struct work_struct *work)
|
||||||
trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded,
|
trace_discard_buckets(c, s.seen, s.open, s.need_journal_commit, s.discarded,
|
||||||
bch2_err_str(ret));
|
bch2_err_str(ret));
|
||||||
|
|
||||||
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
|
|
||||||
percpu_ref_put(&ca->io_ref);
|
percpu_ref_put(&ca->io_ref);
|
||||||
|
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch2_dev_do_discards(struct bch_dev *ca)
|
void bch2_dev_do_discards(struct bch_dev *ca)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = ca->fs;
|
struct bch_fs *c = ca->fs;
|
||||||
|
|
||||||
if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
|
if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_discard))
|
if (!bch2_dev_get_ioref(c, ca->dev_idx, WRITE))
|
||||||
goto put_ioref;
|
goto put_write_ref;
|
||||||
|
|
||||||
if (queue_work(c->write_ref_wq, &ca->discard_work))
|
if (queue_work(c->write_ref_wq, &ca->discard_work))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
|
|
||||||
put_ioref:
|
|
||||||
percpu_ref_put(&ca->io_ref);
|
percpu_ref_put(&ca->io_ref);
|
||||||
|
put_write_ref:
|
||||||
|
bch2_write_ref_put(c, BCH_WRITE_REF_discard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch2_do_discards(struct bch_fs *c)
|
void bch2_do_discards(struct bch_fs *c)
|
||||||
|
|
Loading…
Add table
Reference in a new issue