]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/block/xen-blkfront.c
blk-mq: introduce BLK_STS_DEV_RESOURCE
[mirror_ubuntu-bionic-kernel.git] / drivers / block / xen-blkfront.c
index 891265acb10ec3c0af6a2ddc9e76c14ccc70cfb2..a98f78b9c4c6eb74c9a7f23d7ccde1236f9daddc 100644 (file)
@@ -262,6 +262,7 @@ static DEFINE_SPINLOCK(minor_lock);
 
 static int blkfront_setup_indirect(struct blkfront_ring_info *rinfo);
 static void blkfront_gather_backend_features(struct blkfront_info *info);
+static int negotiate_mq(struct blkfront_info *info);
 
 static int get_id_from_freelist(struct blkfront_ring_info *rinfo)
 {
@@ -911,7 +912,7 @@ out_err:
 out_busy:
        blk_mq_stop_hw_queue(hctx);
        spin_unlock_irqrestore(&rinfo->ring_lock, flags);
-       return BLK_STS_RESOURCE;
+       return BLK_STS_DEV_RESOURCE;
 }
 
 static void blkif_complete_rq(struct request *rq)
@@ -1774,11 +1775,18 @@ static int talk_to_blkback(struct xenbus_device *dev,
        unsigned int i, max_page_order;
        unsigned int ring_page_order;
 
+       if (!info)
+               return -ENODEV;
+
        max_page_order = xenbus_read_unsigned(info->xbdev->otherend,
                                              "max-ring-page-order", 0);
        ring_page_order = min(xen_blkif_max_ring_order, max_page_order);
        info->nr_ring_pages = 1 << ring_page_order;
 
+       err = negotiate_mq(info);
+       if (err)
+               goto destroy_blkring;
+
        for (i = 0; i < info->nr_rings; i++) {
                struct blkfront_ring_info *rinfo = &info->rinfo[i];
 
@@ -1902,6 +1910,7 @@ static int negotiate_mq(struct blkfront_info *info)
        info->rinfo = kzalloc(sizeof(struct blkfront_ring_info) * info->nr_rings, GFP_KERNEL);
        if (!info->rinfo) {
                xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
+               info->nr_rings = 0;
                return -ENOMEM;
        }
 
@@ -1978,11 +1987,6 @@ static int blkfront_probe(struct xenbus_device *dev,
        }
 
        info->xbdev = dev;
-       err = negotiate_mq(info);
-       if (err) {
-               kfree(info);
-               return err;
-       }
 
        mutex_init(&info->mutex);
        info->vdevice = vdevice;
@@ -2099,10 +2103,6 @@ static int blkfront_resume(struct xenbus_device *dev)
 
        blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
 
-       err = negotiate_mq(info);
-       if (err)
-               return err;
-
        err = talk_to_blkback(dev, info);
        if (!err)
                blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings);
@@ -2472,6 +2472,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
 
        dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename);
 
+       if (!info)
+               return 0;
+
        blkif_free(info, 0);
 
        mutex_lock(&info->mutex);