diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2025-02-28 21:59:15 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2025-03-15 04:02:16 +0300 |
commit | 3480aecd5f4d65fffd775929d1de7349fa6b95c1 (patch) | |
tree | 9ae9a5f29178880ab63578b77244d365192615a4 /fs/bcachefs/io_read.c | |
parent | 7bc580816869e31c121eefe26e7eaccd4e3b778b (diff) | |
download | linux-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.c | 9 |
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; |