]> 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 2a305c1a2d881a78e8251288908a7bafcc840af9..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;
@@ -717,72 +720,6 @@ int bdev_write_page(struct block_device *bdev, sector_t sector,
 }
 EXPORT_SYMBOL_GPL(bdev_write_page);
 
-int bdev_dax_pgoff(struct block_device *bdev, sector_t sector, size_t size,
-               pgoff_t *pgoff)
-{
-       phys_addr_t phys_off = (get_start_sect(bdev) + sector) * 512;
-
-       if (pgoff)
-               *pgoff = PHYS_PFN(phys_off);
-       if (phys_off % PAGE_SIZE || size % PAGE_SIZE)
-               return -EINVAL;
-       return 0;
-}
-EXPORT_SYMBOL(bdev_dax_pgoff);
-
-/**
- * bdev_dax_supported() - Check if the device supports dax for filesystem
- * @sb: The superblock of the device
- * @blocksize: The block size of the device
- *
- * This is a library function for filesystems to check if the block device
- * can be mounted with dax option.
- *
- * Return: negative errno if unsupported, 0 if supported.
- */
-int bdev_dax_supported(struct super_block *sb, int blocksize)
-{
-       struct block_device *bdev = sb->s_bdev;
-       struct dax_device *dax_dev;
-       pgoff_t pgoff;
-       int err, id;
-       void *kaddr;
-       pfn_t pfn;
-       long len;
-
-       if (blocksize != PAGE_SIZE) {
-               vfs_msg(sb, KERN_ERR, "error: unsupported blocksize for dax");
-               return -EINVAL;
-       }
-
-       err = bdev_dax_pgoff(bdev, 0, PAGE_SIZE, &pgoff);
-       if (err) {
-               vfs_msg(sb, KERN_ERR, "error: unaligned partition for dax");
-               return err;
-       }
-
-       dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
-       if (!dax_dev) {
-               vfs_msg(sb, KERN_ERR, "error: device does not support dax");
-               return -EOPNOTSUPP;
-       }
-
-       id = dax_read_lock();
-       len = dax_direct_access(dax_dev, pgoff, 1, &kaddr, &pfn);
-       dax_read_unlock(id);
-
-       put_dax(dax_dev);
-
-       if (len < 1) {
-               vfs_msg(sb, KERN_ERR,
-                               "error: dax access failed (%ld)", len);
-               return len < 0 ? len : -EIO;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(bdev_dax_supported);
-
 /*
  * pseudo-fs
  */