]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - fs/block_dev.c
blk-mq: Make it safe to quiesce and unquiesce from an interrupt handler
[karo-tx-linux.git] / fs / block_dev.c
index 519599dddd3692ee373a9eb00d95d5757556ad42..dd91c99e9ba05932d88a96f17250a91cbb5a6c10 100644 (file)
@@ -262,8 +262,8 @@ __blkdev_direct_IO_simple(struct kiocb *iocb, struct iov_iter *iter,
        if (vecs != inline_vecs)
                kfree(vecs);
 
-       if (unlikely(bio.bi_error))
-               return bio.bi_error;
+       if (unlikely(bio.bi_status))
+               return blk_status_to_errno(bio.bi_status);
        return ret;
 }
 
@@ -288,16 +288,18 @@ static void blkdev_bio_end_io(struct bio *bio)
        bool should_dirty = dio->should_dirty;
 
        if (dio->multi_bio && !atomic_dec_and_test(&dio->ref)) {
-               if (bio->bi_error && !dio->bio.bi_error)
-                       dio->bio.bi_error = bio->bi_error;
+               if (bio->bi_status && !dio->bio.bi_status)
+                       dio->bio.bi_status = bio->bi_status;
        } else {
                if (!dio->is_sync) {
                        struct kiocb *iocb = dio->iocb;
-                       ssize_t ret = dio->bio.bi_error;
+                       ssize_t ret;
 
-                       if (likely(!ret)) {
+                       if (likely(!dio->bio.bi_status)) {
                                ret = dio->size;
                                iocb->ki_pos += ret;
+                       } else {
+                               ret = blk_status_to_errno(dio->bio.bi_status);
                        }
 
                        dio->iocb->ki_complete(iocb, ret, 0);
@@ -334,7 +336,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
        bool is_read = (iov_iter_rw(iter) == READ), is_sync;
        loff_t pos = iocb->ki_pos;
        blk_qc_t qc = BLK_QC_T_NONE;
-       int ret;
+       int ret = 0;
 
        if ((pos | iov_iter_alignment(iter)) &
            (bdev_logical_block_size(bdev) - 1))
@@ -363,7 +365,7 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
 
                ret = bio_iov_iter_get_pages(bio, iter);
                if (unlikely(ret)) {
-                       bio->bi_error = ret;
+                       bio->bi_status = BLK_STS_IOERR;
                        bio_endio(bio);
                        break;
                }
@@ -412,7 +414,8 @@ __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter, int nr_pages)
        }
        __set_current_state(TASK_RUNNING);
 
-       ret = dio->bio.bi_error;
+       if (!ret)
+               ret = blk_status_to_errno(dio->bio.bi_status);
        if (likely(!ret))
                ret = dio->size;
 
@@ -436,7 +439,7 @@ blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
 
 static __init int blkdev_init(void)
 {
-       blkdev_dio_pool = bioset_create(4, offsetof(struct blkdev_dio, bio));
+       blkdev_dio_pool = bioset_create(4, offsetof(struct blkdev_dio, bio), BIOSET_NEED_BVECS);
        if (!blkdev_dio_pool)
                return -ENOMEM;
        return 0;