History

virtio-blk: use ida to allocate disk index

Based on a patch by Mark Wu <dwu@redhat.com> Current index allocation in virtio-blk is based on a monotonically increasing variable "index". This means we'll run out of numbers after a while. It also could cause confusion about the disk name in the case of hot-plugging disks. Change virtio-blk to use ida to allocate index, instead.

Michael S. Tsirkin committed 15 years ago

Commit a0eda621 parent c4853ef1 file · +24 −6Browse files

Unified · Split

drivers/block/virtio_blk.c+24−6
@@ -8,10 +8,13 @@ · 7 unmodified lines
8#include <linux/scatterlist.h>8#include <linux/scatterlist.h>
9#include <linux/string_helpers.h>9#include <linux/string_helpers.h>
10#include <scsi/scsi_cmnd.h>10#include <scsi/scsi_cmnd.h>
11#include <linux/idr.h>
11 12
12#define PART_BITS 413#define PART_BITS 4
13 14
14static int major, index;15static int major;
16static DEFINE_IDA(vd_index_ida);
17
15struct workqueue_struct *virtblk_wq;18struct workqueue_struct *virtblk_wq;
16 19
17struct virtio_blk20struct virtio_blk
@@ -35,6 +38,9 @@ struct virtio_blk · 17 unmodified lines
35 /* What host tells us, plus 2 for header & tailer. */38 /* What host tells us, plus 2 for header & tailer. */
36 unsigned int sg_elems;39 unsigned int sg_elems;
37 40
41 /* Ida index - used to track minor number allocations. */
42 int index;
43
38 /* Scatterlist: can be too big for stack. */44 /* Scatterlist: can be too big for stack. */
39 struct scatterlist sg[/*sg_elems*/];45 struct scatterlist sg[/*sg_elems*/];
40};46};
@@ -276,6 +282,11 @@ static int index_to_minor(int index) · 235 unmodified lines
276 return index << PART_BITS;282 return index << PART_BITS;
277}283}
278 284
285static int minor_to_index(int minor)
286{
287 return minor >> PART_BITS;
288}
289
279static ssize_t virtblk_serial_show(struct device *dev,290static ssize_t virtblk_serial_show(struct device *dev,
280 struct device_attribute *attr, char *buf)291 struct device_attribute *attr, char *buf)
281{292{
@@ -341,14 +352,17 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 59 unmodified lines
341{352{
342 struct virtio_blk *vblk;353 struct virtio_blk *vblk;
343 struct request_queue *q;354 struct request_queue *q;
344 int err;355 int err, index;
345 u64 cap;356 u64 cap;
346 u32 v, blk_size, sg_elems, opt_io_size;357 u32 v, blk_size, sg_elems, opt_io_size;
347 u16 min_io_size;358 u16 min_io_size;
348 u8 physical_block_exp, alignment_offset;359 u8 physical_block_exp, alignment_offset;
349 360
350 if (index_to_minor(index) >= 1 << MINORBITS)361 err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS),
351 return -ENOSPC;362 GFP_KERNEL);
363 if (err < 0)
364 goto out;
365 index = err;
352 366
353 /* We need to know how many segments before we allocate. */367 /* We need to know how many segments before we allocate. */
354 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,368 err = virtio_config_val(vdev, VIRTIO_BLK_F_SEG_MAX,
@@ -365,7 +379,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 10 unmodified lines
365 sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL);379 sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL);
366 if (!vblk) {380 if (!vblk) {
367 err = -ENOMEM;381 err = -ENOMEM;
368 goto out;382 goto out_free_index;
369 }383 }
370 384
371 INIT_LIST_HEAD(&vblk->reqs);385 INIT_LIST_HEAD(&vblk->reqs);
@@ -421,7 +435,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 49 unmodified lines
421 vblk->disk->private_data = vblk;435 vblk->disk->private_data = vblk;
422 vblk->disk->fops = &virtblk_fops;436 vblk->disk->fops = &virtblk_fops;
423 vblk->disk->driverfs_dev = &vdev->dev;437 vblk->disk->driverfs_dev = &vdev->dev;
424 index++;438 vblk->index = index;
425 439
426 /* configure queue flush support */440 /* configure queue flush support */
427 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))441 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
@@ -516,6 +530,8 @@ out_free_vq: · 88 unmodified lines
516 vdev->config->del_vqs(vdev);530 vdev->config->del_vqs(vdev);
517out_free_vblk:531out_free_vblk:
518 kfree(vblk);532 kfree(vblk);
533out_free_index:
534 ida_simple_remove(&vd_index_ida, index);
519out:535out:
520 return err;536 return err;
521}537}
@@ -523,6 +539,7 @@ out: · 1 unmodified line
523static void __devexit virtblk_remove(struct virtio_device *vdev)539static void __devexit virtblk_remove(struct virtio_device *vdev)
524{540{
525 struct virtio_blk *vblk = vdev->priv;541 struct virtio_blk *vblk = vdev->priv;
542 int index = vblk->index;
526 543
527 flush_work(&vblk->config_work);544 flush_work(&vblk->config_work);
528 545
@@ -538,6 +555,7 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) · 9 unmodified lines
538 mempool_destroy(vblk->pool);555 mempool_destroy(vblk->pool);
539 vdev->config->del_vqs(vdev);556 vdev->config->del_vqs(vdev);
540 kfree(vblk);557 kfree(vblk);
558 ida_simple_remove(&vd_index_ida, index);
541}559}
542 560
543static const struct virtio_device_id id_table[] = {561static const struct virtio_device_id id_table[] = {