mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andreas Gruenbacher <agruenba@redhat.com>
To: Christoph Hellwig <hch@infradead.org>,
	Jens Axboe <axboe@kernel.dk>, Chris Mason <clm@fb.com>,
	David Sterba <dsterba@suse.com>,
	Satya Tangirala <satyat@google.com>
Cc: Andreas Gruenbacher <agruenba@redhat.com>,
	linux-block@vger.kernel.org, linux-btrfs@vger.kernel.org,
	linux-raid@vger.kernel.org, dm-devel@lists.linux.dev,
	linux-kernel@vger.kernel.org
Subject: [RFC v2 04/17] bio: add bio_set_status
Date: Sun, 21 Dec 2025 03:52:19 +0100	[thread overview]
Message-ID: <20251221025233.87087-5-agruenba@redhat.com> (raw)
In-Reply-To: <20251221025233.87087-1-agruenba@redhat.com>

Add a bio_set_status(bio, status) helper that sets bio->bi_status to
status if status != BLK_STS_OK.  Replace instances of this pattern in
the code with a call to the new helper.

The WRITE_ONCE() in bio_set_status() ensures that the compiler won't
reorder things in a weird way, but tearing is not an issue because
bi_status is a single-byte field.

Created with Coccinelle using the following semantic patch and option
'--disable-iso unlikely'.

(Coccinelle occasionally likes to add unnecessary curly braces
in if statements; those were removed by hand.)

@@
expression status;
struct bio *bio;
@@
- if (status)
-       bio->bi_status = status;
+ bio_set_status(bio, status);

@@
expression status;
struct bio *bio;
@@
- if (unlikely(status))
-       bio->bi_status = status;
+ if (unlikely(status))
+	bio_set_status(bio, status);

@@
expression status;
struct bio *bio;
@@
if (status) {
<...
-       bio->bi_status = status;
+       bio_set_status(bio, status);
...>
}

@@
expression status;
struct bio *bio;
@@
if (status != BLK_STS_OK) {
<...
-       bio->bi_status = status;
+       bio_set_status(bio, status);
...>
}

@@
expression status;
struct bio *bio;
statement S;
@@
if (status)
-       bio->bi_status = status;
+       bio_set_status(bio, status);
else
	S

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
 block/blk-crypto-fallback.c  |  4 ++--
 block/blk-mq.c               |  4 ++--
 block/t10-pi.c               |  2 +-
 drivers/md/dm-cache-target.c |  3 ++-
 drivers/md/dm.c              |  3 +--
 drivers/nvdimm/pmem.c        |  2 +-
 include/linux/bio.h          | 16 ++++++++++++++++
 7 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
index 86b27f96051a..a9cb5647879c 100644
--- a/block/blk-crypto-fallback.c
+++ b/block/blk-crypto-fallback.c
@@ -292,7 +292,7 @@ static bool blk_crypto_fallback_encrypt_bio(struct bio **bio_ptr)
 	blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile,
 					bc->bc_key, &slot);
 	if (blk_st != BLK_STS_OK) {
-		src_bio->bi_status = blk_st;
+		bio_set_status(src_bio, blk_st);
 		goto out_put_enc_bio;
 	}
 
@@ -395,7 +395,7 @@ static void blk_crypto_fallback_decrypt_bio(struct work_struct *work)
 	blk_st = blk_crypto_get_keyslot(blk_crypto_fallback_profile,
 					bc->bc_key, &slot);
 	if (blk_st != BLK_STS_OK) {
-		bio->bi_status = blk_st;
+		bio_set_status(bio, blk_st);
 		goto out_no_keyslot;
 	}
 
diff --git a/block/blk-mq.c b/block/blk-mq.c
index d626d32f6e57..9d1883d653c4 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -970,7 +970,7 @@ bool blk_update_request(struct request *req, blk_status_t error,
 		unsigned bio_bytes = min(bio->bi_iter.bi_size, nr_bytes);
 
 		if (unlikely(error))
-			bio->bi_status = error;
+			bio_set_status(bio, error);
 
 		if (bio_bytes == bio->bi_iter.bi_size) {
 			req->bio = bio->bi_next;
@@ -3206,7 +3206,7 @@ void blk_mq_submit_bio(struct bio *bio)
 
 	ret = blk_crypto_rq_get_keyslot(rq);
 	if (ret != BLK_STS_OK) {
-		bio->bi_status = ret;
+		bio_set_status(bio, ret);
 		bio_endio(bio);
 		blk_mq_free_request(rq);
 		return;
diff --git a/block/t10-pi.c b/block/t10-pi.c
index 0c4ed9702146..968cf1fe45f0 100644
--- a/block/t10-pi.c
+++ b/block/t10-pi.c
@@ -440,7 +440,7 @@ void blk_integrity_verify_iter(struct bio *bio, struct bvec_iter *saved_iter)
 		kunmap_local(kaddr);
 
 		if (ret) {
-			bio->bi_status = ret;
+			bio_set_status(bio, ret);
 			return;
 		}
 	}
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index a10d75a562db..03816f0dcb58 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -1190,7 +1190,8 @@ static void mg_complete(struct dm_cache_migration *mg, bool success)
 			if (success)
 				force_set_dirty(cache, cblock);
 			else if (mg->k.input)
-				mg->overwrite_bio->bi_status = mg->k.input;
+				bio_set_status(mg->overwrite_bio,
+					       mg->k.input);
 			else
 				mg->overwrite_bio->bi_status = BLK_STS_IOERR;
 			bio_endio(mg->overwrite_bio);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 6c83ab940af7..cbc64377fa96 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -983,8 +983,7 @@ static void __dm_io_complete(struct dm_io *io, bool first_stage)
 		queue_io(md, bio);
 	} else {
 		/* done with normal IO or empty flush */
-		if (io_error)
-			bio->bi_status = io_error;
+		bio_set_status(bio, io_error);
 		bio_endio(bio);
 	}
 }
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 05785ff21a8b..4fdcbe56a3bc 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -222,7 +222,7 @@ static void pmem_submit_bio(struct bio *bio)
 			rc = pmem_do_read(pmem, bvec.bv_page, bvec.bv_offset,
 				iter.bi_sector, bvec.bv_len);
 		if (rc) {
-			bio->bi_status = rc;
+			bio_set_status(bio, rc);
 			break;
 		}
 	}
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 16c1c85613b7..a1324ce61ebd 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -376,6 +376,22 @@ void submit_bio(struct bio *bio);
 
 extern void bio_endio(struct bio *);
 
+/**
+ * bio_set_status - set the status of bio
+ * @bio: bio
+ * @status: a BLK_STS_* status code
+ *
+ * Set the status of @bio to @status unless @status is BLK_STS_OK (0).  In bio
+ * chains, this function may be called repeatedly on the same bio.  In that
+ * case, it can override a previous error, but it will never revert from an
+ * error back to BLK_STS_OK.
+ */
+static inline void bio_set_status(struct bio *bio, blk_status_t status)
+{
+	if (status != BLK_STS_OK)
+		WRITE_ONCE(bio->bi_status, status);
+}
+
 static inline void bio_io_error(struct bio *bio)
 {
 	bio->bi_status = BLK_STS_IOERR;
-- 
2.52.0


  parent reply	other threads:[~2025-12-21  2:53 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-21  2:52 [RFC v2 00/17] bio cleanups Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 01/17] xfs: don't clobber bi_status in xfs_zone_alloc_and_submit Andreas Gruenbacher
2025-12-21 15:39   ` Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 02/17] bio: rename bio_chain arguments Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 03/17] bio: use bio_io_error more often Andreas Gruenbacher
2025-12-21  2:52 ` Andreas Gruenbacher [this message]
2025-12-21  2:52 ` [RFC v2 05/17] bio: use bio_set_status for BLK_STS_* status codes Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 06/17] bio: do not check bio->bi_status before assigning to it Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 07/17] block: consecutive blk_status_t error codes Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 08/17] block: fix blk_status_to_{errno,str} inconsistency Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 09/17] block: turn blk_errors array into a macro Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 10/17] block: optimize blk_status <=> errno conversion Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 11/17] bio: bio_set_status from non-zero errno Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 12/17] bio: do not check bio->bi_status before assigning to it (part 2) Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 13/17] xfs: use bio_set_status in xfs_zone_alloc_and_submit Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 14/17] bio: switch to bio_set_status in submit_bio_noacct Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 15/17] bio: never set bi_status to BLK_STS_OK during completion Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 16/17] bio: never set bi_status to BLK_STS_OK during completion (part 2) Andreas Gruenbacher
2025-12-21  2:52 ` [RFC v2 17/17] bio: add bio_endio_status Andreas Gruenbacher

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20251221025233.87087-5-agruenba@redhat.com \
    --to=agruenba@redhat.com \
    --cc=axboe@kernel.dk \
    --cc=clm@fb.com \
    --cc=dm-devel@lists.linux.dev \
    --cc=dsterba@suse.com \
    --cc=hch@infradead.org \
    --cc=linux-block@vger.kernel.org \
    --cc=linux-btrfs@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=satyat@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®