Skip to content

Commit 4246a0b

Browse files
Christoph Hellwigaxboe
authored andcommitted
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: Christoph Hellwig <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: NeilBrown <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 0034af0 commit 4246a0b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+622
-682
lines changed

Documentation/block/biodoc.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ it will loop and handle as many sectors (on a bio-segment granularity)
11091109
as specified.
11101110

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

11141114
If the driver is dropping the io_request_lock from its request_fn strategy,
11151115
then it just needs to replace that with q->queue_lock instead.

arch/m68k/emu/nfblock.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
7676
bvec_to_phys(&bvec));
7777
sec += len;
7878
}
79-
bio_endio(bio, 0);
79+
bio_endio(bio);
8080
}
8181

8282
static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)

arch/powerpc/sysdev/axonram.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
132132
phys_mem += vec.bv_len;
133133
transfered += vec.bv_len;
134134
}
135-
bio_endio(bio, 0);
135+
bio_endio(bio);
136136
}
137137

138138
/**

arch/xtensa/platforms/iss/simdisk.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,9 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
101101
spin_unlock(&dev->lock);
102102
}
103103

104-
static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio)
104+
static void simdisk_make_request(struct request_queue *q, struct bio *bio)
105105
{
106+
struct simdisk *dev = q->queuedata;
106107
struct bio_vec bvec;
107108
struct bvec_iter iter;
108109
sector_t sector = bio->bi_iter.bi_sector;
@@ -116,17 +117,10 @@ static int simdisk_xfer_bio(struct simdisk *dev, struct bio *bio)
116117
sector += len;
117118
__bio_kunmap_atomic(buffer);
118119
}
119-
return 0;
120-
}
121120

122-
static void simdisk_make_request(struct request_queue *q, struct bio *bio)
123-
{
124-
struct simdisk *dev = q->queuedata;
125-
int status = simdisk_xfer_bio(dev, bio);
126-
bio_endio(bio, status);
121+
bio_endio(bio);
127122
}
128123

129-
130124
static int simdisk_open(struct block_device *bdev, fmode_t mode)
131125
{
132126
struct simdisk *dev = bdev->bd_disk->private_data;

block/bio-integrity.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -355,13 +355,12 @@ static void bio_integrity_verify_fn(struct work_struct *work)
355355
container_of(work, struct bio_integrity_payload, bip_work);
356356
struct bio *bio = bip->bip_bio;
357357
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
358-
int error;
359358

360-
error = bio_integrity_process(bio, bi->verify_fn);
359+
bio->bi_error = bio_integrity_process(bio, bi->verify_fn);
361360

362361
/* Restore original bio completion handler */
363362
bio->bi_end_io = bip->bip_end_io;
364-
bio_endio(bio, error);
363+
bio_endio(bio);
365364
}
366365

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

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

393392
return;
394393
}

block/bio.c

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ static void bio_free(struct bio *bio)
269269
void bio_init(struct bio *bio)
270270
{
271271
memset(bio, 0, sizeof(*bio));
272-
bio->bi_flags = 1 << BIO_UPTODATE;
273272
atomic_set(&bio->__bi_remaining, 1);
274273
atomic_set(&bio->__bi_cnt, 1);
275274
}
@@ -292,14 +291,17 @@ void bio_reset(struct bio *bio)
292291
__bio_free(bio);
293292

294293
memset(bio, 0, BIO_RESET_BYTES);
295-
bio->bi_flags = flags | (1 << BIO_UPTODATE);
294+
bio->bi_flags = flags;
296295
atomic_set(&bio->__bi_remaining, 1);
297296
}
298297
EXPORT_SYMBOL(bio_reset);
299298

300-
static void bio_chain_endio(struct bio *bio, int error)
299+
static void bio_chain_endio(struct bio *bio)
301300
{
302-
bio_endio(bio->bi_private, error);
301+
struct bio *parent = bio->bi_private;
302+
303+
parent->bi_error = bio->bi_error;
304+
bio_endio(parent);
303305
bio_put(bio);
304306
}
305307

@@ -896,11 +898,11 @@ struct submit_bio_ret {
896898
int error;
897899
};
898900

899-
static void submit_bio_wait_endio(struct bio *bio, int error)
901+
static void submit_bio_wait_endio(struct bio *bio)
900902
{
901903
struct submit_bio_ret *ret = bio->bi_private;
902904

903-
ret->error = error;
905+
ret->error = bio->bi_error;
904906
complete(&ret->event);
905907
}
906908

@@ -1445,7 +1447,7 @@ void bio_unmap_user(struct bio *bio)
14451447
}
14461448
EXPORT_SYMBOL(bio_unmap_user);
14471449

1448-
static void bio_map_kern_endio(struct bio *bio, int err)
1450+
static void bio_map_kern_endio(struct bio *bio)
14491451
{
14501452
bio_put(bio);
14511453
}
@@ -1501,13 +1503,13 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
15011503
}
15021504
EXPORT_SYMBOL(bio_map_kern);
15031505

1504-
static void bio_copy_kern_endio(struct bio *bio, int err)
1506+
static void bio_copy_kern_endio(struct bio *bio)
15051507
{
15061508
bio_free_pages(bio);
15071509
bio_put(bio);
15081510
}
15091511

1510-
static void bio_copy_kern_endio_read(struct bio *bio, int err)
1512+
static void bio_copy_kern_endio_read(struct bio *bio)
15111513
{
15121514
char *p = bio->bi_private;
15131515
struct bio_vec *bvec;
@@ -1518,7 +1520,7 @@ static void bio_copy_kern_endio_read(struct bio *bio, int err)
15181520
p += bvec->bv_len;
15191521
}
15201522

1521-
bio_copy_kern_endio(bio, err);
1523+
bio_copy_kern_endio(bio);
15221524
}
15231525

15241526
/**
@@ -1778,25 +1780,15 @@ static inline bool bio_remaining_done(struct bio *bio)
17781780
/**
17791781
* bio_endio - end I/O on a bio
17801782
* @bio: bio
1781-
* @error: error, if any
17821783
*
17831784
* Description:
1784-
* bio_endio() will end I/O on the whole bio. bio_endio() is the
1785-
* preferred way to end I/O on a bio, it takes care of clearing
1786-
* BIO_UPTODATE on error. @error is 0 on success, and and one of the
1787-
* established -Exxxx (-EIO, for instance) error values in case
1788-
* something went wrong. No one should call bi_end_io() directly on a
1789-
* bio unless they own it and thus know that it has an end_io
1790-
* function.
1785+
* bio_endio() will end I/O on the whole bio. bio_endio() is the preferred
1786+
* way to end I/O on a bio. No one should call bi_end_io() directly on a
1787+
* bio unless they own it and thus know that it has an end_io function.
17911788
**/
1792-
void bio_endio(struct bio *bio, int error)
1789+
void bio_endio(struct bio *bio)
17931790
{
17941791
while (bio) {
1795-
if (error)
1796-
clear_bit(BIO_UPTODATE, &bio->bi_flags);
1797-
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
1798-
error = -EIO;
1799-
18001792
if (unlikely(!bio_remaining_done(bio)))
18011793
break;
18021794

@@ -1810,11 +1802,12 @@ void bio_endio(struct bio *bio, int error)
18101802
*/
18111803
if (bio->bi_end_io == bio_chain_endio) {
18121804
struct bio *parent = bio->bi_private;
1805+
parent->bi_error = bio->bi_error;
18131806
bio_put(bio);
18141807
bio = parent;
18151808
} else {
18161809
if (bio->bi_end_io)
1817-
bio->bi_end_io(bio, error);
1810+
bio->bi_end_io(bio);
18181811
bio = NULL;
18191812
}
18201813
}

block/blk-core.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
143143
unsigned int nbytes, int error)
144144
{
145145
if (error)
146-
clear_bit(BIO_UPTODATE, &bio->bi_flags);
147-
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
148-
error = -EIO;
146+
bio->bi_error = error;
149147

150148
if (unlikely(rq->cmd_flags & REQ_QUIET))
151149
set_bit(BIO_QUIET, &bio->bi_flags);
@@ -154,7 +152,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
154152

155153
/* don't actually finish bio if it's part of flush sequence */
156154
if (bio->bi_iter.bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
157-
bio_endio(bio, error);
155+
bio_endio(bio);
158156
}
159157

160158
void blk_dump_rq_flags(struct request *rq, char *msg)
@@ -1620,7 +1618,8 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
16201618
blk_queue_bounce(q, &bio);
16211619

16221620
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
1623-
bio_endio(bio, -EIO);
1621+
bio->bi_error = -EIO;
1622+
bio_endio(bio);
16241623
return;
16251624
}
16261625

@@ -1673,7 +1672,8 @@ static void blk_queue_bio(struct request_queue *q, struct bio *bio)
16731672
*/
16741673
req = get_request(q, rw_flags, bio, GFP_NOIO);
16751674
if (IS_ERR(req)) {
1676-
bio_endio(bio, PTR_ERR(req)); /* @q is dead */
1675+
bio->bi_error = PTR_ERR(req);
1676+
bio_endio(bio);
16771677
goto out_unlock;
16781678
}
16791679

@@ -1896,7 +1896,8 @@ generic_make_request_checks(struct bio *bio)
18961896
return true;
18971897

18981898
end_io:
1899-
bio_endio(bio, err);
1899+
bio->bi_error = err;
1900+
bio_endio(bio);
19001901
return false;
19011902
}
19021903

block/blk-lib.c

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@
1111

1212
struct bio_batch {
1313
atomic_t done;
14-
unsigned long flags;
14+
int error;
1515
struct completion *wait;
1616
};
1717

18-
static void bio_batch_end_io(struct bio *bio, int err)
18+
static void bio_batch_end_io(struct bio *bio)
1919
{
2020
struct bio_batch *bb = bio->bi_private;
2121

22-
if (err && (err != -EOPNOTSUPP))
23-
clear_bit(BIO_UPTODATE, &bb->flags);
22+
if (bio->bi_error && bio->bi_error != -EOPNOTSUPP)
23+
bb->error = bio->bi_error;
2424
if (atomic_dec_and_test(&bb->done))
2525
complete(bb->wait);
2626
bio_put(bio);
@@ -78,7 +78,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
7878
}
7979

8080
atomic_set(&bb.done, 1);
81-
bb.flags = 1 << BIO_UPTODATE;
81+
bb.error = 0;
8282
bb.wait = &wait;
8383

8484
blk_start_plug(&plug);
@@ -134,9 +134,8 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
134134
if (!atomic_dec_and_test(&bb.done))
135135
wait_for_completion_io(&wait);
136136

137-
if (!test_bit(BIO_UPTODATE, &bb.flags))
138-
ret = -EIO;
139-
137+
if (bb.error)
138+
return bb.error;
140139
return ret;
141140
}
142141
EXPORT_SYMBOL(blkdev_issue_discard);
@@ -172,7 +171,7 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
172171
return -EOPNOTSUPP;
173172

174173
atomic_set(&bb.done, 1);
175-
bb.flags = 1 << BIO_UPTODATE;
174+
bb.error = 0;
176175
bb.wait = &wait;
177176

178177
while (nr_sects) {
@@ -208,9 +207,8 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
208207
if (!atomic_dec_and_test(&bb.done))
209208
wait_for_completion_io(&wait);
210209

211-
if (!test_bit(BIO_UPTODATE, &bb.flags))
212-
ret = -ENOTSUPP;
213-
210+
if (bb.error)
211+
return bb.error;
214212
return ret;
215213
}
216214
EXPORT_SYMBOL(blkdev_issue_write_same);
@@ -236,7 +234,7 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
236234
DECLARE_COMPLETION_ONSTACK(wait);
237235

238236
atomic_set(&bb.done, 1);
239-
bb.flags = 1 << BIO_UPTODATE;
237+
bb.error = 0;
240238
bb.wait = &wait;
241239

242240
ret = 0;
@@ -270,10 +268,8 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
270268
if (!atomic_dec_and_test(&bb.done))
271269
wait_for_completion_io(&wait);
272270

273-
if (!test_bit(BIO_UPTODATE, &bb.flags))
274-
/* One of bios in the batch was completed with error.*/
275-
ret = -EIO;
276-
271+
if (bb.error)
272+
return bb.error;
277273
return ret;
278274
}
279275

block/blk-map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
103103
* normal IO completion path
104104
*/
105105
bio_get(bio);
106-
bio_endio(bio, 0);
106+
bio_endio(bio);
107107
__blk_rq_unmap_user(bio);
108108
return -EINVAL;
109109
}

block/blk-mq.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,7 +1199,7 @@ static struct request *blk_mq_map_request(struct request_queue *q,
11991199
struct blk_mq_alloc_data alloc_data;
12001200

12011201
if (unlikely(blk_mq_queue_enter(q, GFP_KERNEL))) {
1202-
bio_endio(bio, -EIO);
1202+
bio_io_error(bio);
12031203
return NULL;
12041204
}
12051205

@@ -1283,7 +1283,7 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio)
12831283
blk_queue_bounce(q, &bio);
12841284

12851285
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
1286-
bio_endio(bio, -EIO);
1286+
bio_io_error(bio);
12871287
return;
12881288
}
12891289

@@ -1368,7 +1368,7 @@ static void blk_sq_make_request(struct request_queue *q, struct bio *bio)
13681368
blk_queue_bounce(q, &bio);
13691369

13701370
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
1371-
bio_endio(bio, -EIO);
1371+
bio_io_error(bio);
13721372
return;
13731373
}
13741374

0 commit comments

Comments
 (0)