diff options
| -rw-r--r-- | drivers/block/virtio_blk.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index d2fe679519e4..559c322c4ffa 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
| @@ -7,8 +7,11 @@ | |||
| 7 | #include <linux/scatterlist.h> | 7 | #include <linux/scatterlist.h> |
| 8 | 8 | ||
| 9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) | 9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) |
| 10 | #define PART_BITS 4 | ||
| 10 | 11 | ||
| 11 | static unsigned char virtblk_index = 'a'; | 12 | static unsigned char virtblk_index = 'a'; |
| 13 | static int major, minor; | ||
| 14 | |||
| 12 | struct virtio_blk | 15 | struct virtio_blk |
| 13 | { | 16 | { |
| 14 | spinlock_t lock; | 17 | spinlock_t lock; |
| @@ -171,10 +174,13 @@ static struct block_device_operations virtblk_fops = { | |||
| 171 | static int virtblk_probe(struct virtio_device *vdev) | 174 | static int virtblk_probe(struct virtio_device *vdev) |
| 172 | { | 175 | { |
| 173 | struct virtio_blk *vblk; | 176 | struct virtio_blk *vblk; |
| 174 | int err, major; | 177 | int err; |
| 175 | u64 cap; | 178 | u64 cap; |
| 176 | u32 v; | 179 | u32 v; |
| 177 | 180 | ||
| 181 | if (minor >= 1 << MINORBITS) | ||
| 182 | return -ENOSPC; | ||
| 183 | |||
| 178 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); | 184 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); |
| 179 | if (!vblk) { | 185 | if (!vblk) { |
| 180 | err = -ENOMEM; | 186 | err = -ENOMEM; |
| @@ -198,17 +204,11 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 198 | goto out_free_vq; | 204 | goto out_free_vq; |
| 199 | } | 205 | } |
| 200 | 206 | ||
| 201 | major = register_blkdev(0, "virtblk"); | ||
| 202 | if (major < 0) { | ||
| 203 | err = major; | ||
| 204 | goto out_mempool; | ||
| 205 | } | ||
| 206 | |||
| 207 | /* FIXME: How many partitions? How long is a piece of string? */ | 207 | /* FIXME: How many partitions? How long is a piece of string? */ |
| 208 | vblk->disk = alloc_disk(1 << 4); | 208 | vblk->disk = alloc_disk(1 << PART_BITS); |
| 209 | if (!vblk->disk) { | 209 | if (!vblk->disk) { |
| 210 | err = -ENOMEM; | 210 | err = -ENOMEM; |
| 211 | goto out_unregister_blkdev; | 211 | goto out_mempool; |
| 212 | } | 212 | } |
| 213 | 213 | ||
| 214 | vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); | 214 | vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock); |
| @@ -219,10 +219,12 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 219 | 219 | ||
| 220 | sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); | 220 | sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); |
| 221 | vblk->disk->major = major; | 221 | vblk->disk->major = major; |
| 222 | vblk->disk->first_minor = 0; | 222 | vblk->disk->first_minor = minor; |
| 223 | vblk->disk->private_data = vblk; | 223 | vblk->disk->private_data = vblk; |
| 224 | vblk->disk->fops = &virtblk_fops; | 224 | vblk->disk->fops = &virtblk_fops; |
| 225 | 225 | ||
| 226 | minor += 1 << PART_BITS; | ||
| 227 | |||
| 226 | /* If barriers are supported, tell block layer that queue is ordered */ | 228 | /* If barriers are supported, tell block layer that queue is ordered */ |
| 227 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) | 229 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) |
| 228 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); | 230 | blk_queue_ordered(vblk->disk->queue, QUEUE_ORDERED_TAG, NULL); |
| @@ -258,8 +260,6 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
| 258 | 260 | ||
| 259 | out_put_disk: | 261 | out_put_disk: |
| 260 | put_disk(vblk->disk); | 262 | put_disk(vblk->disk); |
| 261 | out_unregister_blkdev: | ||
| 262 | unregister_blkdev(major, "virtblk"); | ||
| 263 | out_mempool: | 263 | out_mempool: |
| 264 | mempool_destroy(vblk->pool); | 264 | mempool_destroy(vblk->pool); |
| 265 | out_free_vq: | 265 | out_free_vq: |
| @@ -304,11 +304,15 @@ static struct virtio_driver virtio_blk = { | |||
| 304 | 304 | ||
| 305 | static int __init init(void) | 305 | static int __init init(void) |
| 306 | { | 306 | { |
| 307 | major = register_blkdev(0, "virtblk"); | ||
| 308 | if (major < 0) | ||
| 309 | return major; | ||
| 307 | return register_virtio_driver(&virtio_blk); | 310 | return register_virtio_driver(&virtio_blk); |
| 308 | } | 311 | } |
| 309 | 312 | ||
| 310 | static void __exit fini(void) | 313 | static void __exit fini(void) |
| 311 | { | 314 | { |
| 315 | unregister_blkdev(major, "virtblk"); | ||
| 312 | unregister_virtio_driver(&virtio_blk); | 316 | unregister_virtio_driver(&virtio_blk); |
| 313 | } | 317 | } |
| 314 | module_init(init); | 318 | module_init(init); |
