diff options
Diffstat (limited to 'drivers/block/virtio_blk.c')
-rw-r--r-- | drivers/block/virtio_blk.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 559c322c4ffa..3b1a68d6eddb 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c | |||
@@ -9,8 +9,7 @@ | |||
9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) | 9 | #define VIRTIO_MAX_SG (3+MAX_PHYS_SEGMENTS) |
10 | #define PART_BITS 4 | 10 | #define PART_BITS 4 |
11 | 11 | ||
12 | static unsigned char virtblk_index = 'a'; | 12 | static int major, index; |
13 | static int major, minor; | ||
14 | 13 | ||
15 | struct virtio_blk | 14 | struct virtio_blk |
16 | { | 15 | { |
@@ -171,6 +170,11 @@ static struct block_device_operations virtblk_fops = { | |||
171 | .getgeo = virtblk_getgeo, | 170 | .getgeo = virtblk_getgeo, |
172 | }; | 171 | }; |
173 | 172 | ||
173 | static int index_to_minor(int index) | ||
174 | { | ||
175 | return index << PART_BITS; | ||
176 | } | ||
177 | |||
174 | static int virtblk_probe(struct virtio_device *vdev) | 178 | static int virtblk_probe(struct virtio_device *vdev) |
175 | { | 179 | { |
176 | struct virtio_blk *vblk; | 180 | struct virtio_blk *vblk; |
@@ -178,7 +182,7 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
178 | u64 cap; | 182 | u64 cap; |
179 | u32 v; | 183 | u32 v; |
180 | 184 | ||
181 | if (minor >= 1 << MINORBITS) | 185 | if (index_to_minor(index) >= 1 << MINORBITS) |
182 | return -ENOSPC; | 186 | return -ENOSPC; |
183 | 187 | ||
184 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); | 188 | vdev->priv = vblk = kmalloc(sizeof(*vblk), GFP_KERNEL); |
@@ -217,13 +221,24 @@ static int virtblk_probe(struct virtio_device *vdev) | |||
217 | goto out_put_disk; | 221 | goto out_put_disk; |
218 | } | 222 | } |
219 | 223 | ||
220 | sprintf(vblk->disk->disk_name, "vd%c", virtblk_index++); | 224 | if (index < 26) { |
225 | sprintf(vblk->disk->disk_name, "vd%c", 'a' + index % 26); | ||
226 | } else if (index < (26 + 1) * 26) { | ||
227 | sprintf(vblk->disk->disk_name, "vd%c%c", | ||
228 | 'a' + index / 26 - 1, 'a' + index % 26); | ||
229 | } else { | ||
230 | const unsigned int m1 = (index / 26 - 1) / 26 - 1; | ||
231 | const unsigned int m2 = (index / 26 - 1) % 26; | ||
232 | const unsigned int m3 = index % 26; | ||
233 | sprintf(vblk->disk->disk_name, "vd%c%c%c", | ||
234 | 'a' + m1, 'a' + m2, 'a' + m3); | ||
235 | } | ||
236 | |||
221 | vblk->disk->major = major; | 237 | vblk->disk->major = major; |
222 | vblk->disk->first_minor = minor; | 238 | vblk->disk->first_minor = index_to_minor(index); |
223 | vblk->disk->private_data = vblk; | 239 | vblk->disk->private_data = vblk; |
224 | vblk->disk->fops = &virtblk_fops; | 240 | vblk->disk->fops = &virtblk_fops; |
225 | 241 | index++; | |
226 | minor += 1 << PART_BITS; | ||
227 | 242 | ||
228 | /* If barriers are supported, tell block layer that queue is ordered */ | 243 | /* If barriers are supported, tell block layer that queue is ordered */ |
229 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) | 244 | if (vdev->config->feature(vdev, VIRTIO_BLK_F_BARRIER)) |