summaryrefslogtreecommitdiff
path: root/drivers/block/virtio_blk.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:50:03 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 23:50:03 +1100
commit6e5aa7efb27aec7e55b6463fa2c8db594c4226fa (patch)
tree060a955e711ac224136157a5410e88dcdab965af /drivers/block/virtio_blk.c
parentb3369c1fb410fddeb38a404316c861395f6d6ae8 (diff)
downloadlinux-3.10-6e5aa7efb27aec7e55b6463fa2c8db594c4226fa.tar.gz
linux-3.10-6e5aa7efb27aec7e55b6463fa2c8db594c4226fa.tar.bz2
linux-3.10-6e5aa7efb27aec7e55b6463fa2c8db594c4226fa.zip
virtio: reset function
A reset function solves three problems: 1) It allows us to renegotiate features, eg. if we want to upgrade a guest driver without rebooting the guest. 2) It gives us a clean way of shutting down virtqueues: after a reset, we know that the buffers won't be used by the host, and 3) It helps the guest recover from messed-up drivers. So we remove the ->shutdown hook, and the only way we now remove feature bits is via reset. We leave it to the driver to do the reset before it deletes queues: the balloon driver, for example, needs to chat to the host in its remove function. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r--drivers/block/virtio_blk.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 54a8017ad48..6143337527e 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -264,12 +264,16 @@ static void virtblk_remove(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
int major = vblk->disk->major;
+ /* Nothing should be pending. */
BUG_ON(!list_empty(&vblk->reqs));
+
+ /* Stop all the virtqueues. */
+ vdev->config->reset(vdev);
+
blk_cleanup_queue(vblk->disk->queue);
put_disk(vblk->disk);
unregister_blkdev(major, "virtblk");
mempool_destroy(vblk->pool);
- /* There should be nothing in the queue now, so no need to shutdown */
vdev->config->del_vq(vblk->vq);
kfree(vblk);
}