diff options
author | Ren Mingxin <renmx@cn.fujitsu.com> | 2012-04-10 15:28:05 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2012-04-12 10:37:05 +0300 |
commit | c0aa3e0916d7e531e69b02e426f7162dfb1c6c0f (patch) | |
tree | 08968a635c4d43fb16c071cbcdbe25b302b85924 /drivers/block/virtio_blk.c | |
parent | 5e7045b010bdb56abbfe5714e8debf03a024c016 (diff) | |
download | linux-c0aa3e0916d7e531e69b02e426f7162dfb1c6c0f.tar.bz2 |
virtio_blk: helper function to format disk names
The current virtio block's naming algorithm just supports 18278
(26^3 + 26^2 + 26) disks. If there are more virtio blocks,
there will be disks with the same name.
Based on commit 3e1a7ff8a0a7b948f2684930166954f9e8e776fe, add
a function "virtblk_name_format()" for virtio block to support mass
of disks naming.
Notes:
- Our naming scheme is ugly. We are stuck with it
for virtio but don't use it for any new driver:
new drivers should name their devices PREFIX%d
where the sequence number can be allocated by ida
- sd_format_disk_name has exactly the same logic.
Moving it to a central place was deferred over worries
that this will make people keep using the legacy naming
in new drivers.
We kept code idential in case someone wants to deduplicate later.
Signed-off-by: Ren Mingxin <renmx@cn.fujitsu.com>
Acked-by: Asias He <asias@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r-- | drivers/block/virtio_blk.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index c4a60badf252..303779cb1fa2 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -374,6 +374,34 @@ static int init_vq(struct virtio_blk *vblk) return err; } +/* + * Legacy naming scheme used for virtio devices. We are stuck with it for + * virtio blk but don't ever use it for any new driver. + */ +static int virtblk_name_format(char *prefix, int index, char *buf, int buflen) +{ + const int base = 'z' - 'a' + 1; + char *begin = buf + strlen(prefix); + char *end = buf + buflen; + char *p; + int unit; + + p = end - 1; + *p = '\0'; + unit = base; + do { + if (p == begin) + return -EINVAL; + *--p = 'a' + (index % unit); + index = (index / unit) - 1; + } while (index >= 0); + + memmove(begin, p, end - p); + memcpy(buf, prefix, strlen(prefix)); + + return 0; +} + static int __devinit virtblk_probe(struct virtio_device *vdev) { struct virtio_blk *vblk; @@ -442,18 +470,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev) q->queuedata = vblk; - if (index < 26) { - sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); - } else if (index < (26 + 1) * 26) { - sprintf(vblk->disk->disk_name, "vd%c%c", - 'a' + index / 26 - 1, 'a' + index % 26); - } else { - const unsigned int m1 = (index / 26 - 1) / 26 - 1; - const unsigned int m2 = (index / 26 - 1) % 26; - const unsigned int m3 = index % 26; - sprintf(vblk->disk->disk_name, "vd%c%c%c", - 'a' + m1, 'a' + m2, 'a' + m3); - } + virtblk_name_format("vd", index, vblk->disk->disk_name, DISK_NAME_LEN); vblk->disk->major = major; vblk->disk->first_minor = index_to_minor(index); |