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
88 #include <linux/scatterlist.h>
99 #include <linux/string_helpers.h>
1010 #include <scsi/scsi_cmnd.h>
11+#include <linux/idr.h>
1112
1213 #define PART_BITS 4
1314
14−static int major, index;
15+static int major;
16+static DEFINE_IDA(vd_index_ida);
17+
1518 struct workqueue_struct *virtblk_wq;
1619
1720 struct virtio_blk
@@ -35,6 +38,9 @@ struct virtio_blk · 17 unmodified lines
3538 /* What host tells us, plus 2 for header & tailer. */
3639 unsigned int sg_elems;
3740
41+ /* Ida index - used to track minor number allocations. */
42+ int index;
43+
3844 /* Scatterlist: can be too big for stack. */
3945 struct scatterlist sg[/*sg_elems*/];
4046 };
@@ -276,6 +282,11 @@ static int index_to_minor(int index) · 235 unmodified lines
276282 return index << PART_BITS;
277283 }
278284
285+static int minor_to_index(int minor)
286+{
287+ return minor >> PART_BITS;
288+}
289+
279290 static ssize_t virtblk_serial_show(struct device *dev,
280291 struct device_attribute *attr, char *buf)
281292 {
@@ -341,14 +352,17 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 59 unmodified lines
341352 {
342353 struct virtio_blk *vblk;
343354 struct request_queue *q;
344− int err;
355+ int err, index;
345356 u64 cap;
346357 u32 v, blk_size, sg_elems, opt_io_size;
347358 u16 min_io_size;
348359 u8 physical_block_exp, alignment_offset;
349360
350− if (index_to_minor(index) >= 1 << MINORBITS)
351− return -ENOSPC;
361+ err = ida_simple_get(&vd_index_ida, 0, minor_to_index(1 << MINORBITS),
362+ GFP_KERNEL);
363+ if (err < 0)
364+ goto out;
365+ index = err;
352366
353367 /* We need to know how many segments before we allocate. */
354368 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
365379 sizeof(vblk->sg[0]) * sg_elems, GFP_KERNEL);
366380 if (!vblk) {
367381 err = -ENOMEM;
368− goto out;
382+ goto out_free_index;
369383 }
370384
371385 INIT_LIST_HEAD(&vblk->reqs);
@@ -421,7 +435,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) · 49 unmodified lines
421435 vblk->disk->private_data = vblk;
422436 vblk->disk->fops = &virtblk_fops;
423437 vblk->disk->driverfs_dev = &vdev->dev;
424− index++;
438+ vblk->index = index;
425439
426440 /* configure queue flush support */
427441 if (virtio_has_feature(vdev, VIRTIO_BLK_F_FLUSH))
@@ -516,6 +530,8 @@ out_free_vq: · 88 unmodified lines
516530 vdev->config->del_vqs(vdev);
517531 out_free_vblk:
518532 kfree(vblk);
533+out_free_index:
534+ ida_simple_remove(&vd_index_ida, index);
519535 out:
520536 return err;
521537 }
@@ -523,6 +539,7 @@ out: · 1 unmodified line
523539 static void __devexit virtblk_remove(struct virtio_device *vdev)
524540 {
525541 struct virtio_blk *vblk = vdev->priv;
542+ int index = vblk->index;
526543
527544 flush_work(&vblk->config_work);
528545
@@ -538,6 +555,7 @@ static void __devexit virtblk_remove(struct virtio_device *vdev) · 9 unmodified lines
538555 mempool_destroy(vblk->pool);
539556 vdev->config->del_vqs(vdev);
540557 kfree(vblk);
558+ ida_simple_remove(&vd_index_ida, index);
541559 }
542560
543561 static const struct virtio_device_id id_table[] = {