[RFC 03/12] bio: add bio_set_errno

Andreas Gruenbacher <[email protected]>
Newsgroups gmane.comp.file-systems.btrfs,gmane.linux.block,gmane.linux.raid,gmane.linux.kernel
Message-ID <[email protected]>
Add a bio_set_errno(bio, errno) helper that sets bio->bi_status to
errno_to_blk_status(errno) if errno != 0.  Replace instances of this
pattern in the code with a call to the new helper.

The WRITE_ONCE() in bio_set_errno() ensures that the compiler won't
reorder things in a weird way, but it isn't needed to prevent tearing
because a single-byte field like bi_status cannot tear.

Created with Coccinelle using the following semantic patch:

@@
struct bio *bio;
expression errno;
@@
- if (errno)
-	bio->bi_status = errno_to_blk_status(errno);
+ bio_set_errno(bio, errno);

@@
struct bio *bio;
expression errno;
@@
- if (unlikely(errno))
-	bio->bi_status = errno_to_blk_status(errno);
+ bio_set_errno(bio, errno);

Signed-off-by: Andreas Gruenbacher <[email protected]>
---
 drivers/block/drbd/drbd_req.c | 3 +--
 drivers/nvdimm/pmem.c         | 3 +--
 include/linux/bio.h           | 8 ++++++++
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index d15826f6ee81..bd4bc882cc5a 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -176,8 +176,7 @@ void start_new_tl_epoch(struct drbd_connection *connection)
 void complete_master_bio(struct drbd_device *device,
 		struct bio_and_error *m)
 {
-	if (unlikely(m->error))
-		m->bio->bi_status = errno_to_blk_status(m->error);
+	bio_set_errno(m->bio, m->error);
 	bio_endio(m->bio);
 	dec_ap_bio(device);
 }
diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
index 05785ff21a8b..a2f8b5a85326 100644
--- a/drivers/nvdimm/pmem.c
+++ b/drivers/nvdimm/pmem.c
@@ -232,8 +232,7 @@ static void pmem_submit_bio(struct bio *bio)
 	if (bio->bi_opf & REQ_FUA)
 		ret = nvdimm_flush(nd_region, bio);
 
-	if (ret)
-		bio->bi_status = errno_to_blk_status(ret);
+	bio_set_errno(bio, ret);
 
 	bio_endio(bio);
 }
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 16c1c85613b7..38ebf03036cb 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -389,6 +389,14 @@ static inline void bio_wouldblock_error(struct bio *bio)
 	bio_endio(bio);
 }
 
+blk_status_t errno_to_blk_status(int errno);
+
+static inline void bio_set_errno(struct bio *bio, int errno)
+{
+	if (errno)
+		WRITE_ONCE(bio->bi_status, errno_to_blk_status(errno));
+}
+
 /*
  * Calculate number of bvec segments that should be allocated to fit data
  * pointed by @iter. If @iter is backed by bvec it's going to be reused
-- 
2.51.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.