diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-03-29 23:11:08 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-04-02 10:24:34 -0400 |
commit | dcffc3b1ae3251d796a25c673f614e3099ca83d3 (patch) | |
tree | 7b5a5ada3f5ca8e5bda8ab38a396f2c3730fd792 /fs/bcachefs/btree_io.c | |
parent | f1350c2c74e62afbc77048ed35718f42b3baba91 (diff) |
bcachefs: Split up bch_dev.io_ref
We now have separate per device io_refs for read and write access.
This fixes a device removal bug where the discard workers were still
running while we're removing alloc info for that device.
It's also a bit of hardening; we no longer allow writes to devices that
are read-only.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_io.c')
-rw-r--r-- | fs/bcachefs/btree_io.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/fs/bcachefs/btree_io.c b/fs/bcachefs/btree_io.c index 871f3f46a0c2a..17218699f65d5 100644 --- a/fs/bcachefs/btree_io.c +++ b/fs/bcachefs/btree_io.c @@ -1353,7 +1353,7 @@ start: "btree read error %s for %s", bch2_blk_status_to_str(bio->bi_status), buf.buf); if (rb->have_ioref) - percpu_ref_put(&ca->io_ref); + percpu_ref_put(&ca->io_ref[READ]); rb->have_ioref = false; bch2_mark_io_failure(&failed, &rb->pick, false); @@ -1609,7 +1609,7 @@ static void btree_node_read_all_replicas_endio(struct bio *bio) struct bch_dev *ca = bch2_dev_have_ref(c, rb->pick.ptr.dev); bch2_latency_acct(ca, rb->start_time, READ); - percpu_ref_put(&ca->io_ref); + percpu_ref_put(&ca->io_ref[READ]); } ra->err[rb->idx] = bio->bi_status; @@ -1928,7 +1928,7 @@ err: printbuf_exit(&err); bch2_bkey_buf_exit(&scrub->key, c);; btree_bounce_free(c, c->opts.btree_node_size, scrub->used_mempool, scrub->buf); - percpu_ref_put(&scrub->ca->io_ref); + percpu_ref_put(&scrub->ca->io_ref[READ]); kfree(scrub); bch2_write_ref_put(c, BCH_WRITE_REF_btree_node_scrub); } @@ -1997,7 +1997,7 @@ int bch2_btree_node_scrub(struct btree_trans *trans, return 0; err_free: btree_bounce_free(c, c->opts.btree_node_size, used_mempool, buf); - percpu_ref_put(&ca->io_ref); + percpu_ref_put(&ca->io_ref[READ]); err: bch2_write_ref_put(c, BCH_WRITE_REF_btree_node_scrub); return ret; @@ -2159,8 +2159,12 @@ static void btree_node_write_endio(struct bio *bio) spin_unlock_irqrestore(&c->btree_write_error_lock, flags); } + /* + * XXX: we should be using io_ref[WRITE], but we aren't retrying failed + * btree writes yet (due to device removal/ro): + */ if (wbio->have_ioref) - percpu_ref_put(&ca->io_ref); + percpu_ref_put(&ca->io_ref[READ]); if (parent) { bio_put(bio); |