aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorChristian Borntraeger <borntraeger@de.ibm.com>2008-01-31 09:53:53 -0500
committerRusty Russell <rusty@rustcorp.com.au>2008-02-04 07:50:10 -0500
commit4f3bf19c6e8164b441faaee476e734b4f612a78d (patch)
tree27d2c75ef0ce7e02fcf09d08ce20b0fe51e20362 /drivers/block
parent135da0b037984c0284acdf40aaf4f7f31eb5cbd0 (diff)
virtio_blk: Dont waste major numbers
Rusty, currently virtio_blk uses one major number per device. While this works quite well on most systems it is wasteful and will exhaust major numbers on larger installations. This patch allocates a major number on init and will use 16 minor numbers for each disk. That will allow ~64k virtio_blk disks. Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/virtio_blk.c28
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
11static unsigned char virtblk_index = 'a'; 12static unsigned char virtblk_index = 'a';
13static int major, minor;
14
12struct virtio_blk 15struct virtio_blk
13{ 16{
14 spinlock_t lock; 17 spinlock_t lock;
@@ -171,10 +174,13 @@ static struct block_device_operations virtblk_fops = {
171static int virtblk_probe(struct virtio_device *vdev) 174static 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
259out_put_disk: 261out_put_disk:
260 put_disk(vblk->disk); 262 put_disk(vblk->disk);
261out_unregister_blkdev:
262 unregister_blkdev(major, "virtblk");
263out_mempool: 263out_mempool:
264 mempool_destroy(vblk->pool); 264 mempool_destroy(vblk->pool);
265out_free_vq: 265out_free_vq:
@@ -304,11 +304,15 @@ static struct virtio_driver virtio_blk = {
304 304
305static int __init init(void) 305static 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
310static void __exit fini(void) 313static 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}
314module_init(init); 318module_init(init);