static int blkif_ioctl(struct block_device *bdev, fmode_t mode,
                       unsigned command, unsigned long argument)
 {
-       struct blkfront_info *info = bdev->bd_disk->private_data;
        int i;
 
-       dev_dbg(&info->xbdev->dev, "command: 0x%x, argument: 0x%lx\n",
-               command, (long)argument);
-
        switch (command) {
        case CDROMMULTISESSION:
-               dev_dbg(&info->xbdev->dev, "FIXME: support multisession CDs later\n");
                for (i = 0; i < sizeof(struct cdrom_multisession); i++)
                        if (put_user(0, (char __user *)(argument + i)))
                                return -EFAULT;
                return 0;
-
-       case CDROM_GET_CAPABILITY: {
-               struct gendisk *gd = info->gd;
-               if (gd->flags & GENHD_FL_CD)
+       case CDROM_GET_CAPABILITY:
+               if (bdev->bd_disk->flags & GENHD_FL_CD)
                        return 0;
                return -EINVAL;
-       }
-
        default:
-               /*printk(KERN_ALERT "ioctl %08x not supported by Xen blkdev\n",
-                 command);*/
-               return -EINVAL; /* same return as native Linux */
+               return -EINVAL;
        }
-
-       return 0;
 }
 
 static unsigned long blkif_ring_get_request(struct blkfront_ring_info *rinfo,
        return err;
 }
 
-static void xlvbd_release_gendisk(struct blkfront_info *info)
-{
-       unsigned int minor, nr_minors, i;
-       struct blkfront_ring_info *rinfo;
-
-       if (info->rq == NULL)
-               return;
-
-       /* No more blkif_request(). */
-       blk_mq_stop_hw_queues(info->rq);
-
-       for_each_rinfo(info, rinfo, i) {
-               /* No more gnttab callback work. */
-               gnttab_cancel_free_callback(&rinfo->callback);
-
-               /* Flush gnttab callback work. Must be done with no locks held. */
-               flush_work(&rinfo->work);
-       }
-
-       del_gendisk(info->gd);
-
-       minor = info->gd->first_minor;
-       nr_minors = info->gd->minors;
-       xlbd_release_minors(minor, nr_minors);
-
-       blk_cleanup_disk(info->gd);
-       info->gd = NULL;
-       blk_mq_free_tag_set(&info->tag_set);
-}
-
 /* Already hold rinfo->ring_lock. */
 static inline void kick_pending_request_queues_locked(struct blkfront_ring_info *rinfo)
 {
        return err;
 }
 
-static void free_info(struct blkfront_info *info)
-{
-       list_del(&info->info_list);
-       kfree(info);
-}
-
 /* Common code used when first setting up, and when resuming. */
 static int talk_to_blkback(struct xenbus_device *dev,
                           struct blkfront_info *info)
                xenbus_dev_fatal(dev, err, "%s", message);
  destroy_blkring:
        blkif_free(info, 0);
-
-       mutex_lock(&blkfront_mutex);
-       free_info(info);
-       mutex_unlock(&blkfront_mutex);
-
-       dev_set_drvdata(&dev->dev, NULL);
-
        return err;
 }
 
 static void blkfront_closing(struct blkfront_info *info)
 {
        struct xenbus_device *xbdev = info->xbdev;
-       struct block_device *bdev = NULL;
-
-       mutex_lock(&info->mutex);
+       struct blkfront_ring_info *rinfo;
+       unsigned int i;
 
-       if (xbdev->state == XenbusStateClosing) {
-               mutex_unlock(&info->mutex);
+       if (xbdev->state == XenbusStateClosing)
                return;
-       }
 
-       if (info->gd)
-               bdev = bdgrab(info->gd->part0);
-
-       mutex_unlock(&info->mutex);
-
-       if (!bdev) {
-               xenbus_frontend_closed(xbdev);
-               return;
-       }
+       /* No more blkif_request(). */
+       blk_mq_stop_hw_queues(info->rq);
+       blk_set_queue_dying(info->rq);
+       set_capacity(info->gd, 0);
 
-       mutex_lock(&bdev->bd_disk->open_mutex);
+       for_each_rinfo(info, rinfo, i) {
+               /* No more gnttab callback work. */
+               gnttab_cancel_free_callback(&rinfo->callback);
 
-       if (bdev->bd_openers) {
-               xenbus_dev_error(xbdev, -EBUSY,
-                                "Device in use; refusing to close");
-               xenbus_switch_state(xbdev, XenbusStateClosing);
-       } else {
-               xlvbd_release_gendisk(info);
-               xenbus_frontend_closed(xbdev);
+               /* Flush gnttab callback work. Must be done with no locks held. */
+               flush_work(&rinfo->work);
        }
 
-       mutex_unlock(&bdev->bd_disk->open_mutex);
-       bdput(bdev);
+       xenbus_frontend_closed(xbdev);
 }
 
 static void blkfront_setup_discard(struct blkfront_info *info)
                        break;
                fallthrough;
        case XenbusStateClosing:
-               if (info)
-                       blkfront_closing(info);
+               blkfront_closing(info);
                break;
        }
 }
 static int blkfront_remove(struct xenbus_device *xbdev)
 {
        struct blkfront_info *info = dev_get_drvdata(&xbdev->dev);
-       struct block_device *bdev = NULL;
-       struct gendisk *disk;
 
        dev_dbg(&xbdev->dev, "%s removed", xbdev->nodename);
 
-       if (!info)
-               return 0;
-
-       blkif_free(info, 0);
-
-       mutex_lock(&info->mutex);
-
-       disk = info->gd;
-       if (disk)
-               bdev = bdgrab(disk->part0);
-
-       info->xbdev = NULL;
-       mutex_unlock(&info->mutex);
-
-       if (!bdev) {
-               mutex_lock(&blkfront_mutex);
-               free_info(info);
-               mutex_unlock(&blkfront_mutex);
-               return 0;
-       }
-
-       /*
-        * The xbdev was removed before we reached the Closed
-        * state. See if it's safe to remove the disk. If the bdev
-        * isn't closed yet, we let release take care of it.
-        */
-
-       mutex_lock(&disk->open_mutex);
-       info = disk->private_data;
-
-       dev_warn(disk_to_dev(disk),
-                "%s was hot-unplugged, %d stale handles\n",
-                xbdev->nodename, bdev->bd_openers);
+       del_gendisk(info->gd);
 
-       if (info && !bdev->bd_openers) {
-               xlvbd_release_gendisk(info);
-               disk->private_data = NULL;
-               mutex_lock(&blkfront_mutex);
-               free_info(info);
-               mutex_unlock(&blkfront_mutex);
-       }
+       mutex_lock(&blkfront_mutex);
+       list_del(&info->info_list);
+       mutex_unlock(&blkfront_mutex);
 
-       mutex_unlock(&disk->open_mutex);
-       bdput(bdev);
+       blkif_free(info, 0);
+       xlbd_release_minors(info->gd->first_minor, info->gd->minors);
+       blk_cleanup_disk(info->gd);
+       blk_mq_free_tag_set(&info->tag_set);
 
+       kfree(info);
        return 0;
 }
 
        return info->is_ready && info->xbdev;
 }
 
-static int blkif_open(struct block_device *bdev, fmode_t mode)
-{
-       struct gendisk *disk = bdev->bd_disk;
-       struct blkfront_info *info;
-       int err = 0;
-
-       mutex_lock(&blkfront_mutex);
-
-       info = disk->private_data;
-       if (!info) {
-               /* xbdev gone */
-               err = -ERESTARTSYS;
-               goto out;
-       }
-
-       mutex_lock(&info->mutex);
-
-       if (!info->gd)
-               /* xbdev is closed */
-               err = -ERESTARTSYS;
-
-       mutex_unlock(&info->mutex);
-
-out:
-       mutex_unlock(&blkfront_mutex);
-       return err;
-}
-
-static void blkif_release(struct gendisk *disk, fmode_t mode)
-{
-       struct blkfront_info *info = disk->private_data;
-       struct xenbus_device *xbdev;
-
-       mutex_lock(&blkfront_mutex);
-       if (disk->part0->bd_openers)
-               goto out_mutex;
-
-       /*
-        * Check if we have been instructed to close. We will have
-        * deferred this request, because the bdev was still open.
-        */
-
-       mutex_lock(&info->mutex);
-       xbdev = info->xbdev;
-
-       if (xbdev && xbdev->state == XenbusStateClosing) {
-               /* pending switch to state closed */
-               dev_info(disk_to_dev(disk), "releasing disk\n");
-               xlvbd_release_gendisk(info);
-               xenbus_frontend_closed(info->xbdev);
-       }
-
-       mutex_unlock(&info->mutex);
-
-       if (!xbdev) {
-               /* sudden device removal */
-               dev_info(disk_to_dev(disk), "releasing disk\n");
-               xlvbd_release_gendisk(info);
-               disk->private_data = NULL;
-               free_info(info);
-       }
-
-out_mutex:
-       mutex_unlock(&blkfront_mutex);
-}
-
 static const struct block_device_operations xlvbd_block_fops =
 {
        .owner = THIS_MODULE,
-       .open = blkif_open,
-       .release = blkif_release,
        .getgeo = blkif_getgeo,
        .ioctl = blkif_ioctl,
        .compat_ioctl = blkdev_compat_ptr_ioctl,