Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4246a0b6 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

block: add a bi_error field to struct bio



Currently we have two different ways to signal an I/O error on a BIO:

 (1) by clearing the BIO_UPTODATE flag
 (2) by returning a Linux errno value to the bi_end_io callback

The first one has the drawback of only communicating a single possible
error (-EIO), and the second one has the drawback of not beeing persistent
when bios are queued up, and are not passed along from child to parent
bio in the ever more popular chaining scenario.  Having both mechanisms
available has the additional drawback of utterly confusing driver authors
and introducing bugs where various I/O submitters only deal with one of
them, and the others have to add boilerplate code to deal with both kinds
of error returns.

So add a new bi_error field to store an errno value directly in struct
bio and remove the existing mechanisms to clean all this up.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarHannes Reinecke <hare@suse.de>
Reviewed-by: default avatarNeilBrown <neilb@suse.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 0034af03
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1109,7 +1109,7 @@ it will loop and handle as many sectors (on a bio-segment granularity)
as specified.

Now bh->b_end_io is replaced by bio->bi_end_io, but most of the time the
right thing to use is bio_endio(bio, uptodate) instead.
right thing to use is bio_endio(bio) instead.

If the driver is dropping the io_request_lock from its request_fn strategy,
then it just needs to replace that with q->queue_lock instead.
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
				bvec_to_phys(&bvec));
		sec += len;
	}
	bio_endio(bio, 0);
	bio_endio(bio);
}

static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+1 −1
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
		phys_mem += vec.bv_len;
		transfered += vec.bv_len;
	}
	bio_endio(bio, 0);
	bio_endio(bio);
}

/**
+3 −9
Original line number Diff line number Diff line
@@ -101,8 +101,9 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
	spin_unlock(&dev->lock);
}

static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio)
static void simdisk_make_request(struct request_queue *q, struct bio *bio)
{
	struct simdisk *dev = q->queuedata;
	struct bio_vec bvec;
	struct bvec_iter iter;
	sector_t sector = bio->bi_iter.bi_sector;
@@ -116,17 +117,10 @@ static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio)
		sector += len;
		__bio_kunmap_atomic(buffer);
	}
	return 0;
}

static void simdisk_make_request(struct request_queue *q, struct bio *bio)
{
	struct simdisk *dev = q->queuedata;
	int status = simdisk_xfer_bio(dev, bio);
	bio_endio(bio, status);
	bio_endio(bio);
}


static int simdisk_open(struct block_device *bdev, fmode_t mode)
{
	struct simdisk *dev = bdev->bd_disk->private_data;
+5 −6
Original line number Diff line number Diff line
@@ -355,13 +355,12 @@ static void bio_integrity_verify_fn(struct work_struct *work)
		container_of(work, struct bio_integrity_payload, bip_work);
	struct bio *bio = bip->bip_bio;
	struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
	int error;

	error = bio_integrity_process(bio, bi->verify_fn);
	bio->bi_error = bio_integrity_process(bio, bi->verify_fn);

	/* Restore original bio completion handler */
	bio->bi_end_io = bip->bip_end_io;
	bio_endio(bio, error);
	bio_endio(bio);
}

/**
@@ -376,7 +375,7 @@ static void bio_integrity_verify_fn(struct work_struct *work)
 * in process context.	This function postpones completion
 * accordingly.
 */
void bio_integrity_endio(struct bio *bio, int error)
void bio_integrity_endio(struct bio *bio)
{
	struct bio_integrity_payload *bip = bio_integrity(bio);

@@ -386,9 +385,9 @@ void bio_integrity_endio(struct bio *bio, int error)
	 * integrity metadata.  Restore original bio end_io handler
	 * and run it.
	 */
	if (error) {
	if (bio->bi_error) {
		bio->bi_end_io = bip->bip_end_io;
		bio_endio(bio, error);
		bio_endio(bio);

		return;
	}
Loading