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 <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Reviewed-by: NeilBrown <neilb@suse.com> Signed-off-by: Jens Axboe <axboe@fb.com>
This commit is contained in:
Родитель
0034af0365
Коммит
4246a0b63b
|
@ -1109,7 +1109,7 @@ it will loop and handle as many sectors (on a bio-segment granularity)
|
||||||
as specified.
|
as specified.
|
||||||
|
|
||||||
Now bh->b_end_io is replaced by bio->bi_end_io, but most of the time the
|
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,
|
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.
|
then it just needs to replace that with q->queue_lock instead.
|
||||||
|
|
|
@ -76,7 +76,7 @@ static void nfhd_make_request(struct request_queue *queue, struct bio *bio)
|
||||||
bvec_to_phys(&bvec));
|
bvec_to_phys(&bvec));
|
||||||
sec += len;
|
sec += len;
|
||||||
}
|
}
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
static int nfhd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||||
|
|
|
@ -132,7 +132,7 @@ axon_ram_make_request(struct request_queue *queue, struct bio *bio)
|
||||||
phys_mem += vec.bv_len;
|
phys_mem += vec.bv_len;
|
||||||
transfered += vec.bv_len;
|
transfered += vec.bv_len;
|
||||||
}
|
}
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -101,8 +101,9 @@ static void simdisk_transfer(struct simdisk *dev, unsigned long sector,
|
||||||
spin_unlock(&dev->lock);
|
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 bio_vec bvec;
|
||||||
struct bvec_iter iter;
|
struct bvec_iter iter;
|
||||||
sector_t sector = bio->bi_iter.bi_sector;
|
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;
|
sector += len;
|
||||||
__bio_kunmap_atomic(buffer);
|
__bio_kunmap_atomic(buffer);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void simdisk_make_request(struct request_queue *q, struct bio *bio)
|
bio_endio(bio);
|
||||||
{
|
|
||||||
struct simdisk *dev = q->queuedata;
|
|
||||||
int status = simdisk_xfer_bio(dev, bio);
|
|
||||||
bio_endio(bio, status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int simdisk_open(struct block_device *bdev, fmode_t mode)
|
static int simdisk_open(struct block_device *bdev, fmode_t mode)
|
||||||
{
|
{
|
||||||
struct simdisk *dev = bdev->bd_disk->private_data;
|
struct simdisk *dev = bdev->bd_disk->private_data;
|
||||||
|
|
|
@ -355,13 +355,12 @@ static void bio_integrity_verify_fn(struct work_struct *work)
|
||||||
container_of(work, struct bio_integrity_payload, bip_work);
|
container_of(work, struct bio_integrity_payload, bip_work);
|
||||||
struct bio *bio = bip->bip_bio;
|
struct bio *bio = bip->bip_bio;
|
||||||
struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev);
|
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 */
|
/* Restore original bio completion handler */
|
||||||
bio->bi_end_io = bip->bip_end_io;
|
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
|
* in process context. This function postpones completion
|
||||||
* accordingly.
|
* 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);
|
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
|
* integrity metadata. Restore original bio end_io handler
|
||||||
* and run it.
|
* and run it.
|
||||||
*/
|
*/
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
bio->bi_end_io = bip->bip_end_io;
|
bio->bi_end_io = bip->bip_end_io;
|
||||||
bio_endio(bio, error);
|
bio_endio(bio);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
43
block/bio.c
43
block/bio.c
|
@ -269,7 +269,6 @@ static void bio_free(struct bio *bio)
|
||||||
void bio_init(struct bio *bio)
|
void bio_init(struct bio *bio)
|
||||||
{
|
{
|
||||||
memset(bio, 0, sizeof(*bio));
|
memset(bio, 0, sizeof(*bio));
|
||||||
bio->bi_flags = 1 << BIO_UPTODATE;
|
|
||||||
atomic_set(&bio->__bi_remaining, 1);
|
atomic_set(&bio->__bi_remaining, 1);
|
||||||
atomic_set(&bio->__bi_cnt, 1);
|
atomic_set(&bio->__bi_cnt, 1);
|
||||||
}
|
}
|
||||||
|
@ -292,14 +291,17 @@ void bio_reset(struct bio *bio)
|
||||||
__bio_free(bio);
|
__bio_free(bio);
|
||||||
|
|
||||||
memset(bio, 0, BIO_RESET_BYTES);
|
memset(bio, 0, BIO_RESET_BYTES);
|
||||||
bio->bi_flags = flags | (1 << BIO_UPTODATE);
|
bio->bi_flags = flags;
|
||||||
atomic_set(&bio->__bi_remaining, 1);
|
atomic_set(&bio->__bi_remaining, 1);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bio_reset);
|
EXPORT_SYMBOL(bio_reset);
|
||||||
|
|
||||||
static void bio_chain_endio(struct bio *bio, int error)
|
static void bio_chain_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_endio(bio->bi_private, error);
|
struct bio *parent = bio->bi_private;
|
||||||
|
|
||||||
|
parent->bi_error = bio->bi_error;
|
||||||
|
bio_endio(parent);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -896,11 +898,11 @@ struct submit_bio_ret {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void submit_bio_wait_endio(struct bio *bio, int error)
|
static void submit_bio_wait_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct submit_bio_ret *ret = bio->bi_private;
|
struct submit_bio_ret *ret = bio->bi_private;
|
||||||
|
|
||||||
ret->error = error;
|
ret->error = bio->bi_error;
|
||||||
complete(&ret->event);
|
complete(&ret->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,7 +1447,7 @@ void bio_unmap_user(struct bio *bio)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bio_unmap_user);
|
EXPORT_SYMBOL(bio_unmap_user);
|
||||||
|
|
||||||
static void bio_map_kern_endio(struct bio *bio, int err)
|
static void bio_map_kern_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
@ -1501,13 +1503,13 @@ struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bio_map_kern);
|
EXPORT_SYMBOL(bio_map_kern);
|
||||||
|
|
||||||
static void bio_copy_kern_endio(struct bio *bio, int err)
|
static void bio_copy_kern_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_free_pages(bio);
|
bio_free_pages(bio);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bio_copy_kern_endio_read(struct bio *bio, int err)
|
static void bio_copy_kern_endio_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
char *p = bio->bi_private;
|
char *p = bio->bi_private;
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
|
@ -1518,7 +1520,7 @@ static void bio_copy_kern_endio_read(struct bio *bio, int err)
|
||||||
p += bvec->bv_len;
|
p += bvec->bv_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_copy_kern_endio(bio, err);
|
bio_copy_kern_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1778,25 +1780,15 @@ static inline bool bio_remaining_done(struct bio *bio)
|
||||||
/**
|
/**
|
||||||
* bio_endio - end I/O on a bio
|
* bio_endio - end I/O on a bio
|
||||||
* @bio: bio
|
* @bio: bio
|
||||||
* @error: error, if any
|
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* bio_endio() will end I/O on the whole bio. bio_endio() is the
|
* bio_endio() will end I/O on the whole bio. bio_endio() is the preferred
|
||||||
* preferred way to end I/O on a bio, it takes care of clearing
|
* way to end I/O on a bio. No one should call bi_end_io() directly on a
|
||||||
* BIO_UPTODATE on error. @error is 0 on success, and and one of the
|
* bio unless they own it and thus know that it has an end_io function.
|
||||||
* established -Exxxx (-EIO, for instance) error values in case
|
|
||||||
* something went wrong. No one should call bi_end_io() directly on a
|
|
||||||
* bio unless they own it and thus know that it has an end_io
|
|
||||||
* function.
|
|
||||||
**/
|
**/
|
||||||
void bio_endio(struct bio *bio, int error)
|
void bio_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
while (bio) {
|
while (bio) {
|
||||||
if (error)
|
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
|
|
||||||
error = -EIO;
|
|
||||||
|
|
||||||
if (unlikely(!bio_remaining_done(bio)))
|
if (unlikely(!bio_remaining_done(bio)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1810,11 +1802,12 @@ void bio_endio(struct bio *bio, int error)
|
||||||
*/
|
*/
|
||||||
if (bio->bi_end_io == bio_chain_endio) {
|
if (bio->bi_end_io == bio_chain_endio) {
|
||||||
struct bio *parent = bio->bi_private;
|
struct bio *parent = bio->bi_private;
|
||||||
|
parent->bi_error = bio->bi_error;
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
bio = parent;
|
bio = parent;
|
||||||
} else {
|
} else {
|
||||||
if (bio->bi_end_io)
|
if (bio->bi_end_io)
|
||||||
bio->bi_end_io(bio, error);
|
bio->bi_end_io(bio);
|
||||||
bio = NULL;
|
bio = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,9 +143,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
|
||||||
unsigned int nbytes, int error)
|
unsigned int nbytes, int error)
|
||||||
{
|
{
|
||||||
if (error)
|
if (error)
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = error;
|
||||||
else if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
|
|
||||||
error = -EIO;
|
|
||||||
|
|
||||||
if (unlikely(rq->cmd_flags & REQ_QUIET))
|
if (unlikely(rq->cmd_flags & REQ_QUIET))
|
||||||
set_bit(BIO_QUIET, &bio->bi_flags);
|
set_bit(BIO_QUIET, &bio->bi_flags);
|
||||||
|
@ -154,7 +152,7 @@ static void req_bio_endio(struct request *rq, struct bio *bio,
|
||||||
|
|
||||||
/* don't actually finish bio if it's part of flush sequence */
|
/* don't actually finish bio if it's part of flush sequence */
|
||||||
if (bio->bi_iter.bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
|
if (bio->bi_iter.bi_size == 0 && !(rq->cmd_flags & REQ_FLUSH_SEQ))
|
||||||
bio_endio(bio, error);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void blk_dump_rq_flags(struct request *rq, char *msg)
|
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)
|
||||||
blk_queue_bounce(q, &bio);
|
blk_queue_bounce(q, &bio);
|
||||||
|
|
||||||
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
||||||
bio_endio(bio, -EIO);
|
bio->bi_error = -EIO;
|
||||||
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,7 +1672,8 @@ get_rq:
|
||||||
*/
|
*/
|
||||||
req = get_request(q, rw_flags, bio, GFP_NOIO);
|
req = get_request(q, rw_flags, bio, GFP_NOIO);
|
||||||
if (IS_ERR(req)) {
|
if (IS_ERR(req)) {
|
||||||
bio_endio(bio, PTR_ERR(req)); /* @q is dead */
|
bio->bi_error = PTR_ERR(req);
|
||||||
|
bio_endio(bio);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1896,7 +1896,8 @@ generic_make_request_checks(struct bio *bio)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
end_io:
|
end_io:
|
||||||
bio_endio(bio, err);
|
bio->bi_error = err;
|
||||||
|
bio_endio(bio);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,16 @@
|
||||||
|
|
||||||
struct bio_batch {
|
struct bio_batch {
|
||||||
atomic_t done;
|
atomic_t done;
|
||||||
unsigned long flags;
|
int error;
|
||||||
struct completion *wait;
|
struct completion *wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bio_batch_end_io(struct bio *bio, int err)
|
static void bio_batch_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_batch *bb = bio->bi_private;
|
struct bio_batch *bb = bio->bi_private;
|
||||||
|
|
||||||
if (err && (err != -EOPNOTSUPP))
|
if (bio->bi_error && bio->bi_error != -EOPNOTSUPP)
|
||||||
clear_bit(BIO_UPTODATE, &bb->flags);
|
bb->error = bio->bi_error;
|
||||||
if (atomic_dec_and_test(&bb->done))
|
if (atomic_dec_and_test(&bb->done))
|
||||||
complete(bb->wait);
|
complete(bb->wait);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
@ -78,7 +78,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_set(&bb.done, 1);
|
atomic_set(&bb.done, 1);
|
||||||
bb.flags = 1 << BIO_UPTODATE;
|
bb.error = 0;
|
||||||
bb.wait = &wait;
|
bb.wait = &wait;
|
||||||
|
|
||||||
blk_start_plug(&plug);
|
blk_start_plug(&plug);
|
||||||
|
@ -134,9 +134,8 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
||||||
if (!atomic_dec_and_test(&bb.done))
|
if (!atomic_dec_and_test(&bb.done))
|
||||||
wait_for_completion_io(&wait);
|
wait_for_completion_io(&wait);
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bb.flags))
|
if (bb.error)
|
||||||
ret = -EIO;
|
return bb.error;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blkdev_issue_discard);
|
EXPORT_SYMBOL(blkdev_issue_discard);
|
||||||
|
@ -172,7 +171,7 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
atomic_set(&bb.done, 1);
|
atomic_set(&bb.done, 1);
|
||||||
bb.flags = 1 << BIO_UPTODATE;
|
bb.error = 0;
|
||||||
bb.wait = &wait;
|
bb.wait = &wait;
|
||||||
|
|
||||||
while (nr_sects) {
|
while (nr_sects) {
|
||||||
|
@ -208,9 +207,8 @@ int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
|
||||||
if (!atomic_dec_and_test(&bb.done))
|
if (!atomic_dec_and_test(&bb.done))
|
||||||
wait_for_completion_io(&wait);
|
wait_for_completion_io(&wait);
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bb.flags))
|
if (bb.error)
|
||||||
ret = -ENOTSUPP;
|
return bb.error;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(blkdev_issue_write_same);
|
EXPORT_SYMBOL(blkdev_issue_write_same);
|
||||||
|
@ -236,7 +234,7 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||||
DECLARE_COMPLETION_ONSTACK(wait);
|
DECLARE_COMPLETION_ONSTACK(wait);
|
||||||
|
|
||||||
atomic_set(&bb.done, 1);
|
atomic_set(&bb.done, 1);
|
||||||
bb.flags = 1 << BIO_UPTODATE;
|
bb.error = 0;
|
||||||
bb.wait = &wait;
|
bb.wait = &wait;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
@ -270,10 +268,8 @@ static int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
|
||||||
if (!atomic_dec_and_test(&bb.done))
|
if (!atomic_dec_and_test(&bb.done))
|
||||||
wait_for_completion_io(&wait);
|
wait_for_completion_io(&wait);
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bb.flags))
|
if (bb.error)
|
||||||
/* One of bios in the batch was completed with error.*/
|
return bb.error;
|
||||||
ret = -EIO;
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
|
||||||
* normal IO completion path
|
* normal IO completion path
|
||||||
*/
|
*/
|
||||||
bio_get(bio);
|
bio_get(bio);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
__blk_rq_unmap_user(bio);
|
__blk_rq_unmap_user(bio);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1199,7 +1199,7 @@ static struct request *blk_mq_map_request(struct request_queue *q,
|
||||||
struct blk_mq_alloc_data alloc_data;
|
struct blk_mq_alloc_data alloc_data;
|
||||||
|
|
||||||
if (unlikely(blk_mq_queue_enter(q, GFP_KERNEL))) {
|
if (unlikely(blk_mq_queue_enter(q, GFP_KERNEL))) {
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1283,7 +1283,7 @@ static void blk_mq_make_request(struct request_queue *q, struct bio *bio)
|
||||||
blk_queue_bounce(q, &bio);
|
blk_queue_bounce(q, &bio);
|
||||||
|
|
||||||
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1368,7 +1368,7 @@ static void blk_sq_make_request(struct request_queue *q, struct bio *bio)
|
||||||
blk_queue_bounce(q, &bio);
|
blk_queue_bounce(q, &bio);
|
||||||
|
|
||||||
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ static void copy_to_high_bio_irq(struct bio *to, struct bio *from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
|
static void bounce_end_io(struct bio *bio, mempool_t *pool)
|
||||||
{
|
{
|
||||||
struct bio *bio_orig = bio->bi_private;
|
struct bio *bio_orig = bio->bi_private;
|
||||||
struct bio_vec *bvec, *org_vec;
|
struct bio_vec *bvec, *org_vec;
|
||||||
|
@ -141,39 +141,40 @@ static void bounce_end_io(struct bio *bio, mempool_t *pool, int err)
|
||||||
mempool_free(bvec->bv_page, pool);
|
mempool_free(bvec->bv_page, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_endio(bio_orig, err);
|
bio_orig->bi_error = bio->bi_error;
|
||||||
|
bio_endio(bio_orig);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bounce_end_io_write(struct bio *bio, int err)
|
static void bounce_end_io_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
bounce_end_io(bio, page_pool, err);
|
bounce_end_io(bio, page_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bounce_end_io_write_isa(struct bio *bio, int err)
|
static void bounce_end_io_write_isa(struct bio *bio)
|
||||||
{
|
{
|
||||||
|
|
||||||
bounce_end_io(bio, isa_page_pool, err);
|
bounce_end_io(bio, isa_page_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __bounce_end_io_read(struct bio *bio, mempool_t *pool, int err)
|
static void __bounce_end_io_read(struct bio *bio, mempool_t *pool)
|
||||||
{
|
{
|
||||||
struct bio *bio_orig = bio->bi_private;
|
struct bio *bio_orig = bio->bi_private;
|
||||||
|
|
||||||
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
|
if (!bio->bi_error)
|
||||||
copy_to_high_bio_irq(bio_orig, bio);
|
copy_to_high_bio_irq(bio_orig, bio);
|
||||||
|
|
||||||
bounce_end_io(bio, pool, err);
|
bounce_end_io(bio, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bounce_end_io_read(struct bio *bio, int err)
|
static void bounce_end_io_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
__bounce_end_io_read(bio, page_pool, err);
|
__bounce_end_io_read(bio, page_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bounce_end_io_read_isa(struct bio *bio, int err)
|
static void bounce_end_io_read_isa(struct bio *bio)
|
||||||
{
|
{
|
||||||
__bounce_end_io_read(bio, isa_page_pool, err);
|
__bounce_end_io_read(bio, isa_page_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_NEED_BOUNCE_POOL
|
#ifdef CONFIG_NEED_BOUNCE_POOL
|
||||||
|
|
|
@ -1110,7 +1110,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
|
||||||
d->ip.rq = NULL;
|
d->ip.rq = NULL;
|
||||||
do {
|
do {
|
||||||
bio = rq->bio;
|
bio = rq->bio;
|
||||||
bok = !fastfail && test_bit(BIO_UPTODATE, &bio->bi_flags);
|
bok = !fastfail && !bio->bi_error;
|
||||||
} while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_iter.bi_size));
|
} while (__blk_end_request(rq, bok ? 0 : -EIO, bio->bi_iter.bi_size));
|
||||||
|
|
||||||
/* cf. http://lkml.org/lkml/2006/10/31/28 */
|
/* cf. http://lkml.org/lkml/2006/10/31/28 */
|
||||||
|
@ -1172,7 +1172,7 @@ ktiocomplete(struct frame *f)
|
||||||
ahout->cmdstat, ahin->cmdstat,
|
ahout->cmdstat, ahin->cmdstat,
|
||||||
d->aoemajor, d->aoeminor);
|
d->aoemajor, d->aoeminor);
|
||||||
noskb: if (buf)
|
noskb: if (buf)
|
||||||
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
|
buf->bio->bi_error = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1185,7 +1185,7 @@ noskb: if (buf)
|
||||||
"aoe: runt data size in read from",
|
"aoe: runt data size in read from",
|
||||||
(long) d->aoemajor, d->aoeminor,
|
(long) d->aoemajor, d->aoeminor,
|
||||||
skb->len, n);
|
skb->len, n);
|
||||||
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
|
buf->bio->bi_error = -EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (n > f->iter.bi_size) {
|
if (n > f->iter.bi_size) {
|
||||||
|
@ -1193,7 +1193,7 @@ noskb: if (buf)
|
||||||
"aoe: too-large data size in read from",
|
"aoe: too-large data size in read from",
|
||||||
(long) d->aoemajor, d->aoeminor,
|
(long) d->aoemajor, d->aoeminor,
|
||||||
n, f->iter.bi_size);
|
n, f->iter.bi_size);
|
||||||
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
|
buf->bio->bi_error = -EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bvcpy(skb, f->buf->bio, f->iter, n);
|
bvcpy(skb, f->buf->bio, f->iter, n);
|
||||||
|
@ -1695,7 +1695,7 @@ aoe_failbuf(struct aoedev *d, struct buf *buf)
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return;
|
return;
|
||||||
buf->iter.bi_size = 0;
|
buf->iter.bi_size = 0;
|
||||||
clear_bit(BIO_UPTODATE, &buf->bio->bi_flags);
|
buf->bio->bi_error = -EIO;
|
||||||
if (buf->nframesout == 0)
|
if (buf->nframesout == 0)
|
||||||
aoe_end_buf(d, buf);
|
aoe_end_buf(d, buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ aoe_failip(struct aoedev *d)
|
||||||
if (rq == NULL)
|
if (rq == NULL)
|
||||||
return;
|
return;
|
||||||
while ((bio = d->ip.nxbio)) {
|
while ((bio = d->ip.nxbio)) {
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
d->ip.nxbio = bio->bi_next;
|
d->ip.nxbio = bio->bi_next;
|
||||||
n = (unsigned long) rq->special;
|
n = (unsigned long) rq->special;
|
||||||
rq->special = (void *) --n;
|
rq->special = (void *) --n;
|
||||||
|
|
|
@ -331,14 +331,12 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
|
||||||
struct bio_vec bvec;
|
struct bio_vec bvec;
|
||||||
sector_t sector;
|
sector_t sector;
|
||||||
struct bvec_iter iter;
|
struct bvec_iter iter;
|
||||||
int err = -EIO;
|
|
||||||
|
|
||||||
sector = bio->bi_iter.bi_sector;
|
sector = bio->bi_iter.bi_sector;
|
||||||
if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
|
if (bio_end_sector(bio) > get_capacity(bdev->bd_disk))
|
||||||
goto out;
|
goto io_error;
|
||||||
|
|
||||||
if (unlikely(bio->bi_rw & REQ_DISCARD)) {
|
if (unlikely(bio->bi_rw & REQ_DISCARD)) {
|
||||||
err = 0;
|
|
||||||
discard_from_brd(brd, sector, bio->bi_iter.bi_size);
|
discard_from_brd(brd, sector, bio->bi_iter.bi_size);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -349,15 +347,20 @@ static void brd_make_request(struct request_queue *q, struct bio *bio)
|
||||||
|
|
||||||
bio_for_each_segment(bvec, bio, iter) {
|
bio_for_each_segment(bvec, bio, iter) {
|
||||||
unsigned int len = bvec.bv_len;
|
unsigned int len = bvec.bv_len;
|
||||||
|
int err;
|
||||||
|
|
||||||
err = brd_do_bvec(brd, bvec.bv_page, len,
|
err = brd_do_bvec(brd, bvec.bv_page, len,
|
||||||
bvec.bv_offset, rw, sector);
|
bvec.bv_offset, rw, sector);
|
||||||
if (err)
|
if (err)
|
||||||
break;
|
goto io_error;
|
||||||
sector += len >> SECTOR_SHIFT;
|
sector += len >> SECTOR_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bio_endio(bio, err);
|
bio_endio(bio);
|
||||||
|
return;
|
||||||
|
io_error:
|
||||||
|
bio_io_error(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int brd_rw_page(struct block_device *bdev, sector_t sector,
|
static int brd_rw_page(struct block_device *bdev, sector_t sector,
|
||||||
|
|
|
@ -175,11 +175,11 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
|
||||||
atomic_inc(&device->md_io.in_use); /* drbd_md_put_buffer() is in the completion handler */
|
atomic_inc(&device->md_io.in_use); /* drbd_md_put_buffer() is in the completion handler */
|
||||||
device->md_io.submit_jif = jiffies;
|
device->md_io.submit_jif = jiffies;
|
||||||
if (drbd_insert_fault(device, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
|
if (drbd_insert_fault(device, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD))
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
else
|
else
|
||||||
submit_bio(rw, bio);
|
submit_bio(rw, bio);
|
||||||
wait_until_done_or_force_detached(device, bdev, &device->md_io.done);
|
wait_until_done_or_force_detached(device, bdev, &device->md_io.done);
|
||||||
if (bio_flagged(bio, BIO_UPTODATE))
|
if (!bio->bi_error)
|
||||||
err = device->md_io.error;
|
err = device->md_io.error;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -941,36 +941,27 @@ static void drbd_bm_aio_ctx_destroy(struct kref *kref)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bv_page may be a copy, or may be the original */
|
/* bv_page may be a copy, or may be the original */
|
||||||
static void drbd_bm_endio(struct bio *bio, int error)
|
static void drbd_bm_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct drbd_bm_aio_ctx *ctx = bio->bi_private;
|
struct drbd_bm_aio_ctx *ctx = bio->bi_private;
|
||||||
struct drbd_device *device = ctx->device;
|
struct drbd_device *device = ctx->device;
|
||||||
struct drbd_bitmap *b = device->bitmap;
|
struct drbd_bitmap *b = device->bitmap;
|
||||||
unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page);
|
unsigned int idx = bm_page_to_idx(bio->bi_io_vec[0].bv_page);
|
||||||
int uptodate = bio_flagged(bio, BIO_UPTODATE);
|
|
||||||
|
|
||||||
|
|
||||||
/* strange behavior of some lower level drivers...
|
|
||||||
* fail the request by clearing the uptodate flag,
|
|
||||||
* but do not return any error?!
|
|
||||||
* do we want to WARN() on this? */
|
|
||||||
if (!error && !uptodate)
|
|
||||||
error = -EIO;
|
|
||||||
|
|
||||||
if ((ctx->flags & BM_AIO_COPY_PAGES) == 0 &&
|
if ((ctx->flags & BM_AIO_COPY_PAGES) == 0 &&
|
||||||
!bm_test_page_unchanged(b->bm_pages[idx]))
|
!bm_test_page_unchanged(b->bm_pages[idx]))
|
||||||
drbd_warn(device, "bitmap page idx %u changed during IO!\n", idx);
|
drbd_warn(device, "bitmap page idx %u changed during IO!\n", idx);
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
/* ctx error will hold the completed-last non-zero error code,
|
/* ctx error will hold the completed-last non-zero error code,
|
||||||
* in case error codes differ. */
|
* in case error codes differ. */
|
||||||
ctx->error = error;
|
ctx->error = bio->bi_error;
|
||||||
bm_set_page_io_err(b->bm_pages[idx]);
|
bm_set_page_io_err(b->bm_pages[idx]);
|
||||||
/* Not identical to on disk version of it.
|
/* Not identical to on disk version of it.
|
||||||
* Is BM_PAGE_IO_ERROR enough? */
|
* Is BM_PAGE_IO_ERROR enough? */
|
||||||
if (__ratelimit(&drbd_ratelimit_state))
|
if (__ratelimit(&drbd_ratelimit_state))
|
||||||
drbd_err(device, "IO ERROR %d on bitmap page idx %u\n",
|
drbd_err(device, "IO ERROR %d on bitmap page idx %u\n",
|
||||||
error, idx);
|
bio->bi_error, idx);
|
||||||
} else {
|
} else {
|
||||||
bm_clear_page_io_err(b->bm_pages[idx]);
|
bm_clear_page_io_err(b->bm_pages[idx]);
|
||||||
dynamic_drbd_dbg(device, "bitmap page idx %u completed\n", idx);
|
dynamic_drbd_dbg(device, "bitmap page idx %u completed\n", idx);
|
||||||
|
@ -1031,7 +1022,7 @@ static void bm_page_io_async(struct drbd_bm_aio_ctx *ctx, int page_nr) __must_ho
|
||||||
|
|
||||||
if (drbd_insert_fault(device, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
|
if (drbd_insert_fault(device, (rw & WRITE) ? DRBD_FAULT_MD_WR : DRBD_FAULT_MD_RD)) {
|
||||||
bio->bi_rw |= rw;
|
bio->bi_rw |= rw;
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
} else {
|
} else {
|
||||||
submit_bio(rw, bio);
|
submit_bio(rw, bio);
|
||||||
/* this should not count as user activity and cause the
|
/* this should not count as user activity and cause the
|
||||||
|
|
|
@ -1481,9 +1481,9 @@ extern int drbd_khelper(struct drbd_device *device, char *cmd);
|
||||||
|
|
||||||
/* drbd_worker.c */
|
/* drbd_worker.c */
|
||||||
/* bi_end_io handlers */
|
/* bi_end_io handlers */
|
||||||
extern void drbd_md_endio(struct bio *bio, int error);
|
extern void drbd_md_endio(struct bio *bio);
|
||||||
extern void drbd_peer_request_endio(struct bio *bio, int error);
|
extern void drbd_peer_request_endio(struct bio *bio);
|
||||||
extern void drbd_request_endio(struct bio *bio, int error);
|
extern void drbd_request_endio(struct bio *bio);
|
||||||
extern int drbd_worker(struct drbd_thread *thi);
|
extern int drbd_worker(struct drbd_thread *thi);
|
||||||
enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
|
enum drbd_ret_code drbd_resync_after_valid(struct drbd_device *device, int o_minor);
|
||||||
void drbd_resync_after_changed(struct drbd_device *device);
|
void drbd_resync_after_changed(struct drbd_device *device);
|
||||||
|
@ -1604,12 +1604,13 @@ static inline void drbd_generic_make_request(struct drbd_device *device,
|
||||||
__release(local);
|
__release(local);
|
||||||
if (!bio->bi_bdev) {
|
if (!bio->bi_bdev) {
|
||||||
drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n");
|
drbd_err(device, "drbd_generic_make_request: bio->bi_bdev == NULL\n");
|
||||||
bio_endio(bio, -ENODEV);
|
bio->bi_error = -ENODEV;
|
||||||
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drbd_insert_fault(device, fault_type))
|
if (drbd_insert_fault(device, fault_type))
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,8 @@ void start_new_tl_epoch(struct drbd_connection *connection)
|
||||||
void complete_master_bio(struct drbd_device *device,
|
void complete_master_bio(struct drbd_device *device,
|
||||||
struct bio_and_error *m)
|
struct bio_and_error *m)
|
||||||
{
|
{
|
||||||
bio_endio(m->bio, m->error);
|
m->bio->bi_error = m->error;
|
||||||
|
bio_endio(m->bio);
|
||||||
dec_ap_bio(device);
|
dec_ap_bio(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1153,12 +1154,12 @@ drbd_submit_req_private_bio(struct drbd_request *req)
|
||||||
rw == WRITE ? DRBD_FAULT_DT_WR
|
rw == WRITE ? DRBD_FAULT_DT_WR
|
||||||
: rw == READ ? DRBD_FAULT_DT_RD
|
: rw == READ ? DRBD_FAULT_DT_RD
|
||||||
: DRBD_FAULT_DT_RA))
|
: DRBD_FAULT_DT_RA))
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
put_ldev(device);
|
put_ldev(device);
|
||||||
} else
|
} else
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drbd_queue_write(struct drbd_device *device, struct drbd_request *req)
|
static void drbd_queue_write(struct drbd_device *device, struct drbd_request *req)
|
||||||
|
@ -1191,7 +1192,8 @@ drbd_request_prepare(struct drbd_device *device, struct bio *bio, unsigned long
|
||||||
/* only pass the error to the upper layers.
|
/* only pass the error to the upper layers.
|
||||||
* if user cannot handle io errors, that's not our business. */
|
* if user cannot handle io errors, that's not our business. */
|
||||||
drbd_err(device, "could not kmalloc() req\n");
|
drbd_err(device, "could not kmalloc() req\n");
|
||||||
bio_endio(bio, -ENOMEM);
|
bio->bi_error = -ENOMEM;
|
||||||
|
bio_endio(bio);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
req->start_jif = start_jif;
|
req->start_jif = start_jif;
|
||||||
|
|
|
@ -65,12 +65,12 @@ rwlock_t global_state_lock;
|
||||||
/* used for synchronous meta data and bitmap IO
|
/* used for synchronous meta data and bitmap IO
|
||||||
* submitted by drbd_md_sync_page_io()
|
* submitted by drbd_md_sync_page_io()
|
||||||
*/
|
*/
|
||||||
void drbd_md_endio(struct bio *bio, int error)
|
void drbd_md_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct drbd_device *device;
|
struct drbd_device *device;
|
||||||
|
|
||||||
device = bio->bi_private;
|
device = bio->bi_private;
|
||||||
device->md_io.error = error;
|
device->md_io.error = bio->bi_error;
|
||||||
|
|
||||||
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
|
/* We grabbed an extra reference in _drbd_md_sync_page_io() to be able
|
||||||
* to timeout on the lower level device, and eventually detach from it.
|
* to timeout on the lower level device, and eventually detach from it.
|
||||||
|
@ -170,31 +170,20 @@ void drbd_endio_write_sec_final(struct drbd_peer_request *peer_req) __releases(l
|
||||||
/* writes on behalf of the partner, or resync writes,
|
/* writes on behalf of the partner, or resync writes,
|
||||||
* "submitted" by the receiver.
|
* "submitted" by the receiver.
|
||||||
*/
|
*/
|
||||||
void drbd_peer_request_endio(struct bio *bio, int error)
|
void drbd_peer_request_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct drbd_peer_request *peer_req = bio->bi_private;
|
struct drbd_peer_request *peer_req = bio->bi_private;
|
||||||
struct drbd_device *device = peer_req->peer_device->device;
|
struct drbd_device *device = peer_req->peer_device->device;
|
||||||
int uptodate = bio_flagged(bio, BIO_UPTODATE);
|
|
||||||
int is_write = bio_data_dir(bio) == WRITE;
|
int is_write = bio_data_dir(bio) == WRITE;
|
||||||
int is_discard = !!(bio->bi_rw & REQ_DISCARD);
|
int is_discard = !!(bio->bi_rw & REQ_DISCARD);
|
||||||
|
|
||||||
if (error && __ratelimit(&drbd_ratelimit_state))
|
if (bio->bi_error && __ratelimit(&drbd_ratelimit_state))
|
||||||
drbd_warn(device, "%s: error=%d s=%llus\n",
|
drbd_warn(device, "%s: error=%d s=%llus\n",
|
||||||
is_write ? (is_discard ? "discard" : "write")
|
is_write ? (is_discard ? "discard" : "write")
|
||||||
: "read", error,
|
: "read", bio->bi_error,
|
||||||
(unsigned long long)peer_req->i.sector);
|
(unsigned long long)peer_req->i.sector);
|
||||||
if (!error && !uptodate) {
|
|
||||||
if (__ratelimit(&drbd_ratelimit_state))
|
|
||||||
drbd_warn(device, "%s: setting error to -EIO s=%llus\n",
|
|
||||||
is_write ? "write" : "read",
|
|
||||||
(unsigned long long)peer_req->i.sector);
|
|
||||||
/* strange behavior of some lower level drivers...
|
|
||||||
* fail the request by clearing the uptodate flag,
|
|
||||||
* but do not return any error?! */
|
|
||||||
error = -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
set_bit(__EE_WAS_ERROR, &peer_req->flags);
|
set_bit(__EE_WAS_ERROR, &peer_req->flags);
|
||||||
|
|
||||||
bio_put(bio); /* no need for the bio anymore */
|
bio_put(bio); /* no need for the bio anymore */
|
||||||
|
@ -208,24 +197,13 @@ void drbd_peer_request_endio(struct bio *bio, int error)
|
||||||
|
|
||||||
/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
|
/* read, readA or write requests on R_PRIMARY coming from drbd_make_request
|
||||||
*/
|
*/
|
||||||
void drbd_request_endio(struct bio *bio, int error)
|
void drbd_request_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct drbd_request *req = bio->bi_private;
|
struct drbd_request *req = bio->bi_private;
|
||||||
struct drbd_device *device = req->device;
|
struct drbd_device *device = req->device;
|
||||||
struct bio_and_error m;
|
struct bio_and_error m;
|
||||||
enum drbd_req_event what;
|
enum drbd_req_event what;
|
||||||
int uptodate = bio_flagged(bio, BIO_UPTODATE);
|
|
||||||
|
|
||||||
if (!error && !uptodate) {
|
|
||||||
drbd_warn(device, "p %s: setting error to -EIO\n",
|
|
||||||
bio_data_dir(bio) == WRITE ? "write" : "read");
|
|
||||||
/* strange behavior of some lower level drivers...
|
|
||||||
* fail the request by clearing the uptodate flag,
|
|
||||||
* but do not return any error?! */
|
|
||||||
error = -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If this request was aborted locally before,
|
/* If this request was aborted locally before,
|
||||||
* but now was completed "successfully",
|
* but now was completed "successfully",
|
||||||
|
@ -259,14 +237,14 @@ void drbd_request_endio(struct bio *bio, int error)
|
||||||
if (__ratelimit(&drbd_ratelimit_state))
|
if (__ratelimit(&drbd_ratelimit_state))
|
||||||
drbd_emerg(device, "delayed completion of aborted local request; disk-timeout may be too aggressive\n");
|
drbd_emerg(device, "delayed completion of aborted local request; disk-timeout may be too aggressive\n");
|
||||||
|
|
||||||
if (!error)
|
if (!bio->bi_error)
|
||||||
panic("possible random memory corruption caused by delayed completion of aborted local request\n");
|
panic("possible random memory corruption caused by delayed completion of aborted local request\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* to avoid recursion in __req_mod */
|
/* to avoid recursion in __req_mod */
|
||||||
if (unlikely(error)) {
|
if (unlikely(bio->bi_error)) {
|
||||||
if (bio->bi_rw & REQ_DISCARD)
|
if (bio->bi_rw & REQ_DISCARD)
|
||||||
what = (error == -EOPNOTSUPP)
|
what = (bio->bi_error == -EOPNOTSUPP)
|
||||||
? DISCARD_COMPLETED_NOTSUPP
|
? DISCARD_COMPLETED_NOTSUPP
|
||||||
: DISCARD_COMPLETED_WITH_ERROR;
|
: DISCARD_COMPLETED_WITH_ERROR;
|
||||||
else
|
else
|
||||||
|
@ -279,7 +257,7 @@ void drbd_request_endio(struct bio *bio, int error)
|
||||||
what = COMPLETED_OK;
|
what = COMPLETED_OK;
|
||||||
|
|
||||||
bio_put(req->private_bio);
|
bio_put(req->private_bio);
|
||||||
req->private_bio = ERR_PTR(error);
|
req->private_bio = ERR_PTR(bio->bi_error);
|
||||||
|
|
||||||
/* not req_mod(), we need irqsave here! */
|
/* not req_mod(), we need irqsave here! */
|
||||||
spin_lock_irqsave(&device->resource->req_lock, flags);
|
spin_lock_irqsave(&device->resource->req_lock, flags);
|
||||||
|
|
|
@ -3771,13 +3771,14 @@ struct rb0_cbdata {
|
||||||
struct completion complete;
|
struct completion complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void floppy_rb0_cb(struct bio *bio, int err)
|
static void floppy_rb0_cb(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;
|
struct rb0_cbdata *cbdata = (struct rb0_cbdata *)bio->bi_private;
|
||||||
int drive = cbdata->drive;
|
int drive = cbdata->drive;
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
pr_info("floppy: error %d while reading block 0\n", err);
|
pr_info("floppy: error %d while reading block 0\n",
|
||||||
|
bio->bi_error);
|
||||||
set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
|
set_bit(FD_OPEN_SHOULD_FAIL_BIT, &UDRS->flags);
|
||||||
}
|
}
|
||||||
complete(&cbdata->complete);
|
complete(&cbdata->complete);
|
||||||
|
|
|
@ -222,7 +222,7 @@ static void end_cmd(struct nullb_cmd *cmd)
|
||||||
blk_end_request_all(cmd->rq, 0);
|
blk_end_request_all(cmd->rq, 0);
|
||||||
break;
|
break;
|
||||||
case NULL_Q_BIO:
|
case NULL_Q_BIO:
|
||||||
bio_endio(cmd->bio, 0);
|
bio_endio(cmd->bio);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -977,7 +977,7 @@ static void pkt_make_local_copy(struct packet_data *pkt, struct bio_vec *bvec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkt_end_io_read(struct bio *bio, int err)
|
static void pkt_end_io_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct packet_data *pkt = bio->bi_private;
|
struct packet_data *pkt = bio->bi_private;
|
||||||
struct pktcdvd_device *pd = pkt->pd;
|
struct pktcdvd_device *pd = pkt->pd;
|
||||||
|
@ -985,9 +985,9 @@ static void pkt_end_io_read(struct bio *bio, int err)
|
||||||
|
|
||||||
pkt_dbg(2, pd, "bio=%p sec0=%llx sec=%llx err=%d\n",
|
pkt_dbg(2, pd, "bio=%p sec0=%llx sec=%llx err=%d\n",
|
||||||
bio, (unsigned long long)pkt->sector,
|
bio, (unsigned long long)pkt->sector,
|
||||||
(unsigned long long)bio->bi_iter.bi_sector, err);
|
(unsigned long long)bio->bi_iter.bi_sector, bio->bi_error);
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
atomic_inc(&pkt->io_errors);
|
atomic_inc(&pkt->io_errors);
|
||||||
if (atomic_dec_and_test(&pkt->io_wait)) {
|
if (atomic_dec_and_test(&pkt->io_wait)) {
|
||||||
atomic_inc(&pkt->run_sm);
|
atomic_inc(&pkt->run_sm);
|
||||||
|
@ -996,13 +996,13 @@ static void pkt_end_io_read(struct bio *bio, int err)
|
||||||
pkt_bio_finished(pd);
|
pkt_bio_finished(pd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkt_end_io_packet_write(struct bio *bio, int err)
|
static void pkt_end_io_packet_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct packet_data *pkt = bio->bi_private;
|
struct packet_data *pkt = bio->bi_private;
|
||||||
struct pktcdvd_device *pd = pkt->pd;
|
struct pktcdvd_device *pd = pkt->pd;
|
||||||
BUG_ON(!pd);
|
BUG_ON(!pd);
|
||||||
|
|
||||||
pkt_dbg(2, pd, "id=%d, err=%d\n", pkt->id, err);
|
pkt_dbg(2, pd, "id=%d, err=%d\n", pkt->id, bio->bi_error);
|
||||||
|
|
||||||
pd->stats.pkt_ended++;
|
pd->stats.pkt_ended++;
|
||||||
|
|
||||||
|
@ -1340,22 +1340,22 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||||
pkt_queue_bio(pd, pkt->w_bio);
|
pkt_queue_bio(pd, pkt->w_bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkt_finish_packet(struct packet_data *pkt, int uptodate)
|
static void pkt_finish_packet(struct packet_data *pkt, int error)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
|
|
||||||
if (!uptodate)
|
if (error)
|
||||||
pkt->cache_valid = 0;
|
pkt->cache_valid = 0;
|
||||||
|
|
||||||
/* Finish all bios corresponding to this packet */
|
/* Finish all bios corresponding to this packet */
|
||||||
while ((bio = bio_list_pop(&pkt->orig_bios)))
|
while ((bio = bio_list_pop(&pkt->orig_bios))) {
|
||||||
bio_endio(bio, uptodate ? 0 : -EIO);
|
bio->bi_error = error;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt)
|
static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data *pkt)
|
||||||
{
|
{
|
||||||
int uptodate;
|
|
||||||
|
|
||||||
pkt_dbg(2, pd, "pkt %d\n", pkt->id);
|
pkt_dbg(2, pd, "pkt %d\n", pkt->id);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
@ -1384,7 +1384,7 @@ static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data
|
||||||
if (atomic_read(&pkt->io_wait) > 0)
|
if (atomic_read(&pkt->io_wait) > 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (test_bit(BIO_UPTODATE, &pkt->w_bio->bi_flags)) {
|
if (!pkt->w_bio->bi_error) {
|
||||||
pkt_set_state(pkt, PACKET_FINISHED_STATE);
|
pkt_set_state(pkt, PACKET_FINISHED_STATE);
|
||||||
} else {
|
} else {
|
||||||
pkt_set_state(pkt, PACKET_RECOVERY_STATE);
|
pkt_set_state(pkt, PACKET_RECOVERY_STATE);
|
||||||
|
@ -1401,8 +1401,7 @@ static void pkt_run_state_machine(struct pktcdvd_device *pd, struct packet_data
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_FINISHED_STATE:
|
case PACKET_FINISHED_STATE:
|
||||||
uptodate = test_bit(BIO_UPTODATE, &pkt->w_bio->bi_flags);
|
pkt_finish_packet(pkt, pkt->w_bio->bi_error);
|
||||||
pkt_finish_packet(pkt, uptodate);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2332,13 +2331,14 @@ static void pkt_close(struct gendisk *disk, fmode_t mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pkt_end_io_read_cloned(struct bio *bio, int err)
|
static void pkt_end_io_read_cloned(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct packet_stacked_data *psd = bio->bi_private;
|
struct packet_stacked_data *psd = bio->bi_private;
|
||||||
struct pktcdvd_device *pd = psd->pd;
|
struct pktcdvd_device *pd = psd->pd;
|
||||||
|
|
||||||
|
psd->bio->bi_error = bio->bi_error;
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
bio_endio(psd->bio, err);
|
bio_endio(psd->bio);
|
||||||
mempool_free(psd, psd_pool);
|
mempool_free(psd, psd_pool);
|
||||||
pkt_bio_finished(pd);
|
pkt_bio_finished(pd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,7 +593,8 @@ out:
|
||||||
next = bio_list_peek(&priv->list);
|
next = bio_list_peek(&priv->list);
|
||||||
spin_unlock_irq(&priv->lock);
|
spin_unlock_irq(&priv->lock);
|
||||||
|
|
||||||
bio_endio(bio, error);
|
bio->bi_error = error;
|
||||||
|
bio_endio(bio);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,10 @@ static void bio_dma_done_cb(struct rsxx_cardinfo *card,
|
||||||
if (!card->eeh_state && card->gendisk)
|
if (!card->eeh_state && card->gendisk)
|
||||||
disk_stats_complete(card, meta->bio, meta->start_time);
|
disk_stats_complete(card, meta->bio, meta->start_time);
|
||||||
|
|
||||||
bio_endio(meta->bio, atomic_read(&meta->error) ? -EIO : 0);
|
if (atomic_read(&meta->error))
|
||||||
|
bio_io_error(meta->bio);
|
||||||
|
else
|
||||||
|
bio_endio(meta->bio);
|
||||||
kmem_cache_free(bio_meta_pool, meta);
|
kmem_cache_free(bio_meta_pool, meta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +202,9 @@ static void rsxx_make_request(struct request_queue *q, struct bio *bio)
|
||||||
queue_err:
|
queue_err:
|
||||||
kmem_cache_free(bio_meta_pool, bio_meta);
|
kmem_cache_free(bio_meta_pool, bio_meta);
|
||||||
req_err:
|
req_err:
|
||||||
bio_endio(bio, st);
|
if (st)
|
||||||
|
bio->bi_error = st;
|
||||||
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------- Device Setup -------------------*/
|
/*----------------- Device Setup -------------------*/
|
||||||
|
|
|
@ -456,7 +456,7 @@ static void process_page(unsigned long data)
|
||||||
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
|
||||||
if (control & DMASCR_HARD_ERROR) {
|
if (control & DMASCR_HARD_ERROR) {
|
||||||
/* error */
|
/* error */
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
dev_printk(KERN_WARNING, &card->dev->dev,
|
dev_printk(KERN_WARNING, &card->dev->dev,
|
||||||
"I/O error on sector %d/%d\n",
|
"I/O error on sector %d/%d\n",
|
||||||
le32_to_cpu(desc->local_addr)>>9,
|
le32_to_cpu(desc->local_addr)>>9,
|
||||||
|
@ -505,7 +505,7 @@ static void process_page(unsigned long data)
|
||||||
|
|
||||||
return_bio = bio->bi_next;
|
return_bio = bio->bi_next;
|
||||||
bio->bi_next = NULL;
|
bio->bi_next = NULL;
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1078,9 +1078,9 @@ static void __end_block_io_op(struct pending_req *pending_req, int error)
|
||||||
/*
|
/*
|
||||||
* bio callback.
|
* bio callback.
|
||||||
*/
|
*/
|
||||||
static void end_block_io_op(struct bio *bio, int error)
|
static void end_block_io_op(struct bio *bio)
|
||||||
{
|
{
|
||||||
__end_block_io_op(bio->bi_private, error);
|
__end_block_io_op(bio->bi_private, bio->bi_error);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ struct blk_shadow {
|
||||||
struct split_bio {
|
struct split_bio {
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
atomic_t pending;
|
atomic_t pending;
|
||||||
int err;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static DEFINE_MUTEX(blkfront_mutex);
|
static DEFINE_MUTEX(blkfront_mutex);
|
||||||
|
@ -1478,16 +1477,14 @@ static int blkfront_probe(struct xenbus_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void split_bio_end(struct bio *bio, int error)
|
static void split_bio_end(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct split_bio *split_bio = bio->bi_private;
|
struct split_bio *split_bio = bio->bi_private;
|
||||||
|
|
||||||
if (error)
|
|
||||||
split_bio->err = error;
|
|
||||||
|
|
||||||
if (atomic_dec_and_test(&split_bio->pending)) {
|
if (atomic_dec_and_test(&split_bio->pending)) {
|
||||||
split_bio->bio->bi_phys_segments = 0;
|
split_bio->bio->bi_phys_segments = 0;
|
||||||
bio_endio(split_bio->bio, split_bio->err);
|
split_bio->bio->bi_error = bio->bi_error;
|
||||||
|
bio_endio(split_bio->bio);
|
||||||
kfree(split_bio);
|
kfree(split_bio);
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
|
|
@ -850,7 +850,7 @@ static void __zram_make_request(struct zram *zram, struct bio *bio)
|
||||||
|
|
||||||
if (unlikely(bio->bi_rw & REQ_DISCARD)) {
|
if (unlikely(bio->bi_rw & REQ_DISCARD)) {
|
||||||
zram_bio_discard(zram, index, offset, bio);
|
zram_bio_discard(zram, index, offset, bio);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -883,8 +883,7 @@ static void __zram_make_request(struct zram *zram, struct bio *bio)
|
||||||
update_position(&index, &offset, &bvec);
|
update_position(&index, &offset, &bvec);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio_endio(bio);
|
||||||
bio_endio(bio, 0);
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -278,7 +278,7 @@ err:
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btree_node_read_endio(struct bio *bio, int error)
|
static void btree_node_read_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
closure_put(cl);
|
closure_put(cl);
|
||||||
|
@ -305,7 +305,7 @@ static void bch_btree_node_read(struct btree *b)
|
||||||
bch_submit_bbio(bio, b->c, &b->key, 0);
|
bch_submit_bbio(bio, b->c, &b->key, 0);
|
||||||
closure_sync(&cl);
|
closure_sync(&cl);
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
|
if (bio->bi_error)
|
||||||
set_btree_node_io_error(b);
|
set_btree_node_io_error(b);
|
||||||
|
|
||||||
bch_bbio_free(bio, b->c);
|
bch_bbio_free(bio, b->c);
|
||||||
|
@ -371,15 +371,15 @@ static void btree_node_write_done(struct closure *cl)
|
||||||
__btree_node_write_done(cl);
|
__btree_node_write_done(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btree_node_write_endio(struct bio *bio, int error)
|
static void btree_node_write_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
struct btree *b = container_of(cl, struct btree, io);
|
struct btree *b = container_of(cl, struct btree, io);
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
set_btree_node_io_error(b);
|
set_btree_node_io_error(b);
|
||||||
|
|
||||||
bch_bbio_count_io_errors(b->c, bio, error, "writing btree");
|
bch_bbio_count_io_errors(b->c, bio, bio->bi_error, "writing btree");
|
||||||
closure_put(cl);
|
closure_put(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
* they are running owned by the thread that is running them. Otherwise, suppose
|
* they are running owned by the thread that is running them. Otherwise, suppose
|
||||||
* you submit some bios and wish to have a function run when they all complete:
|
* you submit some bios and wish to have a function run when they all complete:
|
||||||
*
|
*
|
||||||
* foo_endio(struct bio *bio, int error)
|
* foo_endio(struct bio *bio)
|
||||||
* {
|
* {
|
||||||
* closure_put(cl);
|
* closure_put(cl);
|
||||||
* }
|
* }
|
||||||
|
|
|
@ -55,19 +55,19 @@ static void bch_bio_submit_split_done(struct closure *cl)
|
||||||
|
|
||||||
s->bio->bi_end_io = s->bi_end_io;
|
s->bio->bi_end_io = s->bi_end_io;
|
||||||
s->bio->bi_private = s->bi_private;
|
s->bio->bi_private = s->bi_private;
|
||||||
bio_endio(s->bio, 0);
|
bio_endio(s->bio);
|
||||||
|
|
||||||
closure_debug_destroy(&s->cl);
|
closure_debug_destroy(&s->cl);
|
||||||
mempool_free(s, s->p->bio_split_hook);
|
mempool_free(s, s->p->bio_split_hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bch_bio_submit_split_endio(struct bio *bio, int error)
|
static void bch_bio_submit_split_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);
|
struct bio_split_hook *s = container_of(cl, struct bio_split_hook, cl);
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
clear_bit(BIO_UPTODATE, &s->bio->bi_flags);
|
s->bio->bi_error = bio->bi_error;
|
||||||
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
closure_put(cl);
|
closure_put(cl);
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* bit.
|
* bit.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void journal_read_endio(struct bio *bio, int error)
|
static void journal_read_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
closure_put(cl);
|
closure_put(cl);
|
||||||
|
@ -401,7 +401,7 @@ retry:
|
||||||
|
|
||||||
#define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1)
|
#define last_seq(j) ((j)->seq - fifo_used(&(j)->pin) + 1)
|
||||||
|
|
||||||
static void journal_discard_endio(struct bio *bio, int error)
|
static void journal_discard_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct journal_device *ja =
|
struct journal_device *ja =
|
||||||
container_of(bio, struct journal_device, discard_bio);
|
container_of(bio, struct journal_device, discard_bio);
|
||||||
|
@ -547,11 +547,11 @@ void bch_journal_next(struct journal *j)
|
||||||
pr_debug("journal_pin full (%zu)", fifo_used(&j->pin));
|
pr_debug("journal_pin full (%zu)", fifo_used(&j->pin));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void journal_write_endio(struct bio *bio, int error)
|
static void journal_write_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct journal_write *w = bio->bi_private;
|
struct journal_write *w = bio->bi_private;
|
||||||
|
|
||||||
cache_set_err_on(error, w->c, "journal io error");
|
cache_set_err_on(bio->bi_error, w->c, "journal io error");
|
||||||
closure_put(&w->c->journal.io);
|
closure_put(&w->c->journal.io);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,20 +60,20 @@ static void write_moving_finish(struct closure *cl)
|
||||||
closure_return_with_destructor(cl, moving_io_destructor);
|
closure_return_with_destructor(cl, moving_io_destructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_moving_endio(struct bio *bio, int error)
|
static void read_moving_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bbio *b = container_of(bio, struct bbio, bio);
|
struct bbio *b = container_of(bio, struct bbio, bio);
|
||||||
struct moving_io *io = container_of(bio->bi_private,
|
struct moving_io *io = container_of(bio->bi_private,
|
||||||
struct moving_io, cl);
|
struct moving_io, cl);
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
io->op.error = error;
|
io->op.error = bio->bi_error;
|
||||||
else if (!KEY_DIRTY(&b->key) &&
|
else if (!KEY_DIRTY(&b->key) &&
|
||||||
ptr_stale(io->op.c, &b->key, 0)) {
|
ptr_stale(io->op.c, &b->key, 0)) {
|
||||||
io->op.error = -EINTR;
|
io->op.error = -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bch_bbio_endio(io->op.c, bio, error, "reading data to move");
|
bch_bbio_endio(io->op.c, bio, bio->bi_error, "reading data to move");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void moving_init(struct moving_io *io)
|
static void moving_init(struct moving_io *io)
|
||||||
|
|
|
@ -173,22 +173,22 @@ static void bch_data_insert_error(struct closure *cl)
|
||||||
bch_data_insert_keys(cl);
|
bch_data_insert_keys(cl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bch_data_insert_endio(struct bio *bio, int error)
|
static void bch_data_insert_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
|
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
/* TODO: We could try to recover from this. */
|
/* TODO: We could try to recover from this. */
|
||||||
if (op->writeback)
|
if (op->writeback)
|
||||||
op->error = error;
|
op->error = bio->bi_error;
|
||||||
else if (!op->replace)
|
else if (!op->replace)
|
||||||
set_closure_fn(cl, bch_data_insert_error, op->wq);
|
set_closure_fn(cl, bch_data_insert_error, op->wq);
|
||||||
else
|
else
|
||||||
set_closure_fn(cl, NULL, NULL);
|
set_closure_fn(cl, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bch_bbio_endio(op->c, bio, error, "writing data to cache");
|
bch_bbio_endio(op->c, bio, bio->bi_error, "writing data to cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bch_data_insert_start(struct closure *cl)
|
static void bch_data_insert_start(struct closure *cl)
|
||||||
|
@ -477,7 +477,7 @@ struct search {
|
||||||
struct data_insert_op iop;
|
struct data_insert_op iop;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void bch_cache_read_endio(struct bio *bio, int error)
|
static void bch_cache_read_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bbio *b = container_of(bio, struct bbio, bio);
|
struct bbio *b = container_of(bio, struct bbio, bio);
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
|
@ -490,15 +490,15 @@ static void bch_cache_read_endio(struct bio *bio, int error)
|
||||||
* from the backing device.
|
* from the backing device.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
s->iop.error = error;
|
s->iop.error = bio->bi_error;
|
||||||
else if (!KEY_DIRTY(&b->key) &&
|
else if (!KEY_DIRTY(&b->key) &&
|
||||||
ptr_stale(s->iop.c, &b->key, 0)) {
|
ptr_stale(s->iop.c, &b->key, 0)) {
|
||||||
atomic_long_inc(&s->iop.c->cache_read_races);
|
atomic_long_inc(&s->iop.c->cache_read_races);
|
||||||
s->iop.error = -EINTR;
|
s->iop.error = -EINTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
bch_bbio_endio(s->iop.c, bio, error, "reading from cache");
|
bch_bbio_endio(s->iop.c, bio, bio->bi_error, "reading from cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -591,13 +591,13 @@ static void cache_lookup(struct closure *cl)
|
||||||
|
|
||||||
/* Common code for the make_request functions */
|
/* Common code for the make_request functions */
|
||||||
|
|
||||||
static void request_endio(struct bio *bio, int error)
|
static void request_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
struct search *s = container_of(cl, struct search, cl);
|
struct search *s = container_of(cl, struct search, cl);
|
||||||
s->iop.error = error;
|
s->iop.error = bio->bi_error;
|
||||||
/* Only cache read errors are recoverable */
|
/* Only cache read errors are recoverable */
|
||||||
s->recoverable = false;
|
s->recoverable = false;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +613,8 @@ static void bio_complete(struct search *s)
|
||||||
&s->d->disk->part0, s->start_time);
|
&s->d->disk->part0, s->start_time);
|
||||||
|
|
||||||
trace_bcache_request_end(s->d, s->orig_bio);
|
trace_bcache_request_end(s->d, s->orig_bio);
|
||||||
bio_endio(s->orig_bio, s->iop.error);
|
s->orig_bio->bi_error = s->iop.error;
|
||||||
|
bio_endio(s->orig_bio);
|
||||||
s->orig_bio = NULL;
|
s->orig_bio = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -992,7 +993,7 @@ static void cached_dev_make_request(struct request_queue *q, struct bio *bio)
|
||||||
} else {
|
} else {
|
||||||
if ((bio->bi_rw & REQ_DISCARD) &&
|
if ((bio->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(dc->bdev)))
|
!blk_queue_discard(bdev_get_queue(dc->bdev)))
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
bch_generic_make_request(bio, &d->bio_split_hook);
|
bch_generic_make_request(bio, &d->bio_split_hook);
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,7 +221,7 @@ err:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_bdev_super_endio(struct bio *bio, int error)
|
static void write_bdev_super_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct cached_dev *dc = bio->bi_private;
|
struct cached_dev *dc = bio->bi_private;
|
||||||
/* XXX: error checking */
|
/* XXX: error checking */
|
||||||
|
@ -290,11 +290,11 @@ void bch_write_bdev_super(struct cached_dev *dc, struct closure *parent)
|
||||||
closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
|
closure_return_with_destructor(cl, bch_write_bdev_super_unlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_super_endio(struct bio *bio, int error)
|
static void write_super_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct cache *ca = bio->bi_private;
|
struct cache *ca = bio->bi_private;
|
||||||
|
|
||||||
bch_count_io_errors(ca, error, "writing superblock");
|
bch_count_io_errors(ca, bio->bi_error, "writing superblock");
|
||||||
closure_put(&ca->set->sb_write);
|
closure_put(&ca->set->sb_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,12 +339,12 @@ void bcache_write_super(struct cache_set *c)
|
||||||
|
|
||||||
/* UUID io */
|
/* UUID io */
|
||||||
|
|
||||||
static void uuid_endio(struct bio *bio, int error)
|
static void uuid_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct closure *cl = bio->bi_private;
|
struct closure *cl = bio->bi_private;
|
||||||
struct cache_set *c = container_of(cl, struct cache_set, uuid_write);
|
struct cache_set *c = container_of(cl, struct cache_set, uuid_write);
|
||||||
|
|
||||||
cache_set_err_on(error, c, "accessing uuids");
|
cache_set_err_on(bio->bi_error, c, "accessing uuids");
|
||||||
bch_bbio_free(bio, c);
|
bch_bbio_free(bio, c);
|
||||||
closure_put(cl);
|
closure_put(cl);
|
||||||
}
|
}
|
||||||
|
@ -512,11 +512,11 @@ static struct uuid_entry *uuid_find_empty(struct cache_set *c)
|
||||||
* disk.
|
* disk.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void prio_endio(struct bio *bio, int error)
|
static void prio_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct cache *ca = bio->bi_private;
|
struct cache *ca = bio->bi_private;
|
||||||
|
|
||||||
cache_set_err_on(error, ca->set, "accessing priorities");
|
cache_set_err_on(bio->bi_error, ca->set, "accessing priorities");
|
||||||
bch_bbio_free(bio, ca->set);
|
bch_bbio_free(bio, ca->set);
|
||||||
closure_put(&ca->prio);
|
closure_put(&ca->prio);
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,12 +166,12 @@ static void write_dirty_finish(struct closure *cl)
|
||||||
closure_return_with_destructor(cl, dirty_io_destructor);
|
closure_return_with_destructor(cl, dirty_io_destructor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dirty_endio(struct bio *bio, int error)
|
static void dirty_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct keybuf_key *w = bio->bi_private;
|
struct keybuf_key *w = bio->bi_private;
|
||||||
struct dirty_io *io = w->private;
|
struct dirty_io *io = w->private;
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
SET_KEY_DIRTY(&w->key, false);
|
SET_KEY_DIRTY(&w->key, false);
|
||||||
|
|
||||||
closure_put(&io->cl);
|
closure_put(&io->cl);
|
||||||
|
@ -193,15 +193,15 @@ static void write_dirty(struct closure *cl)
|
||||||
continue_at(cl, write_dirty_finish, system_wq);
|
continue_at(cl, write_dirty_finish, system_wq);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_dirty_endio(struct bio *bio, int error)
|
static void read_dirty_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct keybuf_key *w = bio->bi_private;
|
struct keybuf_key *w = bio->bi_private;
|
||||||
struct dirty_io *io = w->private;
|
struct dirty_io *io = w->private;
|
||||||
|
|
||||||
bch_count_io_errors(PTR_CACHE(io->dc->disk.c, &w->key, 0),
|
bch_count_io_errors(PTR_CACHE(io->dc->disk.c, &w->key, 0),
|
||||||
error, "reading dirty data from cache");
|
bio->bi_error, "reading dirty data from cache");
|
||||||
|
|
||||||
dirty_endio(bio, error);
|
dirty_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_dirty_submit(struct closure *cl)
|
static void read_dirty_submit(struct closure *cl)
|
||||||
|
|
|
@ -236,8 +236,10 @@ void dm_cell_error(struct dm_bio_prison *prison,
|
||||||
bio_list_init(&bios);
|
bio_list_init(&bios);
|
||||||
dm_cell_release(prison, cell, &bios);
|
dm_cell_release(prison, cell, &bios);
|
||||||
|
|
||||||
while ((bio = bio_list_pop(&bios)))
|
while ((bio = bio_list_pop(&bios))) {
|
||||||
bio_endio(bio, error);
|
bio->bi_error = error;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dm_cell_error);
|
EXPORT_SYMBOL_GPL(dm_cell_error);
|
||||||
|
|
||||||
|
|
|
@ -545,7 +545,8 @@ static void dmio_complete(unsigned long error, void *context)
|
||||||
{
|
{
|
||||||
struct dm_buffer *b = context;
|
struct dm_buffer *b = context;
|
||||||
|
|
||||||
b->bio.bi_end_io(&b->bio, error ? -EIO : 0);
|
b->bio.bi_error = error ? -EIO : 0;
|
||||||
|
b->bio.bi_end_io(&b->bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void use_dmio(struct dm_buffer *b, int rw, sector_t block,
|
static void use_dmio(struct dm_buffer *b, int rw, sector_t block,
|
||||||
|
@ -575,13 +576,16 @@ static void use_dmio(struct dm_buffer *b, int rw, sector_t block,
|
||||||
b->bio.bi_end_io = end_io;
|
b->bio.bi_end_io = end_io;
|
||||||
|
|
||||||
r = dm_io(&io_req, 1, ®ion, NULL);
|
r = dm_io(&io_req, 1, ®ion, NULL);
|
||||||
if (r)
|
if (r) {
|
||||||
end_io(&b->bio, r);
|
b->bio.bi_error = r;
|
||||||
|
end_io(&b->bio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inline_endio(struct bio *bio, int error)
|
static void inline_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_end_io_t *end_fn = bio->bi_private;
|
bio_end_io_t *end_fn = bio->bi_private;
|
||||||
|
int error = bio->bi_error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the bio to free any attached resources
|
* Reset the bio to free any attached resources
|
||||||
|
@ -589,7 +593,8 @@ static void inline_endio(struct bio *bio, int error)
|
||||||
*/
|
*/
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
|
|
||||||
end_fn(bio, error);
|
bio->bi_error = error;
|
||||||
|
end_fn(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,
|
static void use_inline_bio(struct dm_buffer *b, int rw, sector_t block,
|
||||||
|
@ -661,13 +666,14 @@ static void submit_io(struct dm_buffer *b, int rw, sector_t block,
|
||||||
* Set the error, clear B_WRITING bit and wake anyone who was waiting on
|
* Set the error, clear B_WRITING bit and wake anyone who was waiting on
|
||||||
* it.
|
* it.
|
||||||
*/
|
*/
|
||||||
static void write_endio(struct bio *bio, int error)
|
static void write_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
|
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
|
||||||
|
|
||||||
b->write_error = error;
|
b->write_error = bio->bi_error;
|
||||||
if (unlikely(error)) {
|
if (unlikely(bio->bi_error)) {
|
||||||
struct dm_bufio_client *c = b->c;
|
struct dm_bufio_client *c = b->c;
|
||||||
|
int error = bio->bi_error;
|
||||||
(void)cmpxchg(&c->async_write_error, 0, error);
|
(void)cmpxchg(&c->async_write_error, 0, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,11 +1032,11 @@ found_buffer:
|
||||||
* The endio routine for reading: set the error, clear the bit and wake up
|
* The endio routine for reading: set the error, clear the bit and wake up
|
||||||
* anyone waiting on the buffer.
|
* anyone waiting on the buffer.
|
||||||
*/
|
*/
|
||||||
static void read_endio(struct bio *bio, int error)
|
static void read_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
|
struct dm_buffer *b = container_of(bio, struct dm_buffer, bio);
|
||||||
|
|
||||||
b->read_error = error;
|
b->read_error = bio->bi_error;
|
||||||
|
|
||||||
BUG_ON(!test_bit(B_READING, &b->state));
|
BUG_ON(!test_bit(B_READING, &b->state));
|
||||||
|
|
||||||
|
|
|
@ -919,14 +919,14 @@ static void defer_writethrough_bio(struct cache *cache, struct bio *bio)
|
||||||
wake_worker(cache);
|
wake_worker(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writethrough_endio(struct bio *bio, int err)
|
static void writethrough_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT);
|
struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT);
|
||||||
|
|
||||||
dm_unhook_bio(&pb->hook_info, bio);
|
dm_unhook_bio(&pb->hook_info, bio);
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
bio_endio(bio, err);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,7 +1231,7 @@ static void migration_success_post_commit(struct dm_cache_migration *mg)
|
||||||
* The block was promoted via an overwrite, so it's dirty.
|
* The block was promoted via an overwrite, so it's dirty.
|
||||||
*/
|
*/
|
||||||
set_dirty(cache, mg->new_oblock, mg->cblock);
|
set_dirty(cache, mg->new_oblock, mg->cblock);
|
||||||
bio_endio(mg->new_ocell->holder, 0);
|
bio_endio(mg->new_ocell->holder);
|
||||||
cell_defer(cache, mg->new_ocell, false);
|
cell_defer(cache, mg->new_ocell, false);
|
||||||
}
|
}
|
||||||
free_io_migration(mg);
|
free_io_migration(mg);
|
||||||
|
@ -1284,7 +1284,7 @@ static void issue_copy(struct dm_cache_migration *mg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void overwrite_endio(struct bio *bio, int err)
|
static void overwrite_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dm_cache_migration *mg = bio->bi_private;
|
struct dm_cache_migration *mg = bio->bi_private;
|
||||||
struct cache *cache = mg->cache;
|
struct cache *cache = mg->cache;
|
||||||
|
@ -1294,7 +1294,7 @@ static void overwrite_endio(struct bio *bio, int err)
|
||||||
|
|
||||||
dm_unhook_bio(&pb->hook_info, bio);
|
dm_unhook_bio(&pb->hook_info, bio);
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
mg->err = true;
|
mg->err = true;
|
||||||
|
|
||||||
mg->requeue_holder = false;
|
mg->requeue_holder = false;
|
||||||
|
@ -1358,7 +1358,7 @@ static void issue_discard(struct dm_cache_migration *mg)
|
||||||
b = to_dblock(from_dblock(b) + 1);
|
b = to_dblock(from_dblock(b) + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
cell_defer(mg->cache, mg->new_ocell, false);
|
cell_defer(mg->cache, mg->new_ocell, false);
|
||||||
free_migration(mg);
|
free_migration(mg);
|
||||||
}
|
}
|
||||||
|
@ -1631,7 +1631,7 @@ static void process_discard_bio(struct cache *cache, struct prealloc *structs,
|
||||||
|
|
||||||
calc_discard_block_range(cache, bio, &b, &e);
|
calc_discard_block_range(cache, bio, &b, &e);
|
||||||
if (b == e) {
|
if (b == e) {
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2213,8 +2213,10 @@ static void requeue_deferred_bios(struct cache *cache)
|
||||||
bio_list_merge(&bios, &cache->deferred_bios);
|
bio_list_merge(&bios, &cache->deferred_bios);
|
||||||
bio_list_init(&cache->deferred_bios);
|
bio_list_init(&cache->deferred_bios);
|
||||||
|
|
||||||
while ((bio = bio_list_pop(&bios)))
|
while ((bio = bio_list_pop(&bios))) {
|
||||||
bio_endio(bio, DM_ENDIO_REQUEUE);
|
bio->bi_error = DM_ENDIO_REQUEUE;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int more_work(struct cache *cache)
|
static int more_work(struct cache *cache)
|
||||||
|
@ -3119,7 +3121,7 @@ static int cache_map(struct dm_target *ti, struct bio *bio)
|
||||||
* This is a duplicate writethrough io that is no
|
* This is a duplicate writethrough io that is no
|
||||||
* longer needed because the block has been demoted.
|
* longer needed because the block has been demoted.
|
||||||
*/
|
*/
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
// FIXME: remap everything as a miss
|
// FIXME: remap everything as a miss
|
||||||
cell_defer(cache, cell, false);
|
cell_defer(cache, cell, false);
|
||||||
r = DM_MAPIO_SUBMITTED;
|
r = DM_MAPIO_SUBMITTED;
|
||||||
|
|
|
@ -1076,7 +1076,8 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
|
||||||
if (io->ctx.req)
|
if (io->ctx.req)
|
||||||
crypt_free_req(cc, io->ctx.req, base_bio);
|
crypt_free_req(cc, io->ctx.req, base_bio);
|
||||||
|
|
||||||
bio_endio(base_bio, error);
|
base_bio->bi_error = error;
|
||||||
|
bio_endio(base_bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1096,15 +1097,12 @@ static void crypt_dec_pending(struct dm_crypt_io *io)
|
||||||
* The work is done per CPU global for all dm-crypt instances.
|
* The work is done per CPU global for all dm-crypt instances.
|
||||||
* They should not depend on each other and do not block.
|
* They should not depend on each other and do not block.
|
||||||
*/
|
*/
|
||||||
static void crypt_endio(struct bio *clone, int error)
|
static void crypt_endio(struct bio *clone)
|
||||||
{
|
{
|
||||||
struct dm_crypt_io *io = clone->bi_private;
|
struct dm_crypt_io *io = clone->bi_private;
|
||||||
struct crypt_config *cc = io->cc;
|
struct crypt_config *cc = io->cc;
|
||||||
unsigned rw = bio_data_dir(clone);
|
unsigned rw = bio_data_dir(clone);
|
||||||
|
|
||||||
if (unlikely(!bio_flagged(clone, BIO_UPTODATE) && !error))
|
|
||||||
error = -EIO;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* free the processed pages
|
* free the processed pages
|
||||||
*/
|
*/
|
||||||
|
@ -1113,13 +1111,13 @@ static void crypt_endio(struct bio *clone, int error)
|
||||||
|
|
||||||
bio_put(clone);
|
bio_put(clone);
|
||||||
|
|
||||||
if (rw == READ && !error) {
|
if (rw == READ && !clone->bi_error) {
|
||||||
kcryptd_queue_crypt(io);
|
kcryptd_queue_crypt(io);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(error))
|
if (unlikely(clone->bi_error))
|
||||||
io->error = error;
|
io->error = clone->bi_error;
|
||||||
|
|
||||||
crypt_dec_pending(io);
|
crypt_dec_pending(io);
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,7 +296,7 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)
|
||||||
* Drop writes?
|
* Drop writes?
|
||||||
*/
|
*/
|
||||||
if (test_bit(DROP_WRITES, &fc->flags)) {
|
if (test_bit(DROP_WRITES, &fc->flags)) {
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return DM_MAPIO_SUBMITTED;
|
return DM_MAPIO_SUBMITTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,12 +134,12 @@ static void dec_count(struct io *io, unsigned int region, int error)
|
||||||
complete_io(io);
|
complete_io(io);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void endio(struct bio *bio, int error)
|
static void endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct io *io;
|
struct io *io;
|
||||||
unsigned region;
|
unsigned region;
|
||||||
|
|
||||||
if (error && bio_data_dir(bio) == READ)
|
if (bio->bi_error && bio_data_dir(bio) == READ)
|
||||||
zero_fill_bio(bio);
|
zero_fill_bio(bio);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -149,7 +149,7 @@ static void endio(struct bio *bio, int error)
|
||||||
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
|
||||||
dec_count(io, region, error);
|
dec_count(io, region, bio->bi_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
/*-----------------------------------------------------------------
|
||||||
|
|
|
@ -146,16 +146,16 @@ static void put_io_block(struct log_writes_c *lc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_end_io(struct bio *bio, int err)
|
static void log_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct log_writes_c *lc = bio->bi_private;
|
struct log_writes_c *lc = bio->bi_private;
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
DMERR("Error writing log block, error=%d", err);
|
DMERR("Error writing log block, error=%d", bio->bi_error);
|
||||||
spin_lock_irqsave(&lc->blocks_lock, flags);
|
spin_lock_irqsave(&lc->blocks_lock, flags);
|
||||||
lc->logging_enabled = false;
|
lc->logging_enabled = false;
|
||||||
spin_unlock_irqrestore(&lc->blocks_lock, flags);
|
spin_unlock_irqrestore(&lc->blocks_lock, flags);
|
||||||
|
@ -205,7 +205,6 @@ static int write_metadata(struct log_writes_c *lc, void *entry,
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio->bi_bdev = lc->logdev->bdev;
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
|
|
||||||
page = alloc_page(GFP_KERNEL);
|
page = alloc_page(GFP_KERNEL);
|
||||||
if (!page) {
|
if (!page) {
|
||||||
|
@ -270,7 +269,6 @@ static int log_one_block(struct log_writes_c *lc,
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio->bi_bdev = lc->logdev->bdev;
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
|
|
||||||
for (i = 0; i < block->vec_cnt; i++) {
|
for (i = 0; i < block->vec_cnt; i++) {
|
||||||
/*
|
/*
|
||||||
|
@ -292,7 +290,6 @@ static int log_one_block(struct log_writes_c *lc,
|
||||||
bio->bi_bdev = lc->logdev->bdev;
|
bio->bi_bdev = lc->logdev->bdev;
|
||||||
bio->bi_end_io = log_end_io;
|
bio->bi_end_io = log_end_io;
|
||||||
bio->bi_private = lc;
|
bio->bi_private = lc;
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
|
|
||||||
ret = bio_add_page(bio, block->vecs[i].bv_page,
|
ret = bio_add_page(bio, block->vecs[i].bv_page,
|
||||||
block->vecs[i].bv_len, 0);
|
block->vecs[i].bv_len, 0);
|
||||||
|
@ -606,7 +603,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
|
||||||
WARN_ON(flush_bio || fua_bio);
|
WARN_ON(flush_bio || fua_bio);
|
||||||
if (lc->device_supports_discard)
|
if (lc->device_supports_discard)
|
||||||
goto map_bio;
|
goto map_bio;
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return DM_MAPIO_SUBMITTED;
|
return DM_MAPIO_SUBMITTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,9 +490,11 @@ static void hold_bio(struct mirror_set *ms, struct bio *bio)
|
||||||
* If device is suspended, complete the bio.
|
* If device is suspended, complete the bio.
|
||||||
*/
|
*/
|
||||||
if (dm_noflush_suspending(ms->ti))
|
if (dm_noflush_suspending(ms->ti))
|
||||||
bio_endio(bio, DM_ENDIO_REQUEUE);
|
bio->bi_error = DM_ENDIO_REQUEUE;
|
||||||
else
|
else
|
||||||
bio_endio(bio, -EIO);
|
bio->bi_error = -EIO;
|
||||||
|
|
||||||
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +517,7 @@ static void read_callback(unsigned long error, void *context)
|
||||||
bio_set_m(bio, NULL);
|
bio_set_m(bio, NULL);
|
||||||
|
|
||||||
if (likely(!error)) {
|
if (likely(!error)) {
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -531,7 +533,7 @@ static void read_callback(unsigned long error, void *context)
|
||||||
|
|
||||||
DMERR_LIMIT("Read failure on mirror device %s. Failing I/O.",
|
DMERR_LIMIT("Read failure on mirror device %s. Failing I/O.",
|
||||||
m->dev->name);
|
m->dev->name);
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Asynchronous read. */
|
/* Asynchronous read. */
|
||||||
|
@ -580,7 +582,7 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
|
||||||
if (likely(m))
|
if (likely(m))
|
||||||
read_async_bio(m, bio);
|
read_async_bio(m, bio);
|
||||||
else
|
else
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +600,7 @@ static void do_reads(struct mirror_set *ms, struct bio_list *reads)
|
||||||
|
|
||||||
static void write_callback(unsigned long error, void *context)
|
static void write_callback(unsigned long error, void *context)
|
||||||
{
|
{
|
||||||
unsigned i, ret = 0;
|
unsigned i;
|
||||||
struct bio *bio = (struct bio *) context;
|
struct bio *bio = (struct bio *) context;
|
||||||
struct mirror_set *ms;
|
struct mirror_set *ms;
|
||||||
int should_wake = 0;
|
int should_wake = 0;
|
||||||
|
@ -614,7 +616,7 @@ static void write_callback(unsigned long error, void *context)
|
||||||
* regions with the same code.
|
* regions with the same code.
|
||||||
*/
|
*/
|
||||||
if (likely(!error)) {
|
if (likely(!error)) {
|
||||||
bio_endio(bio, ret);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +625,8 @@ static void write_callback(unsigned long error, void *context)
|
||||||
* degrade the array.
|
* degrade the array.
|
||||||
*/
|
*/
|
||||||
if (bio->bi_rw & REQ_DISCARD) {
|
if (bio->bi_rw & REQ_DISCARD) {
|
||||||
bio_endio(bio, -EOPNOTSUPP);
|
bio->bi_error = -EOPNOTSUPP;
|
||||||
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -828,13 +831,12 @@ static void do_failures(struct mirror_set *ms, struct bio_list *failures)
|
||||||
* be wrong if the failed leg returned after reboot and
|
* be wrong if the failed leg returned after reboot and
|
||||||
* got replicated back to the good legs.)
|
* got replicated back to the good legs.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (unlikely(!get_valid_mirror(ms) || (keep_log(ms) && ms->log_failure)))
|
if (unlikely(!get_valid_mirror(ms) || (keep_log(ms) && ms->log_failure)))
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
else if (errors_handled(ms) && !keep_log(ms))
|
else if (errors_handled(ms) && !keep_log(ms))
|
||||||
hold_bio(ms, bio);
|
hold_bio(ms, bio);
|
||||||
else
|
else
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1490,7 +1490,7 @@ out:
|
||||||
error_bios(snapshot_bios);
|
error_bios(snapshot_bios);
|
||||||
} else {
|
} else {
|
||||||
if (full_bio)
|
if (full_bio)
|
||||||
bio_endio(full_bio, 0);
|
bio_endio(full_bio);
|
||||||
flush_bios(snapshot_bios);
|
flush_bios(snapshot_bios);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1580,11 +1580,11 @@ static void start_copy(struct dm_snap_pending_exception *pe)
|
||||||
dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe);
|
dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void full_bio_end_io(struct bio *bio, int error)
|
static void full_bio_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
void *callback_data = bio->bi_private;
|
void *callback_data = bio->bi_private;
|
||||||
|
|
||||||
dm_kcopyd_do_callback(callback_data, 0, error ? 1 : 0);
|
dm_kcopyd_do_callback(callback_data, 0, bio->bi_error ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_full_bio(struct dm_snap_pending_exception *pe,
|
static void start_full_bio(struct dm_snap_pending_exception *pe,
|
||||||
|
|
|
@ -273,7 +273,7 @@ static int stripe_map_range(struct stripe_c *sc, struct bio *bio,
|
||||||
return DM_MAPIO_REMAPPED;
|
return DM_MAPIO_REMAPPED;
|
||||||
} else {
|
} else {
|
||||||
/* The range doesn't map to the target stripe */
|
/* The range doesn't map to the target stripe */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return DM_MAPIO_SUBMITTED;
|
return DM_MAPIO_SUBMITTED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -614,8 +614,10 @@ static void error_bio_list(struct bio_list *bios, int error)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
|
|
||||||
while ((bio = bio_list_pop(bios)))
|
while ((bio = bio_list_pop(bios))) {
|
||||||
bio_endio(bio, error);
|
bio->bi_error = error;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void error_thin_bio_list(struct thin_c *tc, struct bio_list *master, int error)
|
static void error_thin_bio_list(struct thin_c *tc, struct bio_list *master, int error)
|
||||||
|
@ -864,14 +866,14 @@ static void copy_complete(int read_err, unsigned long write_err, void *context)
|
||||||
complete_mapping_preparation(m);
|
complete_mapping_preparation(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void overwrite_endio(struct bio *bio, int err)
|
static void overwrite_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
|
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
|
||||||
struct dm_thin_new_mapping *m = h->overwrite_mapping;
|
struct dm_thin_new_mapping *m = h->overwrite_mapping;
|
||||||
|
|
||||||
bio->bi_end_io = m->saved_bi_end_io;
|
bio->bi_end_io = m->saved_bi_end_io;
|
||||||
|
|
||||||
m->err = err;
|
m->err = bio->bi_error;
|
||||||
complete_mapping_preparation(m);
|
complete_mapping_preparation(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -996,7 +998,7 @@ static void process_prepared_mapping(struct dm_thin_new_mapping *m)
|
||||||
*/
|
*/
|
||||||
if (bio) {
|
if (bio) {
|
||||||
inc_remap_and_issue_cell(tc, m->cell, m->data_block);
|
inc_remap_and_issue_cell(tc, m->cell, m->data_block);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
} else {
|
} else {
|
||||||
inc_all_io_entry(tc->pool, m->cell->holder);
|
inc_all_io_entry(tc->pool, m->cell->holder);
|
||||||
remap_and_issue(tc, m->cell->holder, m->data_block);
|
remap_and_issue(tc, m->cell->holder, m->data_block);
|
||||||
|
@ -1026,7 +1028,7 @@ static void process_prepared_discard_fail(struct dm_thin_new_mapping *m)
|
||||||
|
|
||||||
static void process_prepared_discard_success(struct dm_thin_new_mapping *m)
|
static void process_prepared_discard_success(struct dm_thin_new_mapping *m)
|
||||||
{
|
{
|
||||||
bio_endio(m->bio, 0);
|
bio_endio(m->bio);
|
||||||
free_discard_mapping(m);
|
free_discard_mapping(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1040,7 +1042,7 @@ static void process_prepared_discard_no_passdown(struct dm_thin_new_mapping *m)
|
||||||
metadata_operation_failed(tc->pool, "dm_thin_remove_range", r);
|
metadata_operation_failed(tc->pool, "dm_thin_remove_range", r);
|
||||||
bio_io_error(m->bio);
|
bio_io_error(m->bio);
|
||||||
} else
|
} else
|
||||||
bio_endio(m->bio, 0);
|
bio_endio(m->bio);
|
||||||
|
|
||||||
cell_defer_no_holder(tc, m->cell);
|
cell_defer_no_holder(tc, m->cell);
|
||||||
mempool_free(m, tc->pool->mapping_pool);
|
mempool_free(m, tc->pool->mapping_pool);
|
||||||
|
@ -1111,7 +1113,8 @@ static void process_prepared_discard_passdown(struct dm_thin_new_mapping *m)
|
||||||
* Even if r is set, there could be sub discards in flight that we
|
* Even if r is set, there could be sub discards in flight that we
|
||||||
* need to wait for.
|
* need to wait for.
|
||||||
*/
|
*/
|
||||||
bio_endio(m->bio, r);
|
m->bio->bi_error = r;
|
||||||
|
bio_endio(m->bio);
|
||||||
cell_defer_no_holder(tc, m->cell);
|
cell_defer_no_holder(tc, m->cell);
|
||||||
mempool_free(m, pool->mapping_pool);
|
mempool_free(m, pool->mapping_pool);
|
||||||
}
|
}
|
||||||
|
@ -1487,9 +1490,10 @@ static void handle_unserviceable_bio(struct pool *pool, struct bio *bio)
|
||||||
{
|
{
|
||||||
int error = should_error_unserviceable_bio(pool);
|
int error = should_error_unserviceable_bio(pool);
|
||||||
|
|
||||||
if (error)
|
if (error) {
|
||||||
bio_endio(bio, error);
|
bio->bi_error = error;
|
||||||
else
|
bio_endio(bio);
|
||||||
|
} else
|
||||||
retry_on_resume(bio);
|
retry_on_resume(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1625,7 +1629,7 @@ static void process_discard_cell_passdown(struct thin_c *tc, struct dm_bio_priso
|
||||||
* will prevent completion until the sub range discards have
|
* will prevent completion until the sub range discards have
|
||||||
* completed.
|
* completed.
|
||||||
*/
|
*/
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_discard_bio(struct thin_c *tc, struct bio *bio)
|
static void process_discard_bio(struct thin_c *tc, struct bio *bio)
|
||||||
|
@ -1639,7 +1643,7 @@ static void process_discard_bio(struct thin_c *tc, struct bio *bio)
|
||||||
/*
|
/*
|
||||||
* The discard covers less than a block.
|
* The discard covers less than a block.
|
||||||
*/
|
*/
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1784,7 +1788,7 @@ static void provision_block(struct thin_c *tc, struct bio *bio, dm_block_t block
|
||||||
if (bio_data_dir(bio) == READ) {
|
if (bio_data_dir(bio) == READ) {
|
||||||
zero_fill_bio(bio);
|
zero_fill_bio(bio);
|
||||||
cell_defer_no_holder(tc, cell);
|
cell_defer_no_holder(tc, cell);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1849,7 +1853,7 @@ static void process_cell(struct thin_c *tc, struct dm_bio_prison_cell *cell)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
zero_fill_bio(bio);
|
zero_fill_bio(bio);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
provision_block(tc, bio, block, cell);
|
provision_block(tc, bio, block, cell);
|
||||||
|
@ -1920,7 +1924,7 @@ static void __process_bio_read_only(struct thin_c *tc, struct bio *bio,
|
||||||
}
|
}
|
||||||
|
|
||||||
zero_fill_bio(bio);
|
zero_fill_bio(bio);
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1945,7 +1949,7 @@ static void process_cell_read_only(struct thin_c *tc, struct dm_bio_prison_cell
|
||||||
|
|
||||||
static void process_bio_success(struct thin_c *tc, struct bio *bio)
|
static void process_bio_success(struct thin_c *tc, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_bio_fail(struct thin_c *tc, struct bio *bio)
|
static void process_bio_fail(struct thin_c *tc, struct bio *bio)
|
||||||
|
@ -2581,7 +2585,8 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
|
||||||
thin_hook_bio(tc, bio);
|
thin_hook_bio(tc, bio);
|
||||||
|
|
||||||
if (tc->requeue_mode) {
|
if (tc->requeue_mode) {
|
||||||
bio_endio(bio, DM_ENDIO_REQUEUE);
|
bio->bi_error = DM_ENDIO_REQUEUE;
|
||||||
|
bio_endio(bio);
|
||||||
return DM_MAPIO_SUBMITTED;
|
return DM_MAPIO_SUBMITTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,8 +458,9 @@ static void verity_finish_io(struct dm_verity_io *io, int error)
|
||||||
|
|
||||||
bio->bi_end_io = io->orig_bi_end_io;
|
bio->bi_end_io = io->orig_bi_end_io;
|
||||||
bio->bi_private = io->orig_bi_private;
|
bio->bi_private = io->orig_bi_private;
|
||||||
|
bio->bi_error = error;
|
||||||
|
|
||||||
bio_endio(bio, error);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verity_work(struct work_struct *w)
|
static void verity_work(struct work_struct *w)
|
||||||
|
@ -469,12 +470,12 @@ static void verity_work(struct work_struct *w)
|
||||||
verity_finish_io(io, verity_verify_io(io));
|
verity_finish_io(io, verity_verify_io(io));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void verity_end_io(struct bio *bio, int error)
|
static void verity_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dm_verity_io *io = bio->bi_private;
|
struct dm_verity_io *io = bio->bi_private;
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
verity_finish_io(io, error);
|
verity_finish_io(io, bio->bi_error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ static int zero_map(struct dm_target *ti, struct bio *bio)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
|
|
||||||
/* accepted bio, don't make new request */
|
/* accepted bio, don't make new request */
|
||||||
return DM_MAPIO_SUBMITTED;
|
return DM_MAPIO_SUBMITTED;
|
||||||
|
|
|
@ -944,7 +944,8 @@ static void dec_pending(struct dm_io *io, int error)
|
||||||
} else {
|
} else {
|
||||||
/* done with normal IO or empty flush */
|
/* done with normal IO or empty flush */
|
||||||
trace_block_bio_complete(md->queue, bio, io_error);
|
trace_block_bio_complete(md->queue, bio, io_error);
|
||||||
bio_endio(bio, io_error);
|
bio->bi_error = io_error;
|
||||||
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -957,17 +958,15 @@ static void disable_write_same(struct mapped_device *md)
|
||||||
limits->max_write_same_sectors = 0;
|
limits->max_write_same_sectors = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clone_endio(struct bio *bio, int error)
|
static void clone_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
|
int error = bio->bi_error;
|
||||||
int r = error;
|
int r = error;
|
||||||
struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
|
struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
|
||||||
struct dm_io *io = tio->io;
|
struct dm_io *io = tio->io;
|
||||||
struct mapped_device *md = tio->io->md;
|
struct mapped_device *md = tio->io->md;
|
||||||
dm_endio_fn endio = tio->ti->type->end_io;
|
dm_endio_fn endio = tio->ti->type->end_io;
|
||||||
|
|
||||||
if (!bio_flagged(bio, BIO_UPTODATE) && !error)
|
|
||||||
error = -EIO;
|
|
||||||
|
|
||||||
if (endio) {
|
if (endio) {
|
||||||
r = endio(tio->ti, bio, error);
|
r = endio(tio->ti, bio, error);
|
||||||
if (r < 0 || r == DM_ENDIO_REQUEUE)
|
if (r < 0 || r == DM_ENDIO_REQUEUE)
|
||||||
|
@ -996,7 +995,7 @@ static void clone_endio(struct bio *bio, int error)
|
||||||
/*
|
/*
|
||||||
* Partial completion handling for request-based dm
|
* Partial completion handling for request-based dm
|
||||||
*/
|
*/
|
||||||
static void end_clone_bio(struct bio *clone, int error)
|
static void end_clone_bio(struct bio *clone)
|
||||||
{
|
{
|
||||||
struct dm_rq_clone_bio_info *info =
|
struct dm_rq_clone_bio_info *info =
|
||||||
container_of(clone, struct dm_rq_clone_bio_info, clone);
|
container_of(clone, struct dm_rq_clone_bio_info, clone);
|
||||||
|
@ -1013,13 +1012,13 @@ static void end_clone_bio(struct bio *clone, int error)
|
||||||
* the remainder.
|
* the remainder.
|
||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
else if (error) {
|
else if (bio->bi_error) {
|
||||||
/*
|
/*
|
||||||
* Don't notice the error to the upper layer yet.
|
* Don't notice the error to the upper layer yet.
|
||||||
* The error handling decision is made by the target driver,
|
* The error handling decision is made by the target driver,
|
||||||
* when the request is completed.
|
* when the request is completed.
|
||||||
*/
|
*/
|
||||||
tio->error = error;
|
tio->error = bio->bi_error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
|
|
||||||
static void faulty_fail(struct bio *bio, int error)
|
static void faulty_fail(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio *b = bio->bi_private;
|
struct bio *b = bio->bi_private;
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ static void make_request(struct mddev *mddev, struct bio *bio)
|
||||||
/* special case - don't decrement, don't generic_make_request,
|
/* special case - don't decrement, don't generic_make_request,
|
||||||
* just fail immediately
|
* just fail immediately
|
||||||
*/
|
*/
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -297,7 +297,7 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
|
||||||
if (unlikely((split->bi_rw & REQ_DISCARD) &&
|
if (unlikely((split->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
|
!blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(split, 0);
|
bio_endio(split);
|
||||||
} else
|
} else
|
||||||
generic_make_request(split);
|
generic_make_request(split);
|
||||||
} while (split != bio);
|
} while (split != bio);
|
||||||
|
|
|
@ -263,7 +263,9 @@ static void md_make_request(struct request_queue *q, struct bio *bio)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mddev->ro == 1 && unlikely(rw == WRITE)) {
|
if (mddev->ro == 1 && unlikely(rw == WRITE)) {
|
||||||
bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS);
|
if (bio_sectors(bio) != 0)
|
||||||
|
bio->bi_error = -EROFS;
|
||||||
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
smp_rmb(); /* Ensure implications of 'active' are visible */
|
smp_rmb(); /* Ensure implications of 'active' are visible */
|
||||||
|
@ -377,7 +379,7 @@ static int md_mergeable_bvec(struct request_queue *q,
|
||||||
* Generic flush handling for md
|
* Generic flush handling for md
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void md_end_flush(struct bio *bio, int err)
|
static void md_end_flush(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct md_rdev *rdev = bio->bi_private;
|
struct md_rdev *rdev = bio->bi_private;
|
||||||
struct mddev *mddev = rdev->mddev;
|
struct mddev *mddev = rdev->mddev;
|
||||||
|
@ -433,7 +435,7 @@ static void md_submit_flush_data(struct work_struct *ws)
|
||||||
|
|
||||||
if (bio->bi_iter.bi_size == 0)
|
if (bio->bi_iter.bi_size == 0)
|
||||||
/* an empty barrier - all done */
|
/* an empty barrier - all done */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else {
|
else {
|
||||||
bio->bi_rw &= ~REQ_FLUSH;
|
bio->bi_rw &= ~REQ_FLUSH;
|
||||||
mddev->pers->make_request(mddev, bio);
|
mddev->pers->make_request(mddev, bio);
|
||||||
|
@ -728,15 +730,13 @@ void md_rdev_clear(struct md_rdev *rdev)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(md_rdev_clear);
|
EXPORT_SYMBOL_GPL(md_rdev_clear);
|
||||||
|
|
||||||
static void super_written(struct bio *bio, int error)
|
static void super_written(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct md_rdev *rdev = bio->bi_private;
|
struct md_rdev *rdev = bio->bi_private;
|
||||||
struct mddev *mddev = rdev->mddev;
|
struct mddev *mddev = rdev->mddev;
|
||||||
|
|
||||||
if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags)) {
|
if (bio->bi_error) {
|
||||||
printk("md: super_written gets error=%d, uptodate=%d\n",
|
printk("md: super_written gets error=%d\n", bio->bi_error);
|
||||||
error, test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
WARN_ON(test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
md_error(mddev, rdev);
|
md_error(mddev, rdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +791,7 @@ int sync_page_io(struct md_rdev *rdev, sector_t sector, int size,
|
||||||
bio_add_page(bio, page, size, 0);
|
bio_add_page(bio, page, size, 0);
|
||||||
submit_bio_wait(rw, bio);
|
submit_bio_wait(rw, bio);
|
||||||
|
|
||||||
ret = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
ret = !bio->bi_error;
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,18 +77,18 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err)
|
||||||
struct bio *bio = mp_bh->master_bio;
|
struct bio *bio = mp_bh->master_bio;
|
||||||
struct mpconf *conf = mp_bh->mddev->private;
|
struct mpconf *conf = mp_bh->mddev->private;
|
||||||
|
|
||||||
bio_endio(bio, err);
|
bio->bi_error = err;
|
||||||
|
bio_endio(bio);
|
||||||
mempool_free(mp_bh, conf->pool);
|
mempool_free(mp_bh, conf->pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void multipath_end_request(struct bio *bio, int error)
|
static void multipath_end_request(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct multipath_bh *mp_bh = bio->bi_private;
|
struct multipath_bh *mp_bh = bio->bi_private;
|
||||||
struct mpconf *conf = mp_bh->mddev->private;
|
struct mpconf *conf = mp_bh->mddev->private;
|
||||||
struct md_rdev *rdev = conf->multipaths[mp_bh->path].rdev;
|
struct md_rdev *rdev = conf->multipaths[mp_bh->path].rdev;
|
||||||
|
|
||||||
if (uptodate)
|
if (!bio->bi_error)
|
||||||
multipath_end_bh_io(mp_bh, 0);
|
multipath_end_bh_io(mp_bh, 0);
|
||||||
else if (!(bio->bi_rw & REQ_RAHEAD)) {
|
else if (!(bio->bi_rw & REQ_RAHEAD)) {
|
||||||
/*
|
/*
|
||||||
|
@ -101,7 +101,7 @@ static void multipath_end_request(struct bio *bio, int error)
|
||||||
(unsigned long long)bio->bi_iter.bi_sector);
|
(unsigned long long)bio->bi_iter.bi_sector);
|
||||||
multipath_reschedule_retry(mp_bh);
|
multipath_reschedule_retry(mp_bh);
|
||||||
} else
|
} else
|
||||||
multipath_end_bh_io(mp_bh, error);
|
multipath_end_bh_io(mp_bh, bio->bi_error);
|
||||||
rdev_dec_pending(rdev, conf->mddev);
|
rdev_dec_pending(rdev, conf->mddev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
|
||||||
|
|
||||||
mp_bh->path = multipath_map(conf);
|
mp_bh->path = multipath_map(conf);
|
||||||
if (mp_bh->path < 0) {
|
if (mp_bh->path < 0) {
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
mempool_free(mp_bh, conf->pool);
|
mempool_free(mp_bh, conf->pool);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,7 +543,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
|
||||||
if (unlikely((split->bi_rw & REQ_DISCARD) &&
|
if (unlikely((split->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
|
!blk_queue_discard(bdev_get_queue(split->bi_bdev)))) {
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(split, 0);
|
bio_endio(split);
|
||||||
} else
|
} else
|
||||||
generic_make_request(split);
|
generic_make_request(split);
|
||||||
} while (split != bio);
|
} while (split != bio);
|
||||||
|
|
|
@ -255,9 +255,10 @@ static void call_bio_endio(struct r1bio *r1_bio)
|
||||||
done = 1;
|
done = 1;
|
||||||
|
|
||||||
if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
|
if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
|
|
||||||
if (done) {
|
if (done) {
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
/*
|
/*
|
||||||
* Wake up any possible resync thread that waits for the device
|
* Wake up any possible resync thread that waits for the device
|
||||||
* to go idle.
|
* to go idle.
|
||||||
|
@ -312,9 +313,9 @@ static int find_bio_disk(struct r1bio *r1_bio, struct bio *bio)
|
||||||
return mirror;
|
return mirror;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid1_end_read_request(struct bio *bio, int error)
|
static void raid1_end_read_request(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
int uptodate = !bio->bi_error;
|
||||||
struct r1bio *r1_bio = bio->bi_private;
|
struct r1bio *r1_bio = bio->bi_private;
|
||||||
int mirror;
|
int mirror;
|
||||||
struct r1conf *conf = r1_bio->mddev->private;
|
struct r1conf *conf = r1_bio->mddev->private;
|
||||||
|
@ -397,9 +398,8 @@ static void r1_bio_write_done(struct r1bio *r1_bio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid1_end_write_request(struct bio *bio, int error)
|
static void raid1_end_write_request(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct r1bio *r1_bio = bio->bi_private;
|
struct r1bio *r1_bio = bio->bi_private;
|
||||||
int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
|
int mirror, behind = test_bit(R1BIO_BehindIO, &r1_bio->state);
|
||||||
struct r1conf *conf = r1_bio->mddev->private;
|
struct r1conf *conf = r1_bio->mddev->private;
|
||||||
|
@ -410,7 +410,7 @@ static void raid1_end_write_request(struct bio *bio, int error)
|
||||||
/*
|
/*
|
||||||
* 'one mirror IO has finished' event handler:
|
* 'one mirror IO has finished' event handler:
|
||||||
*/
|
*/
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
set_bit(WriteErrorSeen,
|
set_bit(WriteErrorSeen,
|
||||||
&conf->mirrors[mirror].rdev->flags);
|
&conf->mirrors[mirror].rdev->flags);
|
||||||
if (!test_and_set_bit(WantReplacement,
|
if (!test_and_set_bit(WantReplacement,
|
||||||
|
@ -793,7 +793,7 @@ static void flush_pending_writes(struct r1conf *conf)
|
||||||
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
bio = next;
|
bio = next;
|
||||||
|
@ -1068,7 +1068,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||||
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
bio = next;
|
bio = next;
|
||||||
|
@ -1734,7 +1734,7 @@ abort:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_sync_read(struct bio *bio, int error)
|
static void end_sync_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct r1bio *r1_bio = bio->bi_private;
|
struct r1bio *r1_bio = bio->bi_private;
|
||||||
|
|
||||||
|
@ -1745,16 +1745,16 @@ static void end_sync_read(struct bio *bio, int error)
|
||||||
* or re-read if the read failed.
|
* or re-read if the read failed.
|
||||||
* We don't do much here, just schedule handling by raid1d
|
* We don't do much here, just schedule handling by raid1d
|
||||||
*/
|
*/
|
||||||
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
|
if (!bio->bi_error)
|
||||||
set_bit(R1BIO_Uptodate, &r1_bio->state);
|
set_bit(R1BIO_Uptodate, &r1_bio->state);
|
||||||
|
|
||||||
if (atomic_dec_and_test(&r1_bio->remaining))
|
if (atomic_dec_and_test(&r1_bio->remaining))
|
||||||
reschedule_retry(r1_bio);
|
reschedule_retry(r1_bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_sync_write(struct bio *bio, int error)
|
static void end_sync_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
int uptodate = !bio->bi_error;
|
||||||
struct r1bio *r1_bio = bio->bi_private;
|
struct r1bio *r1_bio = bio->bi_private;
|
||||||
struct mddev *mddev = r1_bio->mddev;
|
struct mddev *mddev = r1_bio->mddev;
|
||||||
struct r1conf *conf = mddev->private;
|
struct r1conf *conf = mddev->private;
|
||||||
|
@ -1941,7 +1941,7 @@ static int fix_sync_read_error(struct r1bio *r1_bio)
|
||||||
idx ++;
|
idx ++;
|
||||||
}
|
}
|
||||||
set_bit(R1BIO_Uptodate, &r1_bio->state);
|
set_bit(R1BIO_Uptodate, &r1_bio->state);
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1965,15 +1965,14 @@ static void process_checks(struct r1bio *r1_bio)
|
||||||
for (i = 0; i < conf->raid_disks * 2; i++) {
|
for (i = 0; i < conf->raid_disks * 2; i++) {
|
||||||
int j;
|
int j;
|
||||||
int size;
|
int size;
|
||||||
int uptodate;
|
int error;
|
||||||
struct bio *b = r1_bio->bios[i];
|
struct bio *b = r1_bio->bios[i];
|
||||||
if (b->bi_end_io != end_sync_read)
|
if (b->bi_end_io != end_sync_read)
|
||||||
continue;
|
continue;
|
||||||
/* fixup the bio for reuse, but preserve BIO_UPTODATE */
|
/* fixup the bio for reuse, but preserve errno */
|
||||||
uptodate = test_bit(BIO_UPTODATE, &b->bi_flags);
|
error = b->bi_error;
|
||||||
bio_reset(b);
|
bio_reset(b);
|
||||||
if (!uptodate)
|
b->bi_error = error;
|
||||||
clear_bit(BIO_UPTODATE, &b->bi_flags);
|
|
||||||
b->bi_vcnt = vcnt;
|
b->bi_vcnt = vcnt;
|
||||||
b->bi_iter.bi_size = r1_bio->sectors << 9;
|
b->bi_iter.bi_size = r1_bio->sectors << 9;
|
||||||
b->bi_iter.bi_sector = r1_bio->sector +
|
b->bi_iter.bi_sector = r1_bio->sector +
|
||||||
|
@ -1996,7 +1995,7 @@ static void process_checks(struct r1bio *r1_bio)
|
||||||
}
|
}
|
||||||
for (primary = 0; primary < conf->raid_disks * 2; primary++)
|
for (primary = 0; primary < conf->raid_disks * 2; primary++)
|
||||||
if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
|
if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
|
||||||
test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
|
!r1_bio->bios[primary]->bi_error) {
|
||||||
r1_bio->bios[primary]->bi_end_io = NULL;
|
r1_bio->bios[primary]->bi_end_io = NULL;
|
||||||
rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
|
rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
|
||||||
break;
|
break;
|
||||||
|
@ -2006,14 +2005,14 @@ static void process_checks(struct r1bio *r1_bio)
|
||||||
int j;
|
int j;
|
||||||
struct bio *pbio = r1_bio->bios[primary];
|
struct bio *pbio = r1_bio->bios[primary];
|
||||||
struct bio *sbio = r1_bio->bios[i];
|
struct bio *sbio = r1_bio->bios[i];
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &sbio->bi_flags);
|
int error = sbio->bi_error;
|
||||||
|
|
||||||
if (sbio->bi_end_io != end_sync_read)
|
if (sbio->bi_end_io != end_sync_read)
|
||||||
continue;
|
continue;
|
||||||
/* Now we can 'fixup' the BIO_UPTODATE flag */
|
/* Now we can 'fixup' the error value */
|
||||||
set_bit(BIO_UPTODATE, &sbio->bi_flags);
|
sbio->bi_error = 0;
|
||||||
|
|
||||||
if (uptodate) {
|
if (!error) {
|
||||||
for (j = vcnt; j-- ; ) {
|
for (j = vcnt; j-- ; ) {
|
||||||
struct page *p, *s;
|
struct page *p, *s;
|
||||||
p = pbio->bi_io_vec[j].bv_page;
|
p = pbio->bi_io_vec[j].bv_page;
|
||||||
|
@ -2028,7 +2027,7 @@ static void process_checks(struct r1bio *r1_bio)
|
||||||
if (j >= 0)
|
if (j >= 0)
|
||||||
atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
|
atomic64_add(r1_bio->sectors, &mddev->resync_mismatches);
|
||||||
if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
|
if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
|
||||||
&& uptodate)) {
|
&& !error)) {
|
||||||
/* No need to write to this device. */
|
/* No need to write to this device. */
|
||||||
sbio->bi_end_io = NULL;
|
sbio->bi_end_io = NULL;
|
||||||
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
|
rdev_dec_pending(conf->mirrors[i].rdev, mddev);
|
||||||
|
@ -2269,11 +2268,11 @@ static void handle_sync_write_finished(struct r1conf *conf, struct r1bio *r1_bio
|
||||||
struct bio *bio = r1_bio->bios[m];
|
struct bio *bio = r1_bio->bios[m];
|
||||||
if (bio->bi_end_io == NULL)
|
if (bio->bi_end_io == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (test_bit(BIO_UPTODATE, &bio->bi_flags) &&
|
if (!bio->bi_error &&
|
||||||
test_bit(R1BIO_MadeGood, &r1_bio->state)) {
|
test_bit(R1BIO_MadeGood, &r1_bio->state)) {
|
||||||
rdev_clear_badblocks(rdev, r1_bio->sector, s, 0);
|
rdev_clear_badblocks(rdev, r1_bio->sector, s, 0);
|
||||||
}
|
}
|
||||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags) &&
|
if (bio->bi_error &&
|
||||||
test_bit(R1BIO_WriteError, &r1_bio->state)) {
|
test_bit(R1BIO_WriteError, &r1_bio->state)) {
|
||||||
if (!rdev_set_badblocks(rdev, r1_bio->sector, s, 0))
|
if (!rdev_set_badblocks(rdev, r1_bio->sector, s, 0))
|
||||||
md_error(conf->mddev, rdev);
|
md_error(conf->mddev, rdev);
|
||||||
|
|
|
@ -101,7 +101,7 @@ static int _enough(struct r10conf *conf, int previous, int ignore);
|
||||||
static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
|
static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
int *skipped);
|
int *skipped);
|
||||||
static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio);
|
static void reshape_request_write(struct mddev *mddev, struct r10bio *r10_bio);
|
||||||
static void end_reshape_write(struct bio *bio, int error);
|
static void end_reshape_write(struct bio *bio);
|
||||||
static void end_reshape(struct r10conf *conf);
|
static void end_reshape(struct r10conf *conf);
|
||||||
|
|
||||||
static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
|
static void * r10bio_pool_alloc(gfp_t gfp_flags, void *data)
|
||||||
|
@ -307,9 +307,9 @@ static void raid_end_bio_io(struct r10bio *r10_bio)
|
||||||
} else
|
} else
|
||||||
done = 1;
|
done = 1;
|
||||||
if (!test_bit(R10BIO_Uptodate, &r10_bio->state))
|
if (!test_bit(R10BIO_Uptodate, &r10_bio->state))
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
if (done) {
|
if (done) {
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
/*
|
/*
|
||||||
* Wake up any possible resync thread that waits for the device
|
* Wake up any possible resync thread that waits for the device
|
||||||
* to go idle.
|
* to go idle.
|
||||||
|
@ -358,9 +358,9 @@ static int find_bio_disk(struct r10conf *conf, struct r10bio *r10_bio,
|
||||||
return r10_bio->devs[slot].devnum;
|
return r10_bio->devs[slot].devnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid10_end_read_request(struct bio *bio, int error)
|
static void raid10_end_read_request(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
int uptodate = !bio->bi_error;
|
||||||
struct r10bio *r10_bio = bio->bi_private;
|
struct r10bio *r10_bio = bio->bi_private;
|
||||||
int slot, dev;
|
int slot, dev;
|
||||||
struct md_rdev *rdev;
|
struct md_rdev *rdev;
|
||||||
|
@ -438,9 +438,8 @@ static void one_write_done(struct r10bio *r10_bio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid10_end_write_request(struct bio *bio, int error)
|
static void raid10_end_write_request(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct r10bio *r10_bio = bio->bi_private;
|
struct r10bio *r10_bio = bio->bi_private;
|
||||||
int dev;
|
int dev;
|
||||||
int dec_rdev = 1;
|
int dec_rdev = 1;
|
||||||
|
@ -460,7 +459,7 @@ static void raid10_end_write_request(struct bio *bio, int error)
|
||||||
/*
|
/*
|
||||||
* this branch is our 'one mirror IO has finished' event handler:
|
* this branch is our 'one mirror IO has finished' event handler:
|
||||||
*/
|
*/
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
if (repl)
|
if (repl)
|
||||||
/* Never record new bad blocks to replacement,
|
/* Never record new bad blocks to replacement,
|
||||||
* just fail it.
|
* just fail it.
|
||||||
|
@ -957,7 +956,7 @@ static void flush_pending_writes(struct r10conf *conf)
|
||||||
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
bio = next;
|
bio = next;
|
||||||
|
@ -1133,7 +1132,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule)
|
||||||
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
if (unlikely((bio->bi_rw & REQ_DISCARD) &&
|
||||||
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
!blk_queue_discard(bdev_get_queue(bio->bi_bdev))))
|
||||||
/* Just ignore it */
|
/* Just ignore it */
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
else
|
else
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
bio = next;
|
bio = next;
|
||||||
|
@ -1916,7 +1915,7 @@ abort:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_sync_read(struct bio *bio, int error)
|
static void end_sync_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct r10bio *r10_bio = bio->bi_private;
|
struct r10bio *r10_bio = bio->bi_private;
|
||||||
struct r10conf *conf = r10_bio->mddev->private;
|
struct r10conf *conf = r10_bio->mddev->private;
|
||||||
|
@ -1928,7 +1927,7 @@ static void end_sync_read(struct bio *bio, int error)
|
||||||
} else
|
} else
|
||||||
d = find_bio_disk(conf, r10_bio, bio, NULL, NULL);
|
d = find_bio_disk(conf, r10_bio, bio, NULL, NULL);
|
||||||
|
|
||||||
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
|
if (!bio->bi_error)
|
||||||
set_bit(R10BIO_Uptodate, &r10_bio->state);
|
set_bit(R10BIO_Uptodate, &r10_bio->state);
|
||||||
else
|
else
|
||||||
/* The write handler will notice the lack of
|
/* The write handler will notice the lack of
|
||||||
|
@ -1977,9 +1976,8 @@ static void end_sync_request(struct r10bio *r10_bio)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_sync_write(struct bio *bio, int error)
|
static void end_sync_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct r10bio *r10_bio = bio->bi_private;
|
struct r10bio *r10_bio = bio->bi_private;
|
||||||
struct mddev *mddev = r10_bio->mddev;
|
struct mddev *mddev = r10_bio->mddev;
|
||||||
struct r10conf *conf = mddev->private;
|
struct r10conf *conf = mddev->private;
|
||||||
|
@ -1996,7 +1994,7 @@ static void end_sync_write(struct bio *bio, int error)
|
||||||
else
|
else
|
||||||
rdev = conf->mirrors[d].rdev;
|
rdev = conf->mirrors[d].rdev;
|
||||||
|
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
if (repl)
|
if (repl)
|
||||||
md_error(mddev, rdev);
|
md_error(mddev, rdev);
|
||||||
else {
|
else {
|
||||||
|
@ -2044,7 +2042,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
|
|
||||||
/* find the first device with a block */
|
/* find the first device with a block */
|
||||||
for (i=0; i<conf->copies; i++)
|
for (i=0; i<conf->copies; i++)
|
||||||
if (test_bit(BIO_UPTODATE, &r10_bio->devs[i].bio->bi_flags))
|
if (!r10_bio->devs[i].bio->bi_error)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (i == conf->copies)
|
if (i == conf->copies)
|
||||||
|
@ -2064,7 +2062,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
|
||||||
continue;
|
continue;
|
||||||
if (i == first)
|
if (i == first)
|
||||||
continue;
|
continue;
|
||||||
if (test_bit(BIO_UPTODATE, &r10_bio->devs[i].bio->bi_flags)) {
|
if (!r10_bio->devs[i].bio->bi_error) {
|
||||||
/* We know that the bi_io_vec layout is the same for
|
/* We know that the bi_io_vec layout is the same for
|
||||||
* both 'first' and 'i', so we just compare them.
|
* both 'first' and 'i', so we just compare them.
|
||||||
* All vec entries are PAGE_SIZE;
|
* All vec entries are PAGE_SIZE;
|
||||||
|
@ -2706,8 +2704,7 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
|
||||||
rdev = conf->mirrors[dev].rdev;
|
rdev = conf->mirrors[dev].rdev;
|
||||||
if (r10_bio->devs[m].bio == NULL)
|
if (r10_bio->devs[m].bio == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (test_bit(BIO_UPTODATE,
|
if (!r10_bio->devs[m].bio->bi_error) {
|
||||||
&r10_bio->devs[m].bio->bi_flags)) {
|
|
||||||
rdev_clear_badblocks(
|
rdev_clear_badblocks(
|
||||||
rdev,
|
rdev,
|
||||||
r10_bio->devs[m].addr,
|
r10_bio->devs[m].addr,
|
||||||
|
@ -2722,8 +2719,8 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
|
||||||
rdev = conf->mirrors[dev].replacement;
|
rdev = conf->mirrors[dev].replacement;
|
||||||
if (r10_bio->devs[m].repl_bio == NULL)
|
if (r10_bio->devs[m].repl_bio == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (test_bit(BIO_UPTODATE,
|
|
||||||
&r10_bio->devs[m].repl_bio->bi_flags)) {
|
if (!r10_bio->devs[m].repl_bio->bi_error) {
|
||||||
rdev_clear_badblocks(
|
rdev_clear_badblocks(
|
||||||
rdev,
|
rdev,
|
||||||
r10_bio->devs[m].addr,
|
r10_bio->devs[m].addr,
|
||||||
|
@ -2748,8 +2745,7 @@ static void handle_write_completed(struct r10conf *conf, struct r10bio *r10_bio)
|
||||||
r10_bio->devs[m].addr,
|
r10_bio->devs[m].addr,
|
||||||
r10_bio->sectors, 0);
|
r10_bio->sectors, 0);
|
||||||
rdev_dec_pending(rdev, conf->mddev);
|
rdev_dec_pending(rdev, conf->mddev);
|
||||||
} else if (bio != NULL &&
|
} else if (bio != NULL && bio->bi_error) {
|
||||||
!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
|
|
||||||
if (!narrow_write_error(r10_bio, m)) {
|
if (!narrow_write_error(r10_bio, m)) {
|
||||||
md_error(conf->mddev, rdev);
|
md_error(conf->mddev, rdev);
|
||||||
set_bit(R10BIO_Degraded,
|
set_bit(R10BIO_Degraded,
|
||||||
|
@ -3263,7 +3259,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
|
|
||||||
bio = r10_bio->devs[i].bio;
|
bio = r10_bio->devs[i].bio;
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
if (conf->mirrors[d].rdev == NULL ||
|
if (conf->mirrors[d].rdev == NULL ||
|
||||||
test_bit(Faulty, &conf->mirrors[d].rdev->flags))
|
test_bit(Faulty, &conf->mirrors[d].rdev->flags))
|
||||||
continue;
|
continue;
|
||||||
|
@ -3300,7 +3296,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
/* Need to set up for writing to the replacement */
|
/* Need to set up for writing to the replacement */
|
||||||
bio = r10_bio->devs[i].repl_bio;
|
bio = r10_bio->devs[i].repl_bio;
|
||||||
bio_reset(bio);
|
bio_reset(bio);
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = -EIO;
|
||||||
|
|
||||||
sector = r10_bio->devs[i].addr;
|
sector = r10_bio->devs[i].addr;
|
||||||
atomic_inc(&conf->mirrors[d].rdev->nr_pending);
|
atomic_inc(&conf->mirrors[d].rdev->nr_pending);
|
||||||
|
@ -3377,7 +3373,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
|
||||||
|
|
||||||
if (bio->bi_end_io == end_sync_read) {
|
if (bio->bi_end_io == end_sync_read) {
|
||||||
md_sync_acct(bio->bi_bdev, nr_sectors);
|
md_sync_acct(bio->bi_bdev, nr_sectors);
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = 0;
|
||||||
generic_make_request(bio);
|
generic_make_request(bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4380,7 +4376,7 @@ read_more:
|
||||||
read_bio->bi_end_io = end_sync_read;
|
read_bio->bi_end_io = end_sync_read;
|
||||||
read_bio->bi_rw = READ;
|
read_bio->bi_rw = READ;
|
||||||
read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
|
read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
|
||||||
__set_bit(BIO_UPTODATE, &read_bio->bi_flags);
|
read_bio->bi_error = 0;
|
||||||
read_bio->bi_vcnt = 0;
|
read_bio->bi_vcnt = 0;
|
||||||
read_bio->bi_iter.bi_size = 0;
|
read_bio->bi_iter.bi_size = 0;
|
||||||
r10_bio->master_bio = read_bio;
|
r10_bio->master_bio = read_bio;
|
||||||
|
@ -4601,9 +4597,8 @@ static int handle_reshape_read_error(struct mddev *mddev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_reshape_write(struct bio *bio, int error)
|
static void end_reshape_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct r10bio *r10_bio = bio->bi_private;
|
struct r10bio *r10_bio = bio->bi_private;
|
||||||
struct mddev *mddev = r10_bio->mddev;
|
struct mddev *mddev = r10_bio->mddev;
|
||||||
struct r10conf *conf = mddev->private;
|
struct r10conf *conf = mddev->private;
|
||||||
|
@ -4620,7 +4615,7 @@ static void end_reshape_write(struct bio *bio, int error)
|
||||||
rdev = conf->mirrors[d].rdev;
|
rdev = conf->mirrors[d].rdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
/* FIXME should record badblock */
|
/* FIXME should record badblock */
|
||||||
md_error(mddev, rdev);
|
md_error(mddev, rdev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,7 +233,7 @@ static void return_io(struct bio *return_bi)
|
||||||
bi->bi_iter.bi_size = 0;
|
bi->bi_iter.bi_size = 0;
|
||||||
trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
|
trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
|
||||||
bi, 0);
|
bi, 0);
|
||||||
bio_endio(bi, 0);
|
bio_endio(bi);
|
||||||
bi = return_bi;
|
bi = return_bi;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,9 +887,9 @@ static int use_new_offset(struct r5conf *conf, struct stripe_head *sh)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
raid5_end_read_request(struct bio *bi, int error);
|
raid5_end_read_request(struct bio *bi);
|
||||||
static void
|
static void
|
||||||
raid5_end_write_request(struct bio *bi, int error);
|
raid5_end_write_request(struct bio *bi);
|
||||||
|
|
||||||
static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
|
static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
|
||||||
{
|
{
|
||||||
|
@ -2277,12 +2277,11 @@ static void shrink_stripes(struct r5conf *conf)
|
||||||
conf->slab_cache = NULL;
|
conf->slab_cache = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid5_end_read_request(struct bio * bi, int error)
|
static void raid5_end_read_request(struct bio * bi)
|
||||||
{
|
{
|
||||||
struct stripe_head *sh = bi->bi_private;
|
struct stripe_head *sh = bi->bi_private;
|
||||||
struct r5conf *conf = sh->raid_conf;
|
struct r5conf *conf = sh->raid_conf;
|
||||||
int disks = sh->disks, i;
|
int disks = sh->disks, i;
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
char b[BDEVNAME_SIZE];
|
char b[BDEVNAME_SIZE];
|
||||||
struct md_rdev *rdev = NULL;
|
struct md_rdev *rdev = NULL;
|
||||||
sector_t s;
|
sector_t s;
|
||||||
|
@ -2291,9 +2290,9 @@ static void raid5_end_read_request(struct bio * bi, int error)
|
||||||
if (bi == &sh->dev[i].req)
|
if (bi == &sh->dev[i].req)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pr_debug("end_read_request %llu/%d, count: %d, uptodate %d.\n",
|
pr_debug("end_read_request %llu/%d, count: %d, error %d.\n",
|
||||||
(unsigned long long)sh->sector, i, atomic_read(&sh->count),
|
(unsigned long long)sh->sector, i, atomic_read(&sh->count),
|
||||||
uptodate);
|
bi->bi_error);
|
||||||
if (i == disks) {
|
if (i == disks) {
|
||||||
BUG();
|
BUG();
|
||||||
return;
|
return;
|
||||||
|
@ -2312,7 +2311,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
|
||||||
s = sh->sector + rdev->new_data_offset;
|
s = sh->sector + rdev->new_data_offset;
|
||||||
else
|
else
|
||||||
s = sh->sector + rdev->data_offset;
|
s = sh->sector + rdev->data_offset;
|
||||||
if (uptodate) {
|
if (!bi->bi_error) {
|
||||||
set_bit(R5_UPTODATE, &sh->dev[i].flags);
|
set_bit(R5_UPTODATE, &sh->dev[i].flags);
|
||||||
if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
|
if (test_bit(R5_ReadError, &sh->dev[i].flags)) {
|
||||||
/* Note that this cannot happen on a
|
/* Note that this cannot happen on a
|
||||||
|
@ -2400,13 +2399,12 @@ static void raid5_end_read_request(struct bio * bi, int error)
|
||||||
release_stripe(sh);
|
release_stripe(sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void raid5_end_write_request(struct bio *bi, int error)
|
static void raid5_end_write_request(struct bio *bi)
|
||||||
{
|
{
|
||||||
struct stripe_head *sh = bi->bi_private;
|
struct stripe_head *sh = bi->bi_private;
|
||||||
struct r5conf *conf = sh->raid_conf;
|
struct r5conf *conf = sh->raid_conf;
|
||||||
int disks = sh->disks, i;
|
int disks = sh->disks, i;
|
||||||
struct md_rdev *uninitialized_var(rdev);
|
struct md_rdev *uninitialized_var(rdev);
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
sector_t first_bad;
|
sector_t first_bad;
|
||||||
int bad_sectors;
|
int bad_sectors;
|
||||||
int replacement = 0;
|
int replacement = 0;
|
||||||
|
@ -2429,23 +2427,23 @@ static void raid5_end_write_request(struct bio *bi, int error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pr_debug("end_write_request %llu/%d, count %d, uptodate: %d.\n",
|
pr_debug("end_write_request %llu/%d, count %d, error: %d.\n",
|
||||||
(unsigned long long)sh->sector, i, atomic_read(&sh->count),
|
(unsigned long long)sh->sector, i, atomic_read(&sh->count),
|
||||||
uptodate);
|
bi->bi_error);
|
||||||
if (i == disks) {
|
if (i == disks) {
|
||||||
BUG();
|
BUG();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (replacement) {
|
if (replacement) {
|
||||||
if (!uptodate)
|
if (bi->bi_error)
|
||||||
md_error(conf->mddev, rdev);
|
md_error(conf->mddev, rdev);
|
||||||
else if (is_badblock(rdev, sh->sector,
|
else if (is_badblock(rdev, sh->sector,
|
||||||
STRIPE_SECTORS,
|
STRIPE_SECTORS,
|
||||||
&first_bad, &bad_sectors))
|
&first_bad, &bad_sectors))
|
||||||
set_bit(R5_MadeGoodRepl, &sh->dev[i].flags);
|
set_bit(R5_MadeGoodRepl, &sh->dev[i].flags);
|
||||||
} else {
|
} else {
|
||||||
if (!uptodate) {
|
if (bi->bi_error) {
|
||||||
set_bit(STRIPE_DEGRADED, &sh->state);
|
set_bit(STRIPE_DEGRADED, &sh->state);
|
||||||
set_bit(WriteErrorSeen, &rdev->flags);
|
set_bit(WriteErrorSeen, &rdev->flags);
|
||||||
set_bit(R5_WriteError, &sh->dev[i].flags);
|
set_bit(R5_WriteError, &sh->dev[i].flags);
|
||||||
|
@ -2466,7 +2464,7 @@ static void raid5_end_write_request(struct bio *bi, int error)
|
||||||
}
|
}
|
||||||
rdev_dec_pending(rdev, conf->mddev);
|
rdev_dec_pending(rdev, conf->mddev);
|
||||||
|
|
||||||
if (sh->batch_head && !uptodate && !replacement)
|
if (sh->batch_head && bi->bi_error && !replacement)
|
||||||
set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state);
|
set_bit(STRIPE_BATCH_ERR, &sh->batch_head->state);
|
||||||
|
|
||||||
if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags))
|
if (!test_and_clear_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags))
|
||||||
|
@ -3107,7 +3105,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
|
||||||
while (bi && bi->bi_iter.bi_sector <
|
while (bi && bi->bi_iter.bi_sector <
|
||||||
sh->dev[i].sector + STRIPE_SECTORS) {
|
sh->dev[i].sector + STRIPE_SECTORS) {
|
||||||
struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
|
struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
|
||||||
clear_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
|
bi->bi_error = -EIO;
|
||||||
if (!raid5_dec_bi_active_stripes(bi)) {
|
if (!raid5_dec_bi_active_stripes(bi)) {
|
||||||
md_write_end(conf->mddev);
|
md_write_end(conf->mddev);
|
||||||
bi->bi_next = *return_bi;
|
bi->bi_next = *return_bi;
|
||||||
|
@ -3131,7 +3130,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
|
||||||
while (bi && bi->bi_iter.bi_sector <
|
while (bi && bi->bi_iter.bi_sector <
|
||||||
sh->dev[i].sector + STRIPE_SECTORS) {
|
sh->dev[i].sector + STRIPE_SECTORS) {
|
||||||
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
|
struct bio *bi2 = r5_next_bio(bi, sh->dev[i].sector);
|
||||||
clear_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
|
bi->bi_error = -EIO;
|
||||||
if (!raid5_dec_bi_active_stripes(bi)) {
|
if (!raid5_dec_bi_active_stripes(bi)) {
|
||||||
md_write_end(conf->mddev);
|
md_write_end(conf->mddev);
|
||||||
bi->bi_next = *return_bi;
|
bi->bi_next = *return_bi;
|
||||||
|
@ -3156,7 +3156,8 @@ handle_failed_stripe(struct r5conf *conf, struct stripe_head *sh,
|
||||||
sh->dev[i].sector + STRIPE_SECTORS) {
|
sh->dev[i].sector + STRIPE_SECTORS) {
|
||||||
struct bio *nextbi =
|
struct bio *nextbi =
|
||||||
r5_next_bio(bi, sh->dev[i].sector);
|
r5_next_bio(bi, sh->dev[i].sector);
|
||||||
clear_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
|
bi->bi_error = -EIO;
|
||||||
if (!raid5_dec_bi_active_stripes(bi)) {
|
if (!raid5_dec_bi_active_stripes(bi)) {
|
||||||
bi->bi_next = *return_bi;
|
bi->bi_next = *return_bi;
|
||||||
*return_bi = bi;
|
*return_bi = bi;
|
||||||
|
@ -4749,12 +4750,11 @@ static struct bio *remove_bio_from_retry(struct r5conf *conf)
|
||||||
* first).
|
* first).
|
||||||
* If the read failed..
|
* If the read failed..
|
||||||
*/
|
*/
|
||||||
static void raid5_align_endio(struct bio *bi, int error)
|
static void raid5_align_endio(struct bio *bi)
|
||||||
{
|
{
|
||||||
struct bio* raid_bi = bi->bi_private;
|
struct bio* raid_bi = bi->bi_private;
|
||||||
struct mddev *mddev;
|
struct mddev *mddev;
|
||||||
struct r5conf *conf;
|
struct r5conf *conf;
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
|
|
||||||
struct md_rdev *rdev;
|
struct md_rdev *rdev;
|
||||||
|
|
||||||
bio_put(bi);
|
bio_put(bi);
|
||||||
|
@ -4766,10 +4766,10 @@ static void raid5_align_endio(struct bio *bi, int error)
|
||||||
|
|
||||||
rdev_dec_pending(rdev, conf->mddev);
|
rdev_dec_pending(rdev, conf->mddev);
|
||||||
|
|
||||||
if (!error && uptodate) {
|
if (!bi->bi_error) {
|
||||||
trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev),
|
trace_block_bio_complete(bdev_get_queue(raid_bi->bi_bdev),
|
||||||
raid_bi, 0);
|
raid_bi, 0);
|
||||||
bio_endio(raid_bi, 0);
|
bio_endio(raid_bi);
|
||||||
if (atomic_dec_and_test(&conf->active_aligned_reads))
|
if (atomic_dec_and_test(&conf->active_aligned_reads))
|
||||||
wake_up(&conf->wait_for_quiescent);
|
wake_up(&conf->wait_for_quiescent);
|
||||||
return;
|
return;
|
||||||
|
@ -5133,7 +5133,7 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi)
|
||||||
remaining = raid5_dec_bi_active_stripes(bi);
|
remaining = raid5_dec_bi_active_stripes(bi);
|
||||||
if (remaining == 0) {
|
if (remaining == 0) {
|
||||||
md_write_end(mddev);
|
md_write_end(mddev);
|
||||||
bio_endio(bi, 0);
|
bio_endio(bi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5297,7 +5297,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
|
||||||
release_stripe_plug(mddev, sh);
|
release_stripe_plug(mddev, sh);
|
||||||
} else {
|
} else {
|
||||||
/* cannot get stripe for read-ahead, just give-up */
|
/* cannot get stripe for read-ahead, just give-up */
|
||||||
clear_bit(BIO_UPTODATE, &bi->bi_flags);
|
bi->bi_error = -EIO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5311,7 +5311,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
|
||||||
|
|
||||||
trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
|
trace_block_bio_complete(bdev_get_queue(bi->bi_bdev),
|
||||||
bi, 0);
|
bi, 0);
|
||||||
bio_endio(bi, 0);
|
bio_endio(bi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5707,7 +5707,7 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio)
|
||||||
if (remaining == 0) {
|
if (remaining == 0) {
|
||||||
trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev),
|
trace_block_bio_complete(bdev_get_queue(raid_bio->bi_bdev),
|
||||||
raid_bio, 0);
|
raid_bio, 0);
|
||||||
bio_endio(raid_bio, 0);
|
bio_endio(raid_bio);
|
||||||
}
|
}
|
||||||
if (atomic_dec_and_test(&conf->active_aligned_reads))
|
if (atomic_dec_and_test(&conf->active_aligned_reads))
|
||||||
wake_up(&conf->wait_for_quiescent);
|
wake_up(&conf->wait_for_quiescent);
|
||||||
|
|
|
@ -180,7 +180,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
|
||||||
* another kernel subsystem, and we just pass it through.
|
* another kernel subsystem, and we just pass it through.
|
||||||
*/
|
*/
|
||||||
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
||||||
err = -EIO;
|
bio->bi_error = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,6 +199,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
|
||||||
"io error in %s sector %lld, len %d,\n",
|
"io error in %s sector %lld, len %d,\n",
|
||||||
(rw == READ) ? "READ" : "WRITE",
|
(rw == READ) ? "READ" : "WRITE",
|
||||||
(unsigned long long) iter.bi_sector, len);
|
(unsigned long long) iter.bi_sector, len);
|
||||||
|
bio->bi_error = err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +207,7 @@ static void nd_blk_make_request(struct request_queue *q, struct bio *bio)
|
||||||
nd_iostat_end(bio, start);
|
nd_iostat_end(bio, start);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bio_endio(bio, err);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nd_blk_rw_bytes(struct nd_namespace_common *ndns,
|
static int nd_blk_rw_bytes(struct nd_namespace_common *ndns,
|
||||||
|
|
|
@ -1189,7 +1189,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
|
||||||
* another kernel subsystem, and we just pass it through.
|
* another kernel subsystem, and we just pass it through.
|
||||||
*/
|
*/
|
||||||
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
if (bio_integrity_enabled(bio) && bio_integrity_prep(bio)) {
|
||||||
err = -EIO;
|
bio->bi_error = -EIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,6 +1211,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
|
||||||
"io error in %s sector %lld, len %d,\n",
|
"io error in %s sector %lld, len %d,\n",
|
||||||
(rw == READ) ? "READ" : "WRITE",
|
(rw == READ) ? "READ" : "WRITE",
|
||||||
(unsigned long long) iter.bi_sector, len);
|
(unsigned long long) iter.bi_sector, len);
|
||||||
|
bio->bi_error = err;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1218,7 +1219,7 @@ static void btt_make_request(struct request_queue *q, struct bio *bio)
|
||||||
nd_iostat_end(bio, start);
|
nd_iostat_end(bio, start);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
bio_endio(bio, err);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int btt_rw_page(struct block_device *bdev, sector_t sector,
|
static int btt_rw_page(struct block_device *bdev, sector_t sector,
|
||||||
|
|
|
@ -77,7 +77,7 @@ static void pmem_make_request(struct request_queue *q, struct bio *bio)
|
||||||
if (bio_data_dir(bio))
|
if (bio_data_dir(bio))
|
||||||
wmb_pmem();
|
wmb_pmem();
|
||||||
|
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pmem_rw_page(struct block_device *bdev, sector_t sector,
|
static int pmem_rw_page(struct block_device *bdev, sector_t sector,
|
||||||
|
|
|
@ -871,7 +871,7 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio)
|
||||||
}
|
}
|
||||||
bytes_done += bvec.bv_len;
|
bytes_done += bvec.bv_len;
|
||||||
}
|
}
|
||||||
bio_endio(bio, 0);
|
bio_endio(bio);
|
||||||
return;
|
return;
|
||||||
fail:
|
fail:
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
|
|
|
@ -220,8 +220,7 @@ static void xpram_make_request(struct request_queue *q, struct bio *bio)
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio_endio(bio);
|
||||||
bio_endio(bio, 0);
|
|
||||||
return;
|
return;
|
||||||
fail:
|
fail:
|
||||||
bio_io_error(bio);
|
bio_io_error(bio);
|
||||||
|
|
|
@ -306,20 +306,13 @@ static void iblock_complete_cmd(struct se_cmd *cmd)
|
||||||
kfree(ibr);
|
kfree(ibr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iblock_bio_done(struct bio *bio, int err)
|
static void iblock_bio_done(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct se_cmd *cmd = bio->bi_private;
|
struct se_cmd *cmd = bio->bi_private;
|
||||||
struct iblock_req *ibr = cmd->priv;
|
struct iblock_req *ibr = cmd->priv;
|
||||||
|
|
||||||
/*
|
if (bio->bi_error) {
|
||||||
* Set -EIO if !BIO_UPTODATE and the passed is still err=0
|
pr_err("bio error: %p, err: %d\n", bio, bio->bi_error);
|
||||||
*/
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags) && !err)
|
|
||||||
err = -EIO;
|
|
||||||
|
|
||||||
if (err != 0) {
|
|
||||||
pr_err("test_bit(BIO_UPTODATE) failed for bio: %p,"
|
|
||||||
" err: %d\n", bio, err);
|
|
||||||
/*
|
/*
|
||||||
* Bump the ib_bio_err_cnt and release bio.
|
* Bump the ib_bio_err_cnt and release bio.
|
||||||
*/
|
*/
|
||||||
|
@ -370,15 +363,15 @@ static void iblock_submit_bios(struct bio_list *list, int rw)
|
||||||
blk_finish_plug(&plug);
|
blk_finish_plug(&plug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iblock_end_io_flush(struct bio *bio, int err)
|
static void iblock_end_io_flush(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct se_cmd *cmd = bio->bi_private;
|
struct se_cmd *cmd = bio->bi_private;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
pr_err("IBLOCK: cache flush failed: %d\n", err);
|
pr_err("IBLOCK: cache flush failed: %d\n", bio->bi_error);
|
||||||
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
|
target_complete_cmd(cmd, SAM_STAT_CHECK_CONDITION);
|
||||||
else
|
else
|
||||||
target_complete_cmd(cmd, SAM_STAT_GOOD);
|
target_complete_cmd(cmd, SAM_STAT_GOOD);
|
||||||
|
|
|
@ -852,7 +852,7 @@ static ssize_t pscsi_show_configfs_dev_params(struct se_device *dev, char *b)
|
||||||
return bl;
|
return bl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pscsi_bi_endio(struct bio *bio, int error)
|
static void pscsi_bi_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
@ -973,7 +973,7 @@ fail:
|
||||||
while (*hbio) {
|
while (*hbio) {
|
||||||
bio = *hbio;
|
bio = *hbio;
|
||||||
*hbio = (*hbio)->bi_next;
|
*hbio = (*hbio)->bi_next;
|
||||||
bio_endio(bio, 0); /* XXX: should be error */
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -1061,7 +1061,7 @@ fail_free_bio:
|
||||||
while (hbio) {
|
while (hbio) {
|
||||||
struct bio *bio = hbio;
|
struct bio *bio = hbio;
|
||||||
hbio = hbio->bi_next;
|
hbio = hbio->bi_next;
|
||||||
bio_endio(bio, 0); /* XXX: should be error */
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
ret = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
|
||||||
fail:
|
fail:
|
||||||
|
|
|
@ -343,7 +343,7 @@ static int btrfsic_process_written_superblock(
|
||||||
struct btrfsic_state *state,
|
struct btrfsic_state *state,
|
||||||
struct btrfsic_block *const block,
|
struct btrfsic_block *const block,
|
||||||
struct btrfs_super_block *const super_hdr);
|
struct btrfs_super_block *const super_hdr);
|
||||||
static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status);
|
static void btrfsic_bio_end_io(struct bio *bp);
|
||||||
static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate);
|
static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate);
|
||||||
static int btrfsic_is_block_ref_by_superblock(const struct btrfsic_state *state,
|
static int btrfsic_is_block_ref_by_superblock(const struct btrfsic_state *state,
|
||||||
const struct btrfsic_block *block,
|
const struct btrfsic_block *block,
|
||||||
|
@ -2207,7 +2207,7 @@ continue_loop:
|
||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status)
|
static void btrfsic_bio_end_io(struct bio *bp)
|
||||||
{
|
{
|
||||||
struct btrfsic_block *block = (struct btrfsic_block *)bp->bi_private;
|
struct btrfsic_block *block = (struct btrfsic_block *)bp->bi_private;
|
||||||
int iodone_w_error;
|
int iodone_w_error;
|
||||||
|
@ -2215,7 +2215,7 @@ static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status)
|
||||||
/* mutex is not held! This is not save if IO is not yet completed
|
/* mutex is not held! This is not save if IO is not yet completed
|
||||||
* on umount */
|
* on umount */
|
||||||
iodone_w_error = 0;
|
iodone_w_error = 0;
|
||||||
if (bio_error_status)
|
if (bp->bi_error)
|
||||||
iodone_w_error = 1;
|
iodone_w_error = 1;
|
||||||
|
|
||||||
BUG_ON(NULL == block);
|
BUG_ON(NULL == block);
|
||||||
|
@ -2230,7 +2230,7 @@ static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status)
|
||||||
BTRFSIC_PRINT_MASK_END_IO_BIO_BH))
|
BTRFSIC_PRINT_MASK_END_IO_BIO_BH))
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"bio_end_io(err=%d) for %c @%llu (%s/%llu/%d)\n",
|
"bio_end_io(err=%d) for %c @%llu (%s/%llu/%d)\n",
|
||||||
bio_error_status,
|
bp->bi_error,
|
||||||
btrfsic_get_block_type(dev_state->state, block),
|
btrfsic_get_block_type(dev_state->state, block),
|
||||||
block->logical_bytenr, dev_state->name,
|
block->logical_bytenr, dev_state->name,
|
||||||
block->dev_bytenr, block->mirror_num);
|
block->dev_bytenr, block->mirror_num);
|
||||||
|
@ -2252,7 +2252,7 @@ static void btrfsic_bio_end_io(struct bio *bp, int bio_error_status)
|
||||||
block = next_block;
|
block = next_block;
|
||||||
} while (NULL != block);
|
} while (NULL != block);
|
||||||
|
|
||||||
bp->bi_end_io(bp, bio_error_status);
|
bp->bi_end_io(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate)
|
static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate)
|
||||||
|
|
|
@ -152,7 +152,7 @@ fail:
|
||||||
* The compressed pages are freed here, and it must be run
|
* The compressed pages are freed here, and it must be run
|
||||||
* in process context
|
* in process context
|
||||||
*/
|
*/
|
||||||
static void end_compressed_bio_read(struct bio *bio, int err)
|
static void end_compressed_bio_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct compressed_bio *cb = bio->bi_private;
|
struct compressed_bio *cb = bio->bi_private;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
@ -160,7 +160,7 @@ static void end_compressed_bio_read(struct bio *bio, int err)
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
cb->errors = 1;
|
cb->errors = 1;
|
||||||
|
|
||||||
/* if there are more bios still pending for this compressed
|
/* if there are more bios still pending for this compressed
|
||||||
|
@ -210,7 +210,7 @@ csum_failed:
|
||||||
bio_for_each_segment_all(bvec, cb->orig_bio, i)
|
bio_for_each_segment_all(bvec, cb->orig_bio, i)
|
||||||
SetPageChecked(bvec->bv_page);
|
SetPageChecked(bvec->bv_page);
|
||||||
|
|
||||||
bio_endio(cb->orig_bio, 0);
|
bio_endio(cb->orig_bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finally free the cb struct */
|
/* finally free the cb struct */
|
||||||
|
@ -266,7 +266,7 @@ static noinline void end_compressed_writeback(struct inode *inode,
|
||||||
* This also calls the writeback end hooks for the file pages so that
|
* This also calls the writeback end hooks for the file pages so that
|
||||||
* metadata and checksums can be updated in the file.
|
* metadata and checksums can be updated in the file.
|
||||||
*/
|
*/
|
||||||
static void end_compressed_bio_write(struct bio *bio, int err)
|
static void end_compressed_bio_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct extent_io_tree *tree;
|
struct extent_io_tree *tree;
|
||||||
struct compressed_bio *cb = bio->bi_private;
|
struct compressed_bio *cb = bio->bi_private;
|
||||||
|
@ -274,7 +274,7 @@ static void end_compressed_bio_write(struct bio *bio, int err)
|
||||||
struct page *page;
|
struct page *page;
|
||||||
unsigned long index;
|
unsigned long index;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
cb->errors = 1;
|
cb->errors = 1;
|
||||||
|
|
||||||
/* if there are more bios still pending for this compressed
|
/* if there are more bios still pending for this compressed
|
||||||
|
@ -293,7 +293,7 @@ static void end_compressed_bio_write(struct bio *bio, int err)
|
||||||
cb->start,
|
cb->start,
|
||||||
cb->start + cb->len - 1,
|
cb->start + cb->len - 1,
|
||||||
NULL,
|
NULL,
|
||||||
err ? 0 : 1);
|
bio->bi_error ? 0 : 1);
|
||||||
cb->compressed_pages[0]->mapping = NULL;
|
cb->compressed_pages[0]->mapping = NULL;
|
||||||
|
|
||||||
end_compressed_writeback(inode, cb);
|
end_compressed_writeback(inode, cb);
|
||||||
|
@ -697,8 +697,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
|
||||||
|
|
||||||
ret = btrfs_map_bio(root, READ, comp_bio,
|
ret = btrfs_map_bio(root, READ, comp_bio,
|
||||||
mirror_num, 0);
|
mirror_num, 0);
|
||||||
if (ret)
|
if (ret) {
|
||||||
bio_endio(comp_bio, ret);
|
bio->bi_error = ret;
|
||||||
|
bio_endio(comp_bio);
|
||||||
|
}
|
||||||
|
|
||||||
bio_put(comp_bio);
|
bio_put(comp_bio);
|
||||||
|
|
||||||
|
@ -724,8 +726,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0);
|
ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0);
|
||||||
if (ret)
|
if (ret) {
|
||||||
bio_endio(comp_bio, ret);
|
bio->bi_error = ret;
|
||||||
|
bio_endio(comp_bio);
|
||||||
|
}
|
||||||
|
|
||||||
bio_put(comp_bio);
|
bio_put(comp_bio);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -703,7 +703,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
|
||||||
return -EIO; /* we fixed nothing */
|
return -EIO; /* we fixed nothing */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_workqueue_bio(struct bio *bio, int err)
|
static void end_workqueue_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
|
struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
|
||||||
struct btrfs_fs_info *fs_info;
|
struct btrfs_fs_info *fs_info;
|
||||||
|
@ -711,7 +711,7 @@ static void end_workqueue_bio(struct bio *bio, int err)
|
||||||
btrfs_work_func_t func;
|
btrfs_work_func_t func;
|
||||||
|
|
||||||
fs_info = end_io_wq->info;
|
fs_info = end_io_wq->info;
|
||||||
end_io_wq->error = err;
|
end_io_wq->error = bio->bi_error;
|
||||||
|
|
||||||
if (bio->bi_rw & REQ_WRITE) {
|
if (bio->bi_rw & REQ_WRITE) {
|
||||||
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
|
if (end_io_wq->metadata == BTRFS_WQ_ENDIO_METADATA) {
|
||||||
|
@ -808,7 +808,8 @@ static void run_one_async_done(struct btrfs_work *work)
|
||||||
|
|
||||||
/* If an error occured we just want to clean up the bio and move on */
|
/* If an error occured we just want to clean up the bio and move on */
|
||||||
if (async->error) {
|
if (async->error) {
|
||||||
bio_endio(async->bio, async->error);
|
async->bio->bi_error = async->error;
|
||||||
|
bio_endio(async->bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -908,8 +909,10 @@ static int __btree_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
|
||||||
* submission context. Just jump into btrfs_map_bio
|
* submission context. Just jump into btrfs_map_bio
|
||||||
*/
|
*/
|
||||||
ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
|
ret = btrfs_map_bio(BTRFS_I(inode)->root, rw, bio, mirror_num, 1);
|
||||||
if (ret)
|
if (ret) {
|
||||||
bio_endio(bio, ret);
|
bio->bi_error = ret;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,10 +963,13 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
|
||||||
__btree_submit_bio_done);
|
__btree_submit_bio_done);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret)
|
||||||
|
goto out_w_error;
|
||||||
|
return 0;
|
||||||
|
|
||||||
out_w_error:
|
out_w_error:
|
||||||
bio_endio(bio, ret);
|
bio->bi_error = ret;
|
||||||
}
|
bio_endio(bio);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1735,16 +1741,15 @@ static void end_workqueue_fn(struct btrfs_work *work)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
struct btrfs_end_io_wq *end_io_wq;
|
struct btrfs_end_io_wq *end_io_wq;
|
||||||
int error;
|
|
||||||
|
|
||||||
end_io_wq = container_of(work, struct btrfs_end_io_wq, work);
|
end_io_wq = container_of(work, struct btrfs_end_io_wq, work);
|
||||||
bio = end_io_wq->bio;
|
bio = end_io_wq->bio;
|
||||||
|
|
||||||
error = end_io_wq->error;
|
bio->bi_error = end_io_wq->error;
|
||||||
bio->bi_private = end_io_wq->private;
|
bio->bi_private = end_io_wq->private;
|
||||||
bio->bi_end_io = end_io_wq->end_io;
|
bio->bi_end_io = end_io_wq->end_io;
|
||||||
kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
|
kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
|
||||||
bio_endio(bio, error);
|
bio_endio(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cleaner_kthread(void *arg)
|
static int cleaner_kthread(void *arg)
|
||||||
|
@ -3323,10 +3328,8 @@ static int write_dev_supers(struct btrfs_device *device,
|
||||||
* endio for the write_dev_flush, this will wake anyone waiting
|
* endio for the write_dev_flush, this will wake anyone waiting
|
||||||
* for the barrier when it is done
|
* for the barrier when it is done
|
||||||
*/
|
*/
|
||||||
static void btrfs_end_empty_barrier(struct bio *bio, int err)
|
static void btrfs_end_empty_barrier(struct bio *bio)
|
||||||
{
|
{
|
||||||
if (err)
|
|
||||||
clear_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
if (bio->bi_private)
|
if (bio->bi_private)
|
||||||
complete(bio->bi_private);
|
complete(bio->bi_private);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
@ -3354,8 +3357,8 @@ static int write_dev_flush(struct btrfs_device *device, int wait)
|
||||||
|
|
||||||
wait_for_completion(&device->flush_wait);
|
wait_for_completion(&device->flush_wait);
|
||||||
|
|
||||||
if (!bio_flagged(bio, BIO_UPTODATE)) {
|
if (bio->bi_error) {
|
||||||
ret = -EIO;
|
ret = bio->bi_error;
|
||||||
btrfs_dev_stat_inc_and_print(device,
|
btrfs_dev_stat_inc_and_print(device,
|
||||||
BTRFS_DEV_STAT_FLUSH_ERRS);
|
BTRFS_DEV_STAT_FLUSH_ERRS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2486,7 +2486,7 @@ int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
|
||||||
* Scheduling is not allowed, so the extent state tree is expected
|
* Scheduling is not allowed, so the extent state tree is expected
|
||||||
* to have one and only one object corresponding to this IO.
|
* to have one and only one object corresponding to this IO.
|
||||||
*/
|
*/
|
||||||
static void end_bio_extent_writepage(struct bio *bio, int err)
|
static void end_bio_extent_writepage(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
u64 start;
|
u64 start;
|
||||||
|
@ -2516,7 +2516,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
|
||||||
start = page_offset(page);
|
start = page_offset(page);
|
||||||
end = start + bvec->bv_offset + bvec->bv_len - 1;
|
end = start + bvec->bv_offset + bvec->bv_len - 1;
|
||||||
|
|
||||||
if (end_extent_writepage(page, err, start, end))
|
if (end_extent_writepage(page, bio->bi_error, start, end))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
end_page_writeback(page);
|
end_page_writeback(page);
|
||||||
|
@ -2548,10 +2548,10 @@ endio_readpage_release_extent(struct extent_io_tree *tree, u64 start, u64 len,
|
||||||
* Scheduling is not allowed, so the extent state tree is expected
|
* Scheduling is not allowed, so the extent state tree is expected
|
||||||
* to have one and only one object corresponding to this IO.
|
* to have one and only one object corresponding to this IO.
|
||||||
*/
|
*/
|
||||||
static void end_bio_extent_readpage(struct bio *bio, int err)
|
static void end_bio_extent_readpage(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
int uptodate = !bio->bi_error;
|
||||||
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
||||||
struct extent_io_tree *tree;
|
struct extent_io_tree *tree;
|
||||||
u64 offset = 0;
|
u64 offset = 0;
|
||||||
|
@ -2564,16 +2564,13 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (err)
|
|
||||||
uptodate = 0;
|
|
||||||
|
|
||||||
bio_for_each_segment_all(bvec, bio, i) {
|
bio_for_each_segment_all(bvec, bio, i) {
|
||||||
struct page *page = bvec->bv_page;
|
struct page *page = bvec->bv_page;
|
||||||
struct inode *inode = page->mapping->host;
|
struct inode *inode = page->mapping->host;
|
||||||
|
|
||||||
pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
|
pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
|
||||||
"mirror=%u\n", (u64)bio->bi_iter.bi_sector, err,
|
"mirror=%u\n", (u64)bio->bi_iter.bi_sector,
|
||||||
io_bio->mirror_num);
|
bio->bi_error, io_bio->mirror_num);
|
||||||
tree = &BTRFS_I(inode)->io_tree;
|
tree = &BTRFS_I(inode)->io_tree;
|
||||||
|
|
||||||
/* We always issue full-page reads, but if some block
|
/* We always issue full-page reads, but if some block
|
||||||
|
@ -2614,8 +2611,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
|
||||||
|
|
||||||
if (tree->ops && tree->ops->readpage_io_failed_hook) {
|
if (tree->ops && tree->ops->readpage_io_failed_hook) {
|
||||||
ret = tree->ops->readpage_io_failed_hook(page, mirror);
|
ret = tree->ops->readpage_io_failed_hook(page, mirror);
|
||||||
if (!ret && !err &&
|
if (!ret && !bio->bi_error)
|
||||||
test_bit(BIO_UPTODATE, &bio->bi_flags))
|
|
||||||
uptodate = 1;
|
uptodate = 1;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
@ -2631,10 +2627,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
|
||||||
ret = bio_readpage_error(bio, offset, page, start, end,
|
ret = bio_readpage_error(bio, offset, page, start, end,
|
||||||
mirror);
|
mirror);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
uptodate =
|
uptodate = !bio->bi_error;
|
||||||
test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
if (err)
|
|
||||||
uptodate = 0;
|
|
||||||
offset += len;
|
offset += len;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2684,7 +2677,7 @@ readpage_ok:
|
||||||
endio_readpage_release_extent(tree, extent_start, extent_len,
|
endio_readpage_release_extent(tree, extent_start, extent_len,
|
||||||
uptodate);
|
uptodate);
|
||||||
if (io_bio->end_io)
|
if (io_bio->end_io)
|
||||||
io_bio->end_io(io_bio, err);
|
io_bio->end_io(io_bio, bio->bi_error);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3696,7 +3689,7 @@ static void set_btree_ioerr(struct page *page)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_bio_extent_buffer_writepage(struct bio *bio, int err)
|
static void end_bio_extent_buffer_writepage(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
struct extent_buffer *eb;
|
struct extent_buffer *eb;
|
||||||
|
@ -3709,7 +3702,8 @@ static void end_bio_extent_buffer_writepage(struct bio *bio, int err)
|
||||||
BUG_ON(!eb);
|
BUG_ON(!eb);
|
||||||
done = atomic_dec_and_test(&eb->io_pages);
|
done = atomic_dec_and_test(&eb->io_pages);
|
||||||
|
|
||||||
if (err || test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) {
|
if (bio->bi_error ||
|
||||||
|
test_bit(EXTENT_BUFFER_WRITE_ERR, &eb->bflags)) {
|
||||||
ClearPageUptodate(page);
|
ClearPageUptodate(page);
|
||||||
set_btree_ioerr(page);
|
set_btree_ioerr(page);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1845,8 +1845,10 @@ static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = btrfs_map_bio(root, rw, bio, mirror_num, 1);
|
ret = btrfs_map_bio(root, rw, bio, mirror_num, 1);
|
||||||
if (ret)
|
if (ret) {
|
||||||
bio_endio(bio, ret);
|
bio->bi_error = ret;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1906,8 +1908,10 @@ mapit:
|
||||||
ret = btrfs_map_bio(root, rw, bio, mirror_num, 0);
|
ret = btrfs_map_bio(root, rw, bio, mirror_num, 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (ret < 0)
|
if (ret < 0) {
|
||||||
bio_endio(bio, ret);
|
bio->bi_error = ret;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7689,13 +7693,13 @@ struct btrfs_retry_complete {
|
||||||
int uptodate;
|
int uptodate;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void btrfs_retry_endio_nocsum(struct bio *bio, int err)
|
static void btrfs_retry_endio_nocsum(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_retry_complete *done = bio->bi_private;
|
struct btrfs_retry_complete *done = bio->bi_private;
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
done->uptodate = 1;
|
done->uptodate = 1;
|
||||||
|
@ -7744,7 +7748,7 @@ try_again:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_retry_endio(struct bio *bio, int err)
|
static void btrfs_retry_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_retry_complete *done = bio->bi_private;
|
struct btrfs_retry_complete *done = bio->bi_private;
|
||||||
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
||||||
|
@ -7753,7 +7757,7 @@ static void btrfs_retry_endio(struct bio *bio, int err)
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
uptodate = 1;
|
uptodate = 1;
|
||||||
|
@ -7836,12 +7840,13 @@ static int btrfs_subio_endio_read(struct inode *inode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_endio_direct_read(struct bio *bio, int err)
|
static void btrfs_endio_direct_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_dio_private *dip = bio->bi_private;
|
struct btrfs_dio_private *dip = bio->bi_private;
|
||||||
struct inode *inode = dip->inode;
|
struct inode *inode = dip->inode;
|
||||||
struct bio *dio_bio;
|
struct bio *dio_bio;
|
||||||
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
struct btrfs_io_bio *io_bio = btrfs_io_bio(bio);
|
||||||
|
int err = bio->bi_error;
|
||||||
|
|
||||||
if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)
|
if (dip->flags & BTRFS_DIO_ORIG_BIO_SUBMITTED)
|
||||||
err = btrfs_subio_endio_read(inode, io_bio, err);
|
err = btrfs_subio_endio_read(inode, io_bio, err);
|
||||||
|
@ -7852,17 +7857,14 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
|
||||||
|
|
||||||
kfree(dip);
|
kfree(dip);
|
||||||
|
|
||||||
/* If we had a csum failure make sure to clear the uptodate flag */
|
dio_end_io(dio_bio, bio->bi_error);
|
||||||
if (err)
|
|
||||||
clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
|
|
||||||
dio_end_io(dio_bio, err);
|
|
||||||
|
|
||||||
if (io_bio->end_io)
|
if (io_bio->end_io)
|
||||||
io_bio->end_io(io_bio, err);
|
io_bio->end_io(io_bio, err);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_endio_direct_write(struct bio *bio, int err)
|
static void btrfs_endio_direct_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_dio_private *dip = bio->bi_private;
|
struct btrfs_dio_private *dip = bio->bi_private;
|
||||||
struct inode *inode = dip->inode;
|
struct inode *inode = dip->inode;
|
||||||
|
@ -7876,7 +7878,8 @@ static void btrfs_endio_direct_write(struct bio *bio, int err)
|
||||||
again:
|
again:
|
||||||
ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
|
ret = btrfs_dec_test_first_ordered_pending(inode, &ordered,
|
||||||
&ordered_offset,
|
&ordered_offset,
|
||||||
ordered_bytes, !err);
|
ordered_bytes,
|
||||||
|
!bio->bi_error);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
goto out_test;
|
goto out_test;
|
||||||
|
|
||||||
|
@ -7899,10 +7902,7 @@ out_test:
|
||||||
|
|
||||||
kfree(dip);
|
kfree(dip);
|
||||||
|
|
||||||
/* If we had an error make sure to clear the uptodate flag */
|
dio_end_io(dio_bio, bio->bi_error);
|
||||||
if (err)
|
|
||||||
clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
|
|
||||||
dio_end_io(dio_bio, err);
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7917,9 +7917,10 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_end_dio_bio(struct bio *bio, int err)
|
static void btrfs_end_dio_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_dio_private *dip = bio->bi_private;
|
struct btrfs_dio_private *dip = bio->bi_private;
|
||||||
|
int err = bio->bi_error;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
btrfs_warn(BTRFS_I(dip->inode)->root->fs_info,
|
btrfs_warn(BTRFS_I(dip->inode)->root->fs_info,
|
||||||
|
@ -7948,8 +7949,8 @@ static void btrfs_end_dio_bio(struct bio *bio, int err)
|
||||||
if (dip->errors) {
|
if (dip->errors) {
|
||||||
bio_io_error(dip->orig_bio);
|
bio_io_error(dip->orig_bio);
|
||||||
} else {
|
} else {
|
||||||
set_bit(BIO_UPTODATE, &dip->dio_bio->bi_flags);
|
dip->dio_bio->bi_error = 0;
|
||||||
bio_endio(dip->orig_bio, 0);
|
bio_endio(dip->orig_bio);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
@ -8220,7 +8221,8 @@ free_ordered:
|
||||||
* callbacks - they require an allocated dip and a clone of dio_bio.
|
* callbacks - they require an allocated dip and a clone of dio_bio.
|
||||||
*/
|
*/
|
||||||
if (io_bio && dip) {
|
if (io_bio && dip) {
|
||||||
bio_endio(io_bio, ret);
|
io_bio->bi_error = -EIO;
|
||||||
|
bio_endio(io_bio);
|
||||||
/*
|
/*
|
||||||
* The end io callbacks free our dip, do the final put on io_bio
|
* The end io callbacks free our dip, do the final put on io_bio
|
||||||
* and all the cleanup and final put for dio_bio (through
|
* and all the cleanup and final put for dio_bio (through
|
||||||
|
@ -8247,7 +8249,7 @@ free_ordered:
|
||||||
unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,
|
unlock_extent(&BTRFS_I(inode)->io_tree, file_offset,
|
||||||
file_offset + dio_bio->bi_iter.bi_size - 1);
|
file_offset + dio_bio->bi_iter.bi_size - 1);
|
||||||
}
|
}
|
||||||
clear_bit(BIO_UPTODATE, &dio_bio->bi_flags);
|
dio_bio->bi_error = -EIO;
|
||||||
/*
|
/*
|
||||||
* Releases and cleans up our dio_bio, no need to bio_put()
|
* Releases and cleans up our dio_bio, no need to bio_put()
|
||||||
* nor bio_endio()/bio_io_error() against dio_bio.
|
* nor bio_endio()/bio_io_error() against dio_bio.
|
||||||
|
|
|
@ -851,7 +851,7 @@ static void free_raid_bio(struct btrfs_raid_bio *rbio)
|
||||||
* this frees the rbio and runs through all the bios in the
|
* this frees the rbio and runs through all the bios in the
|
||||||
* bio_list and calls end_io on them
|
* bio_list and calls end_io on them
|
||||||
*/
|
*/
|
||||||
static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, int err, int uptodate)
|
static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, int err)
|
||||||
{
|
{
|
||||||
struct bio *cur = bio_list_get(&rbio->bio_list);
|
struct bio *cur = bio_list_get(&rbio->bio_list);
|
||||||
struct bio *next;
|
struct bio *next;
|
||||||
|
@ -864,9 +864,8 @@ static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, int err, int uptodate)
|
||||||
while (cur) {
|
while (cur) {
|
||||||
next = cur->bi_next;
|
next = cur->bi_next;
|
||||||
cur->bi_next = NULL;
|
cur->bi_next = NULL;
|
||||||
if (uptodate)
|
cur->bi_error = err;
|
||||||
set_bit(BIO_UPTODATE, &cur->bi_flags);
|
bio_endio(cur);
|
||||||
bio_endio(cur, err);
|
|
||||||
cur = next;
|
cur = next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -875,9 +874,10 @@ static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, int err, int uptodate)
|
||||||
* end io function used by finish_rmw. When we finally
|
* end io function used by finish_rmw. When we finally
|
||||||
* get here, we've written a full stripe
|
* get here, we've written a full stripe
|
||||||
*/
|
*/
|
||||||
static void raid_write_end_io(struct bio *bio, int err)
|
static void raid_write_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_raid_bio *rbio = bio->bi_private;
|
struct btrfs_raid_bio *rbio = bio->bi_private;
|
||||||
|
int err = bio->bi_error;
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
fail_bio_stripe(rbio, bio);
|
fail_bio_stripe(rbio, bio);
|
||||||
|
@ -893,7 +893,7 @@ static void raid_write_end_io(struct bio *bio, int err)
|
||||||
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
|
|
||||||
rbio_orig_end_io(rbio, err, 0);
|
rbio_orig_end_io(rbio, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,7 +1071,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
|
||||||
* devices or if they are not contiguous
|
* devices or if they are not contiguous
|
||||||
*/
|
*/
|
||||||
if (last_end == disk_start && stripe->dev->bdev &&
|
if (last_end == disk_start && stripe->dev->bdev &&
|
||||||
test_bit(BIO_UPTODATE, &last->bi_flags) &&
|
!last->bi_error &&
|
||||||
last->bi_bdev == stripe->dev->bdev) {
|
last->bi_bdev == stripe->dev->bdev) {
|
||||||
ret = bio_add_page(last, page, PAGE_CACHE_SIZE, 0);
|
ret = bio_add_page(last, page, PAGE_CACHE_SIZE, 0);
|
||||||
if (ret == PAGE_CACHE_SIZE)
|
if (ret == PAGE_CACHE_SIZE)
|
||||||
|
@ -1087,7 +1087,6 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
bio->bi_bdev = stripe->dev->bdev;
|
bio->bi_bdev = stripe->dev->bdev;
|
||||||
bio->bi_iter.bi_sector = disk_start >> 9;
|
bio->bi_iter.bi_sector = disk_start >> 9;
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
|
|
||||||
bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
|
bio_add_page(bio, page, PAGE_CACHE_SIZE, 0);
|
||||||
bio_list_add(bio_list, bio);
|
bio_list_add(bio_list, bio);
|
||||||
|
@ -1312,13 +1311,12 @@ write_data:
|
||||||
|
|
||||||
bio->bi_private = rbio;
|
bio->bi_private = rbio;
|
||||||
bio->bi_end_io = raid_write_end_io;
|
bio->bi_end_io = raid_write_end_io;
|
||||||
BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
submit_bio(WRITE, bio);
|
submit_bio(WRITE, bio);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1441,11 +1439,11 @@ static void set_bio_pages_uptodate(struct bio *bio)
|
||||||
* This will usually kick off finish_rmw once all the bios are read in, but it
|
* This will usually kick off finish_rmw once all the bios are read in, but it
|
||||||
* may trigger parity reconstruction if we had any errors along the way
|
* may trigger parity reconstruction if we had any errors along the way
|
||||||
*/
|
*/
|
||||||
static void raid_rmw_end_io(struct bio *bio, int err)
|
static void raid_rmw_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_raid_bio *rbio = bio->bi_private;
|
struct btrfs_raid_bio *rbio = bio->bi_private;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
fail_bio_stripe(rbio, bio);
|
fail_bio_stripe(rbio, bio);
|
||||||
else
|
else
|
||||||
set_bio_pages_uptodate(bio);
|
set_bio_pages_uptodate(bio);
|
||||||
|
@ -1455,7 +1453,6 @@ static void raid_rmw_end_io(struct bio *bio, int err)
|
||||||
if (!atomic_dec_and_test(&rbio->stripes_pending))
|
if (!atomic_dec_and_test(&rbio->stripes_pending))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
err = 0;
|
|
||||||
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -1469,7 +1466,7 @@ static void raid_rmw_end_io(struct bio *bio, int err)
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void async_rmw_stripe(struct btrfs_raid_bio *rbio)
|
static void async_rmw_stripe(struct btrfs_raid_bio *rbio)
|
||||||
|
@ -1572,14 +1569,13 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
|
||||||
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
||||||
BTRFS_WQ_ENDIO_RAID56);
|
BTRFS_WQ_ENDIO_RAID56);
|
||||||
|
|
||||||
BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
submit_bio(READ, bio);
|
submit_bio(READ, bio);
|
||||||
}
|
}
|
||||||
/* the actual write will happen once the reads are done */
|
/* the actual write will happen once the reads are done */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
@ -1964,7 +1960,7 @@ cleanup_io:
|
||||||
else
|
else
|
||||||
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
|
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
|
||||||
|
|
||||||
rbio_orig_end_io(rbio, err, err == 0);
|
rbio_orig_end_io(rbio, err);
|
||||||
} else if (err == 0) {
|
} else if (err == 0) {
|
||||||
rbio->faila = -1;
|
rbio->faila = -1;
|
||||||
rbio->failb = -1;
|
rbio->failb = -1;
|
||||||
|
@ -1976,7 +1972,7 @@ cleanup_io:
|
||||||
else
|
else
|
||||||
BUG();
|
BUG();
|
||||||
} else {
|
} else {
|
||||||
rbio_orig_end_io(rbio, err, 0);
|
rbio_orig_end_io(rbio, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,7 +1980,7 @@ cleanup_io:
|
||||||
* This is called only for stripes we've read from disk to
|
* This is called only for stripes we've read from disk to
|
||||||
* reconstruct the parity.
|
* reconstruct the parity.
|
||||||
*/
|
*/
|
||||||
static void raid_recover_end_io(struct bio *bio, int err)
|
static void raid_recover_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_raid_bio *rbio = bio->bi_private;
|
struct btrfs_raid_bio *rbio = bio->bi_private;
|
||||||
|
|
||||||
|
@ -1992,7 +1988,7 @@ static void raid_recover_end_io(struct bio *bio, int err)
|
||||||
* we only read stripe pages off the disk, set them
|
* we only read stripe pages off the disk, set them
|
||||||
* up to date if there were no errors
|
* up to date if there were no errors
|
||||||
*/
|
*/
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
fail_bio_stripe(rbio, bio);
|
fail_bio_stripe(rbio, bio);
|
||||||
else
|
else
|
||||||
set_bio_pages_uptodate(bio);
|
set_bio_pages_uptodate(bio);
|
||||||
|
@ -2002,7 +1998,7 @@ static void raid_recover_end_io(struct bio *bio, int err)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
if (atomic_read(&rbio->error) > rbio->bbio->max_errors)
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
else
|
else
|
||||||
__raid_recover_end_io(rbio);
|
__raid_recover_end_io(rbio);
|
||||||
}
|
}
|
||||||
|
@ -2094,7 +2090,6 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
|
||||||
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
||||||
BTRFS_WQ_ENDIO_RAID56);
|
BTRFS_WQ_ENDIO_RAID56);
|
||||||
|
|
||||||
BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
submit_bio(READ, bio);
|
submit_bio(READ, bio);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
@ -2102,7 +2097,7 @@ out:
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (rbio->operation == BTRFS_RBIO_READ_REBUILD)
|
if (rbio->operation == BTRFS_RBIO_READ_REBUILD)
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,11 +2272,12 @@ static int alloc_rbio_essential_pages(struct btrfs_raid_bio *rbio)
|
||||||
* end io function used by finish_rmw. When we finally
|
* end io function used by finish_rmw. When we finally
|
||||||
* get here, we've written a full stripe
|
* get here, we've written a full stripe
|
||||||
*/
|
*/
|
||||||
static void raid_write_parity_end_io(struct bio *bio, int err)
|
static void raid_write_parity_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_raid_bio *rbio = bio->bi_private;
|
struct btrfs_raid_bio *rbio = bio->bi_private;
|
||||||
|
int err = bio->bi_error;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
fail_bio_stripe(rbio, bio);
|
fail_bio_stripe(rbio, bio);
|
||||||
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
@ -2294,7 +2290,7 @@ static void raid_write_parity_end_io(struct bio *bio, int err)
|
||||||
if (atomic_read(&rbio->error))
|
if (atomic_read(&rbio->error))
|
||||||
err = -EIO;
|
err = -EIO;
|
||||||
|
|
||||||
rbio_orig_end_io(rbio, err, 0);
|
rbio_orig_end_io(rbio, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
|
static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
|
||||||
|
@ -2437,7 +2433,7 @@ submit_write:
|
||||||
nr_data = bio_list_size(&bio_list);
|
nr_data = bio_list_size(&bio_list);
|
||||||
if (!nr_data) {
|
if (!nr_data) {
|
||||||
/* Every parity is right */
|
/* Every parity is right */
|
||||||
rbio_orig_end_io(rbio, 0, 0);
|
rbio_orig_end_io(rbio, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2450,13 +2446,12 @@ submit_write:
|
||||||
|
|
||||||
bio->bi_private = rbio;
|
bio->bi_private = rbio;
|
||||||
bio->bi_end_io = raid_write_parity_end_io;
|
bio->bi_end_io = raid_write_parity_end_io;
|
||||||
BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
submit_bio(WRITE, bio);
|
submit_bio(WRITE, bio);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
|
static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
|
||||||
|
@ -2524,7 +2519,7 @@ static void validate_rbio_for_parity_scrub(struct btrfs_raid_bio *rbio)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2535,11 +2530,11 @@ cleanup:
|
||||||
* This will usually kick off finish_rmw once all the bios are read in, but it
|
* This will usually kick off finish_rmw once all the bios are read in, but it
|
||||||
* may trigger parity reconstruction if we had any errors along the way
|
* may trigger parity reconstruction if we had any errors along the way
|
||||||
*/
|
*/
|
||||||
static void raid56_parity_scrub_end_io(struct bio *bio, int err)
|
static void raid56_parity_scrub_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_raid_bio *rbio = bio->bi_private;
|
struct btrfs_raid_bio *rbio = bio->bi_private;
|
||||||
|
|
||||||
if (err)
|
if (bio->bi_error)
|
||||||
fail_bio_stripe(rbio, bio);
|
fail_bio_stripe(rbio, bio);
|
||||||
else
|
else
|
||||||
set_bio_pages_uptodate(bio);
|
set_bio_pages_uptodate(bio);
|
||||||
|
@ -2632,14 +2627,13 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
|
||||||
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
btrfs_bio_wq_end_io(rbio->fs_info, bio,
|
||||||
BTRFS_WQ_ENDIO_RAID56);
|
BTRFS_WQ_ENDIO_RAID56);
|
||||||
|
|
||||||
BUG_ON(!test_bit(BIO_UPTODATE, &bio->bi_flags));
|
|
||||||
submit_bio(READ, bio);
|
submit_bio(READ, bio);
|
||||||
}
|
}
|
||||||
/* the actual write will happen once the reads are done */
|
/* the actual write will happen once the reads are done */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
rbio_orig_end_io(rbio, -EIO, 0);
|
rbio_orig_end_io(rbio, -EIO);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
|
|
@ -278,7 +278,7 @@ static int scrub_pages(struct scrub_ctx *sctx, u64 logical, u64 len,
|
||||||
u64 physical, struct btrfs_device *dev, u64 flags,
|
u64 physical, struct btrfs_device *dev, u64 flags,
|
||||||
u64 gen, int mirror_num, u8 *csum, int force,
|
u64 gen, int mirror_num, u8 *csum, int force,
|
||||||
u64 physical_for_dev_replace);
|
u64 physical_for_dev_replace);
|
||||||
static void scrub_bio_end_io(struct bio *bio, int err);
|
static void scrub_bio_end_io(struct bio *bio);
|
||||||
static void scrub_bio_end_io_worker(struct btrfs_work *work);
|
static void scrub_bio_end_io_worker(struct btrfs_work *work);
|
||||||
static void scrub_block_complete(struct scrub_block *sblock);
|
static void scrub_block_complete(struct scrub_block *sblock);
|
||||||
static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
|
static void scrub_remap_extent(struct btrfs_fs_info *fs_info,
|
||||||
|
@ -295,7 +295,7 @@ static void scrub_free_wr_ctx(struct scrub_wr_ctx *wr_ctx);
|
||||||
static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx,
|
static int scrub_add_page_to_wr_bio(struct scrub_ctx *sctx,
|
||||||
struct scrub_page *spage);
|
struct scrub_page *spage);
|
||||||
static void scrub_wr_submit(struct scrub_ctx *sctx);
|
static void scrub_wr_submit(struct scrub_ctx *sctx);
|
||||||
static void scrub_wr_bio_end_io(struct bio *bio, int err);
|
static void scrub_wr_bio_end_io(struct bio *bio);
|
||||||
static void scrub_wr_bio_end_io_worker(struct btrfs_work *work);
|
static void scrub_wr_bio_end_io_worker(struct btrfs_work *work);
|
||||||
static int write_page_nocow(struct scrub_ctx *sctx,
|
static int write_page_nocow(struct scrub_ctx *sctx,
|
||||||
u64 physical_for_dev_replace, struct page *page);
|
u64 physical_for_dev_replace, struct page *page);
|
||||||
|
@ -1429,11 +1429,11 @@ struct scrub_bio_ret {
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void scrub_bio_wait_endio(struct bio *bio, int error)
|
static void scrub_bio_wait_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct scrub_bio_ret *ret = bio->bi_private;
|
struct scrub_bio_ret *ret = bio->bi_private;
|
||||||
|
|
||||||
ret->error = error;
|
ret->error = bio->bi_error;
|
||||||
complete(&ret->event);
|
complete(&ret->event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1790,12 +1790,12 @@ static void scrub_wr_submit(struct scrub_ctx *sctx)
|
||||||
btrfsic_submit_bio(WRITE, sbio->bio);
|
btrfsic_submit_bio(WRITE, sbio->bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scrub_wr_bio_end_io(struct bio *bio, int err)
|
static void scrub_wr_bio_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct scrub_bio *sbio = bio->bi_private;
|
struct scrub_bio *sbio = bio->bi_private;
|
||||||
struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
|
struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
|
||||||
|
|
||||||
sbio->err = err;
|
sbio->err = bio->bi_error;
|
||||||
sbio->bio = bio;
|
sbio->bio = bio;
|
||||||
|
|
||||||
btrfs_init_work(&sbio->work, btrfs_scrubwrc_helper,
|
btrfs_init_work(&sbio->work, btrfs_scrubwrc_helper,
|
||||||
|
@ -2098,7 +2098,7 @@ static void scrub_submit(struct scrub_ctx *sctx)
|
||||||
*/
|
*/
|
||||||
printk_ratelimited(KERN_WARNING
|
printk_ratelimited(KERN_WARNING
|
||||||
"BTRFS: scrub_submit(bio bdev == NULL) is unexpected!\n");
|
"BTRFS: scrub_submit(bio bdev == NULL) is unexpected!\n");
|
||||||
bio_endio(sbio->bio, -EIO);
|
bio_io_error(sbio->bio);
|
||||||
} else {
|
} else {
|
||||||
btrfsic_submit_bio(READ, sbio->bio);
|
btrfsic_submit_bio(READ, sbio->bio);
|
||||||
}
|
}
|
||||||
|
@ -2260,12 +2260,12 @@ leave_nomem:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scrub_bio_end_io(struct bio *bio, int err)
|
static void scrub_bio_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct scrub_bio *sbio = bio->bi_private;
|
struct scrub_bio *sbio = bio->bi_private;
|
||||||
struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
|
struct btrfs_fs_info *fs_info = sbio->dev->dev_root->fs_info;
|
||||||
|
|
||||||
sbio->err = err;
|
sbio->err = bio->bi_error;
|
||||||
sbio->bio = bio;
|
sbio->bio = bio;
|
||||||
|
|
||||||
btrfs_queue_work(fs_info->scrub_workers, &sbio->work);
|
btrfs_queue_work(fs_info->scrub_workers, &sbio->work);
|
||||||
|
@ -2672,11 +2672,11 @@ static void scrub_parity_bio_endio_worker(struct btrfs_work *work)
|
||||||
scrub_pending_bio_dec(sctx);
|
scrub_pending_bio_dec(sctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scrub_parity_bio_endio(struct bio *bio, int error)
|
static void scrub_parity_bio_endio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct scrub_parity *sparity = (struct scrub_parity *)bio->bi_private;
|
struct scrub_parity *sparity = (struct scrub_parity *)bio->bi_private;
|
||||||
|
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap,
|
bitmap_or(sparity->ebitmap, sparity->ebitmap, sparity->dbitmap,
|
||||||
sparity->nsectors);
|
sparity->nsectors);
|
||||||
|
|
||||||
|
|
|
@ -5741,23 +5741,23 @@ int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio, int err)
|
static inline void btrfs_end_bbio(struct btrfs_bio *bbio, struct bio *bio)
|
||||||
{
|
{
|
||||||
bio->bi_private = bbio->private;
|
bio->bi_private = bbio->private;
|
||||||
bio->bi_end_io = bbio->end_io;
|
bio->bi_end_io = bbio->end_io;
|
||||||
bio_endio(bio, err);
|
bio_endio(bio);
|
||||||
|
|
||||||
btrfs_put_bbio(bbio);
|
btrfs_put_bbio(bbio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void btrfs_end_bio(struct bio *bio, int err)
|
static void btrfs_end_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct btrfs_bio *bbio = bio->bi_private;
|
struct btrfs_bio *bbio = bio->bi_private;
|
||||||
int is_orig_bio = 0;
|
int is_orig_bio = 0;
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
atomic_inc(&bbio->error);
|
atomic_inc(&bbio->error);
|
||||||
if (err == -EIO || err == -EREMOTEIO) {
|
if (bio->bi_error == -EIO || bio->bi_error == -EREMOTEIO) {
|
||||||
unsigned int stripe_index =
|
unsigned int stripe_index =
|
||||||
btrfs_io_bio(bio)->stripe_index;
|
btrfs_io_bio(bio)->stripe_index;
|
||||||
struct btrfs_device *dev;
|
struct btrfs_device *dev;
|
||||||
|
@ -5795,17 +5795,16 @@ static void btrfs_end_bio(struct bio *bio, int err)
|
||||||
* beyond the tolerance of the btrfs bio
|
* beyond the tolerance of the btrfs bio
|
||||||
*/
|
*/
|
||||||
if (atomic_read(&bbio->error) > bbio->max_errors) {
|
if (atomic_read(&bbio->error) > bbio->max_errors) {
|
||||||
err = -EIO;
|
bio->bi_error = -EIO;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* this bio is actually up to date, we didn't
|
* this bio is actually up to date, we didn't
|
||||||
* go over the max number of errors
|
* go over the max number of errors
|
||||||
*/
|
*/
|
||||||
set_bit(BIO_UPTODATE, &bio->bi_flags);
|
bio->bi_error = 0;
|
||||||
err = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btrfs_end_bbio(bbio, bio, err);
|
btrfs_end_bbio(bbio, bio);
|
||||||
} else if (!is_orig_bio) {
|
} else if (!is_orig_bio) {
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
@ -5826,7 +5825,7 @@ static noinline void btrfs_schedule_bio(struct btrfs_root *root,
|
||||||
struct btrfs_pending_bios *pending_bios;
|
struct btrfs_pending_bios *pending_bios;
|
||||||
|
|
||||||
if (device->missing || !device->bdev) {
|
if (device->missing || !device->bdev) {
|
||||||
bio_endio(bio, -EIO);
|
bio_io_error(bio);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5973,8 +5972,8 @@ static void bbio_error(struct btrfs_bio *bbio, struct bio *bio, u64 logical)
|
||||||
|
|
||||||
btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
|
btrfs_io_bio(bio)->mirror_num = bbio->mirror_num;
|
||||||
bio->bi_iter.bi_sector = logical >> 9;
|
bio->bi_iter.bi_sector = logical >> 9;
|
||||||
|
bio->bi_error = -EIO;
|
||||||
btrfs_end_bbio(bbio, bio, -EIO);
|
btrfs_end_bbio(bbio, bio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2957,14 +2957,14 @@ sector_t generic_block_bmap(struct address_space *mapping, sector_t block,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(generic_block_bmap);
|
EXPORT_SYMBOL(generic_block_bmap);
|
||||||
|
|
||||||
static void end_bio_bh_io_sync(struct bio *bio, int err)
|
static void end_bio_bh_io_sync(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh = bio->bi_private;
|
struct buffer_head *bh = bio->bi_private;
|
||||||
|
|
||||||
if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags)))
|
if (unlikely (test_bit(BIO_QUIET,&bio->bi_flags)))
|
||||||
set_bit(BH_Quiet, &bh->b_state);
|
set_bit(BH_Quiet, &bh->b_state);
|
||||||
|
|
||||||
bh->b_end_io(bh, test_bit(BIO_UPTODATE, &bio->bi_flags));
|
bh->b_end_io(bh, !bio->bi_error);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio);
|
||||||
/*
|
/*
|
||||||
* Asynchronous IO callback.
|
* Asynchronous IO callback.
|
||||||
*/
|
*/
|
||||||
static void dio_bio_end_aio(struct bio *bio, int error)
|
static void dio_bio_end_aio(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dio *dio = bio->bi_private;
|
struct dio *dio = bio->bi_private;
|
||||||
unsigned long remaining;
|
unsigned long remaining;
|
||||||
|
@ -318,7 +318,7 @@ static void dio_bio_end_aio(struct bio *bio, int error)
|
||||||
* During I/O bi_private points at the dio. After I/O, bi_private is used to
|
* During I/O bi_private points at the dio. After I/O, bi_private is used to
|
||||||
* implement a singly-linked list of completed BIOs, at dio->bio_list.
|
* implement a singly-linked list of completed BIOs, at dio->bio_list.
|
||||||
*/
|
*/
|
||||||
static void dio_bio_end_io(struct bio *bio, int error)
|
static void dio_bio_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct dio *dio = bio->bi_private;
|
struct dio *dio = bio->bi_private;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
@ -345,9 +345,9 @@ void dio_end_io(struct bio *bio, int error)
|
||||||
struct dio *dio = bio->bi_private;
|
struct dio *dio = bio->bi_private;
|
||||||
|
|
||||||
if (dio->is_async)
|
if (dio->is_async)
|
||||||
dio_bio_end_aio(bio, error);
|
dio_bio_end_aio(bio);
|
||||||
else
|
else
|
||||||
dio_bio_end_io(bio, error);
|
dio_bio_end_io(bio);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(dio_end_io);
|
EXPORT_SYMBOL_GPL(dio_end_io);
|
||||||
|
|
||||||
|
@ -457,11 +457,10 @@ static struct bio *dio_await_one(struct dio *dio)
|
||||||
*/
|
*/
|
||||||
static int dio_bio_complete(struct dio *dio, struct bio *bio)
|
static int dio_bio_complete(struct dio *dio, struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (!uptodate)
|
if (bio->bi_error)
|
||||||
dio->io_error = -EIO;
|
dio->io_error = -EIO;
|
||||||
|
|
||||||
if (dio->is_async && dio->rw == READ) {
|
if (dio->is_async && dio->rw == READ) {
|
||||||
|
@ -476,7 +475,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
|
||||||
}
|
}
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
return uptodate ? 0 : -EIO;
|
return bio->bi_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -61,7 +61,6 @@ static void buffer_io_error(struct buffer_head *bh)
|
||||||
static void ext4_finish_bio(struct bio *bio)
|
static void ext4_finish_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int error = !test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
|
|
||||||
bio_for_each_segment_all(bvec, bio, i) {
|
bio_for_each_segment_all(bvec, bio, i) {
|
||||||
|
@ -88,7 +87,7 @@ static void ext4_finish_bio(struct bio *bio)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
set_bit(AS_EIO, &page->mapping->flags);
|
set_bit(AS_EIO, &page->mapping->flags);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +106,7 @@ static void ext4_finish_bio(struct bio *bio)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
clear_buffer_async_write(bh);
|
clear_buffer_async_write(bh);
|
||||||
if (error)
|
if (bio->bi_error)
|
||||||
buffer_io_error(bh);
|
buffer_io_error(bh);
|
||||||
} while ((bh = bh->b_this_page) != head);
|
} while ((bh = bh->b_this_page) != head);
|
||||||
bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
|
bit_spin_unlock(BH_Uptodate_Lock, &head->b_state);
|
||||||
|
@ -310,27 +309,25 @@ ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* BIO completion function for page writeback */
|
/* BIO completion function for page writeback */
|
||||||
static void ext4_end_bio(struct bio *bio, int error)
|
static void ext4_end_bio(struct bio *bio)
|
||||||
{
|
{
|
||||||
ext4_io_end_t *io_end = bio->bi_private;
|
ext4_io_end_t *io_end = bio->bi_private;
|
||||||
sector_t bi_sector = bio->bi_iter.bi_sector;
|
sector_t bi_sector = bio->bi_iter.bi_sector;
|
||||||
|
|
||||||
BUG_ON(!io_end);
|
BUG_ON(!io_end);
|
||||||
bio->bi_end_io = NULL;
|
bio->bi_end_io = NULL;
|
||||||
if (test_bit(BIO_UPTODATE, &bio->bi_flags))
|
|
||||||
error = 0;
|
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
struct inode *inode = io_end->inode;
|
struct inode *inode = io_end->inode;
|
||||||
|
|
||||||
ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu "
|
ext4_warning(inode->i_sb, "I/O error %d writing to inode %lu "
|
||||||
"(offset %llu size %ld starting block %llu)",
|
"(offset %llu size %ld starting block %llu)",
|
||||||
error, inode->i_ino,
|
bio->bi_error, inode->i_ino,
|
||||||
(unsigned long long) io_end->offset,
|
(unsigned long long) io_end->offset,
|
||||||
(long) io_end->size,
|
(long) io_end->size,
|
||||||
(unsigned long long)
|
(unsigned long long)
|
||||||
bi_sector >> (inode->i_blkbits - 9));
|
bi_sector >> (inode->i_blkbits - 9));
|
||||||
mapping_set_error(inode->i_mapping, error);
|
mapping_set_error(inode->i_mapping, bio->bi_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
if (io_end->flag & EXT4_IO_END_UNWRITTEN) {
|
||||||
|
|
|
@ -98,7 +98,7 @@ static inline bool ext4_bio_encrypted(struct bio *bio)
|
||||||
* status of that page is hard. See end_buffer_async_read() for the details.
|
* status of that page is hard. See end_buffer_async_read() for the details.
|
||||||
* There is no point in duplicating all that complexity.
|
* There is no point in duplicating all that complexity.
|
||||||
*/
|
*/
|
||||||
static void mpage_end_io(struct bio *bio, int err)
|
static void mpage_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bv;
|
struct bio_vec *bv;
|
||||||
int i;
|
int i;
|
||||||
|
@ -106,7 +106,7 @@ static void mpage_end_io(struct bio *bio, int err)
|
||||||
if (ext4_bio_encrypted(bio)) {
|
if (ext4_bio_encrypted(bio)) {
|
||||||
struct ext4_crypto_ctx *ctx = bio->bi_private;
|
struct ext4_crypto_ctx *ctx = bio->bi_private;
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
ext4_release_crypto_ctx(ctx);
|
ext4_release_crypto_ctx(ctx);
|
||||||
} else {
|
} else {
|
||||||
INIT_WORK(&ctx->r.work, completion_pages);
|
INIT_WORK(&ctx->r.work, completion_pages);
|
||||||
|
@ -118,7 +118,7 @@ static void mpage_end_io(struct bio *bio, int err)
|
||||||
bio_for_each_segment_all(bv, bio, i) {
|
bio_for_each_segment_all(bv, bio, i) {
|
||||||
struct page *page = bv->bv_page;
|
struct page *page = bv->bv_page;
|
||||||
|
|
||||||
if (!err) {
|
if (!bio->bi_error) {
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
} else {
|
} else {
|
||||||
ClearPageUptodate(page);
|
ClearPageUptodate(page);
|
||||||
|
|
|
@ -29,13 +29,13 @@
|
||||||
static struct kmem_cache *extent_tree_slab;
|
static struct kmem_cache *extent_tree_slab;
|
||||||
static struct kmem_cache *extent_node_slab;
|
static struct kmem_cache *extent_node_slab;
|
||||||
|
|
||||||
static void f2fs_read_end_io(struct bio *bio, int err)
|
static void f2fs_read_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (f2fs_bio_encrypted(bio)) {
|
if (f2fs_bio_encrypted(bio)) {
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
f2fs_release_crypto_ctx(bio->bi_private);
|
f2fs_release_crypto_ctx(bio->bi_private);
|
||||||
} else {
|
} else {
|
||||||
f2fs_end_io_crypto_work(bio->bi_private, bio);
|
f2fs_end_io_crypto_work(bio->bi_private, bio);
|
||||||
|
@ -46,7 +46,7 @@ static void f2fs_read_end_io(struct bio *bio, int err)
|
||||||
bio_for_each_segment_all(bvec, bio, i) {
|
bio_for_each_segment_all(bvec, bio, i) {
|
||||||
struct page *page = bvec->bv_page;
|
struct page *page = bvec->bv_page;
|
||||||
|
|
||||||
if (!err) {
|
if (!bio->bi_error) {
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
} else {
|
} else {
|
||||||
ClearPageUptodate(page);
|
ClearPageUptodate(page);
|
||||||
|
@ -57,7 +57,7 @@ static void f2fs_read_end_io(struct bio *bio, int err)
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void f2fs_write_end_io(struct bio *bio, int err)
|
static void f2fs_write_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct f2fs_sb_info *sbi = bio->bi_private;
|
struct f2fs_sb_info *sbi = bio->bi_private;
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
|
@ -68,7 +68,7 @@ static void f2fs_write_end_io(struct bio *bio, int err)
|
||||||
|
|
||||||
f2fs_restore_and_release_control_page(&page);
|
f2fs_restore_and_release_control_page(&page);
|
||||||
|
|
||||||
if (unlikely(err)) {
|
if (unlikely(bio->bi_error)) {
|
||||||
set_page_dirty(page);
|
set_page_dirty(page);
|
||||||
set_bit(AS_EIO, &page->mapping->flags);
|
set_bit(AS_EIO, &page->mapping->flags);
|
||||||
f2fs_stop_checkpoint(sbi);
|
f2fs_stop_checkpoint(sbi);
|
||||||
|
|
|
@ -202,22 +202,22 @@ static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void gfs2_end_log_write(struct bio *bio, int error)
|
static void gfs2_end_log_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct gfs2_sbd *sdp = bio->bi_private;
|
struct gfs2_sbd *sdp = bio->bi_private;
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
struct page *page;
|
struct page *page;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
sdp->sd_log_error = error;
|
sdp->sd_log_error = bio->bi_error;
|
||||||
fs_err(sdp, "Error %d writing to log\n", error);
|
fs_err(sdp, "Error %d writing to log\n", bio->bi_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_for_each_segment_all(bvec, bio, i) {
|
bio_for_each_segment_all(bvec, bio, i) {
|
||||||
page = bvec->bv_page;
|
page = bvec->bv_page;
|
||||||
if (page_has_buffers(page))
|
if (page_has_buffers(page))
|
||||||
gfs2_end_log_write_bh(sdp, bvec, error);
|
gfs2_end_log_write_bh(sdp, bvec, bio->bi_error);
|
||||||
else
|
else
|
||||||
mempool_free(page, gfs2_page_pool);
|
mempool_free(page, gfs2_page_pool);
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,14 +171,14 @@ static int gfs2_check_sb(struct gfs2_sbd *sdp, int silent)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_bio_io_page(struct bio *bio, int error)
|
static void end_bio_io_page(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct page *page = bio->bi_private;
|
struct page *page = bio->bi_private;
|
||||||
|
|
||||||
if (!error)
|
if (!bio->bi_error)
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
else
|
else
|
||||||
pr_warn("error %d reading superblock\n", error);
|
pr_warn("error %d reading superblock\n", bio->bi_error);
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2011,7 +2011,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
|
||||||
/*check if journaling to disk has been disabled*/
|
/*check if journaling to disk has been disabled*/
|
||||||
if (log->no_integrity) {
|
if (log->no_integrity) {
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
lbmIODone(bio, 0);
|
lbmIODone(bio);
|
||||||
} else {
|
} else {
|
||||||
submit_bio(READ_SYNC, bio);
|
submit_bio(READ_SYNC, bio);
|
||||||
}
|
}
|
||||||
|
@ -2158,7 +2158,7 @@ static void lbmStartIO(struct lbuf * bp)
|
||||||
/* check if journaling to disk has been disabled */
|
/* check if journaling to disk has been disabled */
|
||||||
if (log->no_integrity) {
|
if (log->no_integrity) {
|
||||||
bio->bi_iter.bi_size = 0;
|
bio->bi_iter.bi_size = 0;
|
||||||
lbmIODone(bio, 0);
|
lbmIODone(bio);
|
||||||
} else {
|
} else {
|
||||||
submit_bio(WRITE_SYNC, bio);
|
submit_bio(WRITE_SYNC, bio);
|
||||||
INCREMENT(lmStat.submitted);
|
INCREMENT(lmStat.submitted);
|
||||||
|
@ -2196,7 +2196,7 @@ static int lbmIOWait(struct lbuf * bp, int flag)
|
||||||
*
|
*
|
||||||
* executed at INTIODONE level
|
* executed at INTIODONE level
|
||||||
*/
|
*/
|
||||||
static void lbmIODone(struct bio *bio, int error)
|
static void lbmIODone(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct lbuf *bp = bio->bi_private;
|
struct lbuf *bp = bio->bi_private;
|
||||||
struct lbuf *nextbp, *tail;
|
struct lbuf *nextbp, *tail;
|
||||||
|
@ -2212,7 +2212,7 @@ static void lbmIODone(struct bio *bio, int error)
|
||||||
|
|
||||||
bp->l_flag |= lbmDONE;
|
bp->l_flag |= lbmDONE;
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
|
if (bio->bi_error) {
|
||||||
bp->l_flag |= lbmERROR;
|
bp->l_flag |= lbmERROR;
|
||||||
|
|
||||||
jfs_err("lbmIODone: I/O error in JFS log");
|
jfs_err("lbmIODone: I/O error in JFS log");
|
||||||
|
|
|
@ -276,11 +276,11 @@ static void last_read_complete(struct page *page)
|
||||||
unlock_page(page);
|
unlock_page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void metapage_read_end_io(struct bio *bio, int err)
|
static void metapage_read_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct page *page = bio->bi_private;
|
struct page *page = bio->bi_private;
|
||||||
|
|
||||||
if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
|
if (bio->bi_error) {
|
||||||
printk(KERN_ERR "metapage_read_end_io: I/O error\n");
|
printk(KERN_ERR "metapage_read_end_io: I/O error\n");
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
}
|
}
|
||||||
|
@ -331,13 +331,13 @@ static void last_write_complete(struct page *page)
|
||||||
end_page_writeback(page);
|
end_page_writeback(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void metapage_write_end_io(struct bio *bio, int err)
|
static void metapage_write_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct page *page = bio->bi_private;
|
struct page *page = bio->bi_private;
|
||||||
|
|
||||||
BUG_ON(!PagePrivate(page));
|
BUG_ON(!PagePrivate(page));
|
||||||
|
|
||||||
if (! test_bit(BIO_UPTODATE, &bio->bi_flags)) {
|
if (bio->bi_error) {
|
||||||
printk(KERN_ERR "metapage_write_end_io: I/O error\n");
|
printk(KERN_ERR "metapage_write_end_io: I/O error\n");
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,16 +53,14 @@ static int bdev_readpage(void *_sb, struct page *page)
|
||||||
|
|
||||||
static DECLARE_WAIT_QUEUE_HEAD(wq);
|
static DECLARE_WAIT_QUEUE_HEAD(wq);
|
||||||
|
|
||||||
static void writeseg_end_io(struct bio *bio, int err)
|
static void writeseg_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct bio_vec *bvec;
|
struct bio_vec *bvec;
|
||||||
int i;
|
int i;
|
||||||
struct super_block *sb = bio->bi_private;
|
struct super_block *sb = bio->bi_private;
|
||||||
struct logfs_super *super = logfs_super(sb);
|
struct logfs_super *super = logfs_super(sb);
|
||||||
|
|
||||||
BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
|
BUG_ON(bio->bi_error); /* FIXME: Retry io or write elsewhere */
|
||||||
BUG_ON(err);
|
|
||||||
|
|
||||||
bio_for_each_segment_all(bvec, bio, i) {
|
bio_for_each_segment_all(bvec, bio, i) {
|
||||||
end_page_writeback(bvec->bv_page);
|
end_page_writeback(bvec->bv_page);
|
||||||
|
@ -153,14 +151,12 @@ static void bdev_writeseg(struct super_block *sb, u64 ofs, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void erase_end_io(struct bio *bio, int err)
|
static void erase_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct super_block *sb = bio->bi_private;
|
struct super_block *sb = bio->bi_private;
|
||||||
struct logfs_super *super = logfs_super(sb);
|
struct logfs_super *super = logfs_super(sb);
|
||||||
|
|
||||||
BUG_ON(!uptodate); /* FIXME: Retry io or write elsewhere */
|
BUG_ON(bio->bi_error); /* FIXME: Retry io or write elsewhere */
|
||||||
BUG_ON(err);
|
|
||||||
BUG_ON(bio->bi_vcnt == 0);
|
BUG_ON(bio->bi_vcnt == 0);
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
if (atomic_dec_and_test(&super->s_pending_writes))
|
if (atomic_dec_and_test(&super->s_pending_writes))
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
* status of that page is hard. See end_buffer_async_read() for the details.
|
* status of that page is hard. See end_buffer_async_read() for the details.
|
||||||
* There is no point in duplicating all that complexity.
|
* There is no point in duplicating all that complexity.
|
||||||
*/
|
*/
|
||||||
static void mpage_end_io(struct bio *bio, int err)
|
static void mpage_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct bio_vec *bv;
|
struct bio_vec *bv;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bio_for_each_segment_all(bv, bio, i) {
|
bio_for_each_segment_all(bv, bio, i) {
|
||||||
struct page *page = bv->bv_page;
|
struct page *page = bv->bv_page;
|
||||||
page_endio(page, bio_data_dir(bio), err);
|
page_endio(page, bio_data_dir(bio), bio->bi_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
|
|
@ -116,7 +116,7 @@ bl_submit_bio(int rw, struct bio *bio)
|
||||||
|
|
||||||
static struct bio *
|
static struct bio *
|
||||||
bl_alloc_init_bio(int npg, struct block_device *bdev, sector_t disk_sector,
|
bl_alloc_init_bio(int npg, struct block_device *bdev, sector_t disk_sector,
|
||||||
void (*end_io)(struct bio *, int err), struct parallel_io *par)
|
bio_end_io_t end_io, struct parallel_io *par)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
|
|
||||||
|
@ -139,8 +139,7 @@ bl_alloc_init_bio(int npg, struct block_device *bdev, sector_t disk_sector,
|
||||||
static struct bio *
|
static struct bio *
|
||||||
do_add_page_to_bio(struct bio *bio, int npg, int rw, sector_t isect,
|
do_add_page_to_bio(struct bio *bio, int npg, int rw, sector_t isect,
|
||||||
struct page *page, struct pnfs_block_dev_map *map,
|
struct page *page, struct pnfs_block_dev_map *map,
|
||||||
struct pnfs_block_extent *be,
|
struct pnfs_block_extent *be, bio_end_io_t end_io,
|
||||||
void (*end_io)(struct bio *, int err),
|
|
||||||
struct parallel_io *par, unsigned int offset, int *len)
|
struct parallel_io *par, unsigned int offset, int *len)
|
||||||
{
|
{
|
||||||
struct pnfs_block_dev *dev =
|
struct pnfs_block_dev *dev =
|
||||||
|
@ -183,11 +182,11 @@ retry:
|
||||||
return bio;
|
return bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bl_end_io_read(struct bio *bio, int err)
|
static void bl_end_io_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct parallel_io *par = bio->bi_private;
|
struct parallel_io *par = bio->bi_private;
|
||||||
|
|
||||||
if (err) {
|
if (bio->bi_error) {
|
||||||
struct nfs_pgio_header *header = par->data;
|
struct nfs_pgio_header *header = par->data;
|
||||||
|
|
||||||
if (!header->pnfs_error)
|
if (!header->pnfs_error)
|
||||||
|
@ -316,13 +315,12 @@ out:
|
||||||
return PNFS_ATTEMPTED;
|
return PNFS_ATTEMPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bl_end_io_write(struct bio *bio, int err)
|
static void bl_end_io_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct parallel_io *par = bio->bi_private;
|
struct parallel_io *par = bio->bi_private;
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct nfs_pgio_header *header = par->data;
|
struct nfs_pgio_header *header = par->data;
|
||||||
|
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
if (!header->pnfs_error)
|
if (!header->pnfs_error)
|
||||||
header->pnfs_error = -EIO;
|
header->pnfs_error = -EIO;
|
||||||
pnfs_set_lo_fail(header->lseg);
|
pnfs_set_lo_fail(header->lseg);
|
||||||
|
|
|
@ -338,12 +338,11 @@ void nilfs_add_checksums_on_logs(struct list_head *logs, u32 seed)
|
||||||
/*
|
/*
|
||||||
* BIO operations
|
* BIO operations
|
||||||
*/
|
*/
|
||||||
static void nilfs_end_bio_write(struct bio *bio, int err)
|
static void nilfs_end_bio_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct nilfs_segment_buffer *segbuf = bio->bi_private;
|
struct nilfs_segment_buffer *segbuf = bio->bi_private;
|
||||||
|
|
||||||
if (!uptodate)
|
if (bio->bi_error)
|
||||||
atomic_inc(&segbuf->sb_err);
|
atomic_inc(&segbuf->sb_err);
|
||||||
|
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
|
|
|
@ -372,14 +372,13 @@ static void o2hb_wait_on_io(struct o2hb_region *reg,
|
||||||
wait_for_completion(&wc->wc_io_complete);
|
wait_for_completion(&wc->wc_io_complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void o2hb_bio_end_io(struct bio *bio,
|
static void o2hb_bio_end_io(struct bio *bio)
|
||||||
int error)
|
|
||||||
{
|
{
|
||||||
struct o2hb_bio_wait_ctxt *wc = bio->bi_private;
|
struct o2hb_bio_wait_ctxt *wc = bio->bi_private;
|
||||||
|
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
mlog(ML_ERROR, "IO Error %d\n", error);
|
mlog(ML_ERROR, "IO Error %d\n", bio->bi_error);
|
||||||
wc->wc_error = error;
|
wc->wc_error = bio->bi_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
o2hb_bio_wait_dec(wc, 1);
|
o2hb_bio_wait_dec(wc, 1);
|
||||||
|
|
|
@ -351,12 +351,11 @@ xfs_imap_valid(
|
||||||
*/
|
*/
|
||||||
STATIC void
|
STATIC void
|
||||||
xfs_end_bio(
|
xfs_end_bio(
|
||||||
struct bio *bio,
|
struct bio *bio)
|
||||||
int error)
|
|
||||||
{
|
{
|
||||||
xfs_ioend_t *ioend = bio->bi_private;
|
xfs_ioend_t *ioend = bio->bi_private;
|
||||||
|
|
||||||
ioend->io_error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : error;
|
ioend->io_error = bio->bi_error;
|
||||||
|
|
||||||
/* Toss bio and pass work off to an xfsdatad thread */
|
/* Toss bio and pass work off to an xfsdatad thread */
|
||||||
bio->bi_private = NULL;
|
bio->bi_private = NULL;
|
||||||
|
|
|
@ -1096,8 +1096,7 @@ xfs_bwrite(
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
xfs_buf_bio_end_io(
|
xfs_buf_bio_end_io(
|
||||||
struct bio *bio,
|
struct bio *bio)
|
||||||
int error)
|
|
||||||
{
|
{
|
||||||
xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
|
xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
|
||||||
|
|
||||||
|
@ -1105,10 +1104,10 @@ xfs_buf_bio_end_io(
|
||||||
* don't overwrite existing errors - otherwise we can lose errors on
|
* don't overwrite existing errors - otherwise we can lose errors on
|
||||||
* buffers that require multiple bios to complete.
|
* buffers that require multiple bios to complete.
|
||||||
*/
|
*/
|
||||||
if (error) {
|
if (bio->bi_error) {
|
||||||
spin_lock(&bp->b_lock);
|
spin_lock(&bp->b_lock);
|
||||||
if (!bp->b_io_error)
|
if (!bp->b_io_error)
|
||||||
bp->b_io_error = error;
|
bp->b_io_error = bio->bi_error;
|
||||||
spin_unlock(&bp->b_lock);
|
spin_unlock(&bp->b_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,8 +195,6 @@ static inline bool bvec_gap_to_prev(struct bio_vec *bprv, unsigned int offset)
|
||||||
return offset || ((bprv->bv_offset + bprv->bv_len) & (PAGE_SIZE - 1));
|
return offset || ((bprv->bv_offset + bprv->bv_len) & (PAGE_SIZE - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define bio_io_error(bio) bio_endio((bio), -EIO)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drivers should _never_ use the all version - the bio may have been split
|
* drivers should _never_ use the all version - the bio may have been split
|
||||||
* before it got to the driver and the driver won't own all of it
|
* before it got to the driver and the driver won't own all of it
|
||||||
|
@ -426,7 +424,14 @@ static inline struct bio *bio_clone_kmalloc(struct bio *bio, gfp_t gfp_mask)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void bio_endio(struct bio *, int);
|
extern void bio_endio(struct bio *);
|
||||||
|
|
||||||
|
static inline void bio_io_error(struct bio *bio)
|
||||||
|
{
|
||||||
|
bio->bi_error = -EIO;
|
||||||
|
bio_endio(bio);
|
||||||
|
}
|
||||||
|
|
||||||
struct request_queue;
|
struct request_queue;
|
||||||
extern int bio_phys_segments(struct request_queue *, struct bio *);
|
extern int bio_phys_segments(struct request_queue *, struct bio *);
|
||||||
|
|
||||||
|
@ -717,7 +722,7 @@ extern void bio_integrity_free(struct bio *);
|
||||||
extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
|
extern int bio_integrity_add_page(struct bio *, struct page *, unsigned int, unsigned int);
|
||||||
extern bool bio_integrity_enabled(struct bio *bio);
|
extern bool bio_integrity_enabled(struct bio *bio);
|
||||||
extern int bio_integrity_prep(struct bio *);
|
extern int bio_integrity_prep(struct bio *);
|
||||||
extern void bio_integrity_endio(struct bio *, int);
|
extern void bio_integrity_endio(struct bio *);
|
||||||
extern void bio_integrity_advance(struct bio *, unsigned int);
|
extern void bio_integrity_advance(struct bio *, unsigned int);
|
||||||
extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
|
extern void bio_integrity_trim(struct bio *, unsigned int, unsigned int);
|
||||||
extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
|
extern int bio_integrity_clone(struct bio *, struct bio *, gfp_t);
|
||||||
|
|
|
@ -14,7 +14,7 @@ struct page;
|
||||||
struct block_device;
|
struct block_device;
|
||||||
struct io_context;
|
struct io_context;
|
||||||
struct cgroup_subsys_state;
|
struct cgroup_subsys_state;
|
||||||
typedef void (bio_end_io_t) (struct bio *, int);
|
typedef void (bio_end_io_t) (struct bio *);
|
||||||
typedef void (bio_destructor_t) (struct bio *);
|
typedef void (bio_destructor_t) (struct bio *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -53,6 +53,7 @@ struct bio {
|
||||||
|
|
||||||
struct bvec_iter bi_iter;
|
struct bvec_iter bi_iter;
|
||||||
|
|
||||||
|
int bi_error;
|
||||||
/* Number of segments in this BIO after
|
/* Number of segments in this BIO after
|
||||||
* physical address coalescing is performed.
|
* physical address coalescing is performed.
|
||||||
*/
|
*/
|
||||||
|
@ -111,7 +112,6 @@ struct bio {
|
||||||
/*
|
/*
|
||||||
* bio flags
|
* bio flags
|
||||||
*/
|
*/
|
||||||
#define BIO_UPTODATE 0 /* ok after I/O completion */
|
|
||||||
#define BIO_SEG_VALID 1 /* bi_phys_segments valid */
|
#define BIO_SEG_VALID 1 /* bi_phys_segments valid */
|
||||||
#define BIO_CLONED 2 /* doesn't own data */
|
#define BIO_CLONED 2 /* doesn't own data */
|
||||||
#define BIO_BOUNCED 3 /* bio is a bounce bio */
|
#define BIO_BOUNCED 3 /* bio is a bounce bio */
|
||||||
|
|
|
@ -373,9 +373,9 @@ static inline void mem_cgroup_uncharge_swap(swp_entry_t entry)
|
||||||
/* linux/mm/page_io.c */
|
/* linux/mm/page_io.c */
|
||||||
extern int swap_readpage(struct page *);
|
extern int swap_readpage(struct page *);
|
||||||
extern int swap_writepage(struct page *page, struct writeback_control *wbc);
|
extern int swap_writepage(struct page *page, struct writeback_control *wbc);
|
||||||
extern void end_swap_bio_write(struct bio *bio, int err);
|
extern void end_swap_bio_write(struct bio *bio);
|
||||||
extern int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
extern int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
||||||
void (*end_write_func)(struct bio *, int));
|
bio_end_io_t end_write_func);
|
||||||
extern int swap_set_page_dirty(struct page *page);
|
extern int swap_set_page_dirty(struct page *page);
|
||||||
|
|
||||||
int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
|
int add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
|
||||||
|
|
|
@ -227,27 +227,23 @@ static void hib_init_batch(struct hib_bio_batch *hb)
|
||||||
hb->error = 0;
|
hb->error = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hib_end_io(struct bio *bio, int error)
|
static void hib_end_io(struct bio *bio)
|
||||||
{
|
{
|
||||||
struct hib_bio_batch *hb = bio->bi_private;
|
struct hib_bio_batch *hb = bio->bi_private;
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct page *page = bio->bi_io_vec[0].bv_page;
|
struct page *page = bio->bi_io_vec[0].bv_page;
|
||||||
|
|
||||||
if (!uptodate || error) {
|
if (bio->bi_error) {
|
||||||
printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n",
|
printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n",
|
||||||
imajor(bio->bi_bdev->bd_inode),
|
imajor(bio->bi_bdev->bd_inode),
|
||||||
iminor(bio->bi_bdev->bd_inode),
|
iminor(bio->bi_bdev->bd_inode),
|
||||||
(unsigned long long)bio->bi_iter.bi_sector);
|
(unsigned long long)bio->bi_iter.bi_sector);
|
||||||
|
|
||||||
if (!error)
|
|
||||||
error = -EIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bio_data_dir(bio) == WRITE)
|
if (bio_data_dir(bio) == WRITE)
|
||||||
put_page(page);
|
put_page(page);
|
||||||
|
|
||||||
if (error && !hb->error)
|
if (bio->bi_error && !hb->error)
|
||||||
hb->error = error;
|
hb->error = bio->bi_error;
|
||||||
if (atomic_dec_and_test(&hb->count))
|
if (atomic_dec_and_test(&hb->count))
|
||||||
wake_up(&hb->wait);
|
wake_up(&hb->wait);
|
||||||
|
|
||||||
|
|
|
@ -778,9 +778,6 @@ static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
|
||||||
if (likely(!bt))
|
if (likely(!bt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!error && !bio_flagged(bio, BIO_UPTODATE))
|
|
||||||
error = EIO;
|
|
||||||
|
|
||||||
__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
|
__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
|
||||||
bio->bi_rw, what, error, 0, NULL);
|
bio->bi_rw, what, error, 0, NULL);
|
||||||
}
|
}
|
||||||
|
@ -887,8 +884,7 @@ static void blk_add_trace_split(void *ignore,
|
||||||
|
|
||||||
__blk_add_trace(bt, bio->bi_iter.bi_sector,
|
__blk_add_trace(bt, bio->bi_iter.bi_sector,
|
||||||
bio->bi_iter.bi_size, bio->bi_rw, BLK_TA_SPLIT,
|
bio->bi_iter.bi_size, bio->bi_rw, BLK_TA_SPLIT,
|
||||||
!bio_flagged(bio, BIO_UPTODATE),
|
bio->bi_error, sizeof(rpdu), &rpdu);
|
||||||
sizeof(rpdu), &rpdu);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -920,8 +916,8 @@ static void blk_add_trace_bio_remap(void *ignore,
|
||||||
r.sector_from = cpu_to_be64(from);
|
r.sector_from = cpu_to_be64(from);
|
||||||
|
|
||||||
__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
|
__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
|
||||||
bio->bi_rw, BLK_TA_REMAP,
|
bio->bi_rw, BLK_TA_REMAP, bio->bi_error,
|
||||||
!bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r);
|
sizeof(r), &r);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
12
mm/page_io.c
12
mm/page_io.c
|
@ -43,12 +43,11 @@ static struct bio *get_swap_bio(gfp_t gfp_flags,
|
||||||
return bio;
|
return bio;
|
||||||
}
|
}
|
||||||
|
|
||||||
void end_swap_bio_write(struct bio *bio, int err)
|
void end_swap_bio_write(struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct page *page = bio->bi_io_vec[0].bv_page;
|
struct page *page = bio->bi_io_vec[0].bv_page;
|
||||||
|
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
/*
|
/*
|
||||||
* We failed to write the page out to swap-space.
|
* We failed to write the page out to swap-space.
|
||||||
|
@ -69,12 +68,11 @@ void end_swap_bio_write(struct bio *bio, int err)
|
||||||
bio_put(bio);
|
bio_put(bio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void end_swap_bio_read(struct bio *bio, int err)
|
static void end_swap_bio_read(struct bio *bio)
|
||||||
{
|
{
|
||||||
const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
|
|
||||||
struct page *page = bio->bi_io_vec[0].bv_page;
|
struct page *page = bio->bi_io_vec[0].bv_page;
|
||||||
|
|
||||||
if (!uptodate) {
|
if (bio->bi_error) {
|
||||||
SetPageError(page);
|
SetPageError(page);
|
||||||
ClearPageUptodate(page);
|
ClearPageUptodate(page);
|
||||||
printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n",
|
printk(KERN_ALERT "Read-error on swap-device (%u:%u:%Lu)\n",
|
||||||
|
@ -254,7 +252,7 @@ static sector_t swap_page_sector(struct page *page)
|
||||||
}
|
}
|
||||||
|
|
||||||
int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
int __swap_writepage(struct page *page, struct writeback_control *wbc,
|
||||||
void (*end_write_func)(struct bio *, int))
|
bio_end_io_t end_write_func)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
int ret, rw = WRITE;
|
int ret, rw = WRITE;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче