summaryrefslogtreecommitdiff
path: root/fs/bcachefs/io_read.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2025-02-28 21:59:15 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2025-03-15 04:02:16 +0300
commit3480aecd5f4d65fffd775929d1de7349fa6b95c1 (patch)
tree9ae9a5f29178880ab63578b77244d365192615a4 /fs/bcachefs/io_read.c
parent7bc580816869e31c121eefe26e7eaccd4e3b778b (diff)
downloadlinux-3480aecd5f4d65fffd775929d1de7349fa6b95c1.tar.xz
bcachefs: Fix read path io_ref handling
We were using our device pointer after we'd released our ref to it. Unlikely to be a race that's practical to hit, since actually removing a member device is a whole process besides just taking it offline, but - needs to be fixed. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/io_read.c')
-rw-r--r--fs/bcachefs/io_read.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/fs/bcachefs/io_read.c b/fs/bcachefs/io_read.c
index dcd5a2aee0f1..f97716e52556 100644
--- a/fs/bcachefs/io_read.c
+++ b/fs/bcachefs/io_read.c
@@ -375,6 +375,11 @@ static inline struct bch_read_bio *bch2_rbio_free(struct bch_read_bio *rbio)
{
BUG_ON(rbio->bounce && !rbio->split);
+ if (rbio->have_ioref) {
+ struct bch_dev *ca = bch2_dev_have_ref(rbio->c, rbio->pick.ptr.dev);
+ percpu_ref_put(&ca->io_ref);
+ }
+
if (rbio->split) {
struct bch_read_bio *parent = rbio->parent;
@@ -790,10 +795,8 @@ static void bch2_read_endio(struct bio *bio)
struct workqueue_struct *wq = NULL;
enum rbio_context context = RBIO_CONTEXT_NULL;
- if (rbio->have_ioref) {
+ if (ca)
bch2_latency_acct(ca, rbio->submit_time, READ);
- percpu_ref_put(&ca->io_ref);
- }
if (!rbio->split)
rbio->bio.bi_end_io = rbio->end_io;