diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2007-11-19 11:20:42 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2007-11-19 11:20:42 +1100 |
commit | 74b2553f1d13e60fb27063204bd5b6908a6f8494 (patch) | |
tree | cd35e82d16cf190ccd95362478a598314de639ce /drivers/block | |
parent | d1c856e0f1a4c946c6329cff126548ef4288735f (diff) | |
download | op-kernel-dev-74b2553f1d13e60fb27063204bd5b6908a6f8494.zip op-kernel-dev-74b2553f1d13e60fb27063204bd5b6908a6f8494.tar.gz |
virtio: fix module/device unloading
The virtio code never hooked through the ->remove callback. Although
noone supports device removal at the moment, this code is already
needed for module unloading.
This of course also revealed bugs in virtio_blk, virtio_net and lguest
unloading paths.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/virtio_blk.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 3cf7129..924ddd8 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -223,7 +223,7 @@ static int virtblk_probe(struct virtio_device *vdev) err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_CAPACITY, &cap); if (err) { dev_err(&vdev->dev, "Bad/missing capacity in config\n"); - goto out_put_disk; + goto out_cleanup_queue; } /* If capacity is too big, truncate with warning. */ @@ -239,7 +239,7 @@ static int virtblk_probe(struct virtio_device *vdev) blk_queue_max_segment_size(vblk->disk->queue, v); else if (err != -ENOENT) { dev_err(&vdev->dev, "Bad SIZE_MAX in config\n"); - goto out_put_disk; + goto out_cleanup_queue; } err = virtio_config_val(vdev, VIRTIO_CONFIG_BLK_F_SEG_MAX, &v); @@ -247,12 +247,14 @@ static int virtblk_probe(struct virtio_device *vdev) blk_queue_max_hw_segments(vblk->disk->queue, v); else if (err != -ENOENT) { dev_err(&vdev->dev, "Bad SEG_MAX in config\n"); - goto out_put_disk; + goto out_cleanup_queue; } add_disk(vblk->disk); return 0; +out_cleanup_queue: + blk_cleanup_queue(vblk->disk->queue); out_put_disk: put_disk(vblk->disk); out_unregister_blkdev: @@ -277,6 +279,8 @@ static void virtblk_remove(struct virtio_device *vdev) 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); } |