Instead of setting bio->bi_status to BLK_STS_IOERR and calling
bio_endio(bio), use the shorthand bio_io_error(bio).
Created with Coccinelle using the following semantic patch:
@@
struct bio *bio;
@@
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
block/fops.c | 3 +--
drivers/block/drbd/drbd_int.h | 3 +--
drivers/md/bcache/bcache.h | 3 +--
drivers/md/bcache/request.c | 6 ++----
drivers/md/dm-mpath.c | 3 +--
drivers/md/dm-writecache.c | 3 +--
fs/f2fs/segment.c | 3 +--
7 files changed, 8 insertions(+), 16 deletions(-)
diff --git a/block/fops.c b/block/fops.c
index bb6642b45937..9547f656904d 100644
--- a/block/fops.c
+++ b/block/fops.c
@@ -218,8 +218,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
ret = blkdev_iov_iter_get_pages(bio, iter, bdev);
if (unlikely(ret)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
break;
}
if (iocb->ki_flags & IOCB_NOWAIT) {
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index f6d6276974ee..32639e8ea72a 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -1491,8 +1491,7 @@ static inline void drbd_submit_bio_noacct(struct drbd_device *device,
__release(local);
if (!bio->bi_bdev) {
drbd_err(device, "drbd_submit_bio_noacct: bio->bi_bdev == NULL\n");
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
return;
}
diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
index ec9ff9715081..e0c9d9eef0a0 100644
--- a/drivers/md/bcache/bcache.h
+++ b/drivers/md/bcache/bcache.h
@@ -947,8 +947,7 @@ static inline void closure_bio_submit(struct cache_set *c,
{
closure_get(cl);
if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
return;
}
submit_bio_noacct(bio);
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index 3fa3b13a410f..0f6fa0a2920b 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -1178,8 +1178,7 @@ void cached_dev_submit_bio(struct bio *bio)
if (unlikely((d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags)) ||
dc->io_disable)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
return;
}
@@ -1283,8 +1282,7 @@ void flash_dev_submit_bio(struct bio *bio)
struct bcache_device *d = bio->bi_bdev->bd_disk->private_data;
if (unlikely(d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags))) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
return;
}
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 7cb7bb6233b6..bf4927f58d7f 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -712,8 +712,7 @@ static void process_queued_bios(struct work_struct *work)
r = __multipath_map_bio(m, bio, mpio);
switch (r) {
case DM_MAPIO_KILL:
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
break;
case DM_MAPIO_REQUEUE:
bio->bi_status = BLK_STS_DM_REQUEUE;
diff --git a/drivers/md/dm-writecache.c b/drivers/md/dm-writecache.c
index 98bd945f6da7..78a730a9b1ef 100644
--- a/drivers/md/dm-writecache.c
+++ b/drivers/md/dm-writecache.c
@@ -1876,8 +1876,7 @@ static void __writecache_writeback_pmem(struct dm_writecache *wc, struct writeba
if (WC_MODE_FUA(wc))
bio->bi_opf |= REQ_FUA;
if (writecache_has_error(wc)) {
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
} else if (unlikely(!bio_sectors(bio))) {
bio->bi_status = BLK_STS_OK;
bio_endio(bio);
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 6a97fe76712b..2dac0cbb5540 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -4101,8 +4101,7 @@ int f2fs_inplace_write_data(struct f2fs_io_info *fio)
if (fio->bio && *(fio->bio)) {
struct bio *bio = *(fio->bio);
- bio->bi_status = BLK_STS_IOERR;
- bio_endio(bio);
+ bio_io_error(bio);
*(fio->bio) = NULL;
}
return err;
--
2.52.0
On Wed, Mar 04, 2026 at 08:04:09PM +0800, Andreas Gruenbacher wrote:
> Instead of setting bio->bi_status to BLK_STS_IOERR and calling
> bio_endio(bio), use the shorthand bio_io_error(bio).
>
> Created with Coccinelle using the following semantic patch:
>
> @@
> struct bio *bio;
> @@
> - bio->bi_status = BLK_STS_IOERR;
> - bio_endio(bio);
> + bio_io_error(bio);
>
> Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> ---
> block/fops.c | 3 +--
> drivers/block/drbd/drbd_int.h | 3 +--
> drivers/md/bcache/bcache.h | 3 +--
> drivers/md/bcache/request.c | 6 ++----
> drivers/md/dm-mpath.c | 3 +--
> drivers/md/dm-writecache.c | 3 +--
> fs/f2fs/segment.c | 3 +--
> 7 files changed, 8 insertions(+), 16 deletions(-)
>
[snipped]
>
> diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h
> index ec9ff9715081..e0c9d9eef0a0 100644
> --- a/drivers/md/bcache/bcache.h
> +++ b/drivers/md/bcache/bcache.h
> @@ -947,8 +947,7 @@ static inline void closure_bio_submit(struct cache_set *c,
> {
> closure_get(cl);
> if (unlikely(test_bit(CACHE_SET_IO_DISABLE, &c->flags))) {
> - bio->bi_status = BLK_STS_IOERR;
> - bio_endio(bio);
> + bio_io_error(bio);
> return;
> }
> submit_bio_noacct(bio);
> diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
> index 3fa3b13a410f..0f6fa0a2920b 100644
> --- a/drivers/md/bcache/request.c
> +++ b/drivers/md/bcache/request.c
> @@ -1178,8 +1178,7 @@ void cached_dev_submit_bio(struct bio *bio)
>
> if (unlikely((d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags)) ||
> dc->io_disable)) {
> - bio->bi_status = BLK_STS_IOERR;
> - bio_endio(bio);
> + bio_io_error(bio);
> return;
> }
>
> @@ -1283,8 +1282,7 @@ void flash_dev_submit_bio(struct bio *bio)
> struct bcache_device *d = bio->bi_bdev->bd_disk->private_data;
>
> if (unlikely(d->c && test_bit(CACHE_SET_IO_DISABLE, &d->c->flags))) {
> - bio->bi_status = BLK_STS_IOERR;
> - bio_endio(bio);
> + bio_io_error(bio);
> return;
> }
>
For bcache part, I feel current hard code is explict and clear.
The bio_io_error() wrapper is not so directly understood. This is just
my opinion, not a strong objection.
Thanks.
Coly Li
[snipped]
On Wed, Mar 04, 2026 at 08:04:09PM +0100, Andreas Gruenbacher wrote: > Instead of setting bio->bi_status to BLK_STS_IOERR and calling > bio_endio(bio), use the shorthand bio_io_error(bio). I'm a little torn how good these helpers actually are, as hard coding one specific type of error seems to create weird code and lead to bugs like the xfs one you fixed yesterday. Maybe we just need a bio_endio_status() that allows passing the satatus? Also you really need to send one patch per subsystem.
On Thu, Mar 5, 2026 at 3:14 PM Christoph Hellwig <hch@infradead.org> wrote: > On Wed, Mar 04, 2026 at 08:04:09PM +0100, Andreas Gruenbacher wrote: > > Instead of setting bio->bi_status to BLK_STS_IOERR and calling > > bio_endio(bio), use the shorthand bio_io_error(bio). > > I'm a little torn how good these helpers actually are, as > hard coding one specific type of error seems to create weird > code and lead to bugs like the xfs one you fixed yesterday. > > Maybe we just need a bio_endio_status() that allows passing the > status? I'm not particularly attached to bio_io_error(bio); it's been around forever but it can be confusing. Any thoughts on replacing it with a new bio_endio_status(bio, BLK_STS_IOERR) helper instead of keeping two mechanisms for doing the same thing? > Also you really need to send one patch per subsystem. I'm really trying to avoid that for simple, obviously correct, mechanical changes that can be recreated from scratch any time. Thanks, Andreas
© 2016 - 2026 Red Hat, Inc.