diff options
author | Jan Beulich <JBeulich@suse.com> | 2012-04-05 11:37:22 -0400 |
---|---|---|
committer | Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> | 2012-05-11 16:11:52 -0400 |
commit | e77c78c02290c27925f67cd35b497e99ee0d6fe1 (patch) | |
tree | 779e1f9d6e3a8abf5e14711043504b768cc1ef97 /drivers/block/xen-blkfront.c | |
parent | e816b57a337ea3b755de72bec38c10c864f23015 (diff) |
xen-blkfront: properly name all devices
- devices beyond xvdzz didn't get proper names assigned at all
- extended devices with minors not representable within the kernel's
major/minor bit split spilled into foreign majors
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'drivers/block/xen-blkfront.c')
-rw-r--r-- | drivers/block/xen-blkfront.c | 40 |
1 files changed, 22 insertions, 18 deletions
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4e86393a09cf..4f2b46052976 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -526,6 +526,14 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) | |||
526 | return 0; | 526 | return 0; |
527 | } | 527 | } |
528 | 528 | ||
529 | static char *encode_disk_name(char *ptr, unsigned int n) | ||
530 | { | ||
531 | if (n >= 26) | ||
532 | ptr = encode_disk_name(ptr, n / 26 - 1); | ||
533 | *ptr = 'a' + n % 26; | ||
534 | return ptr + 1; | ||
535 | } | ||
536 | |||
529 | static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | 537 | static int xlvbd_alloc_gendisk(blkif_sector_t capacity, |
530 | struct blkfront_info *info, | 538 | struct blkfront_info *info, |
531 | u16 vdisk_info, u16 sector_size) | 539 | u16 vdisk_info, u16 sector_size) |
@@ -536,6 +544,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
536 | unsigned int offset; | 544 | unsigned int offset; |
537 | int minor; | 545 | int minor; |
538 | int nr_parts; | 546 | int nr_parts; |
547 | char *ptr; | ||
539 | 548 | ||
540 | BUG_ON(info->gd != NULL); | 549 | BUG_ON(info->gd != NULL); |
541 | BUG_ON(info->rq != NULL); | 550 | BUG_ON(info->rq != NULL); |
@@ -560,7 +569,11 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
560 | "emulated IDE disks,\n\t choose an xvd device name" | 569 | "emulated IDE disks,\n\t choose an xvd device name" |
561 | "from xvde on\n", info->vdevice); | 570 | "from xvde on\n", info->vdevice); |
562 | } | 571 | } |
563 | err = -ENODEV; | 572 | if (minor >> MINORBITS) { |
573 | pr_warn("blkfront: %#x's minor (%#x) out of range; ignoring\n", | ||
574 | info->vdevice, minor); | ||
575 | return -ENODEV; | ||
576 | } | ||
564 | 577 | ||
565 | if ((minor % nr_parts) == 0) | 578 | if ((minor % nr_parts) == 0) |
566 | nr_minors = nr_parts; | 579 | nr_minors = nr_parts; |
@@ -574,23 +587,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, | |||
574 | if (gd == NULL) | 587 | if (gd == NULL) |
575 | goto release; | 588 | goto release; |
576 | 589 | ||
577 | if (nr_minors > 1) { | 590 | strcpy(gd->disk_name, DEV_NAME); |
578 | if (offset < 26) | 591 | ptr = encode_disk_name(gd->disk_name + sizeof(DEV_NAME) - 1, offset); |
579 | sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset); | 592 | BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN); |
580 | else | 593 | if (nr_minors > 1) |
581 | sprintf(gd->disk_name, "%s%c%c", DEV_NAME, | 594 | *ptr = 0; |
582 | 'a' + ((offset / 26)-1), 'a' + (offset % 26)); | 595 | else |
583 | } else { | 596 | snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr, |
584 | if (offset < 26) | 597 | "%d", minor & (nr_parts - 1)); |
585 | sprintf(gd->disk_name, "%s%c%d", DEV_NAME, | ||
586 | 'a' + offset, | ||
587 | minor & (nr_parts - 1)); | ||
588 | else | ||
589 | sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME, | ||
590 | 'a' + ((offset / 26) - 1), | ||
591 | 'a' + (offset % 26), | ||
592 | minor & (nr_parts - 1)); | ||
593 | } | ||
594 | 598 | ||
595 | gd->major = XENVBD_MAJOR; | 599 | gd->major = XENVBD_MAJOR; |
596 | gd->first_minor = minor; | 600 | gd->first_minor = minor; |