|
@@ -526,6 +526,14 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static char *encode_disk_name(char *ptr, unsigned int n)
|
|
|
|
+{
|
|
|
|
+ if (n >= 26)
|
|
|
|
+ ptr = encode_disk_name(ptr, n / 26 - 1);
|
|
|
|
+ *ptr = 'a' + n % 26;
|
|
|
|
+ return ptr + 1;
|
|
|
|
+}
|
|
|
|
+
|
|
static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
|
static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
|
struct blkfront_info *info,
|
|
struct blkfront_info *info,
|
|
u16 vdisk_info, u16 sector_size)
|
|
u16 vdisk_info, u16 sector_size)
|
|
@@ -536,6 +544,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
|
unsigned int offset;
|
|
unsigned int offset;
|
|
int minor;
|
|
int minor;
|
|
int nr_parts;
|
|
int nr_parts;
|
|
|
|
+ char *ptr;
|
|
|
|
|
|
BUG_ON(info->gd != NULL);
|
|
BUG_ON(info->gd != NULL);
|
|
BUG_ON(info->rq != NULL);
|
|
BUG_ON(info->rq != NULL);
|
|
@@ -560,7 +569,11 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
|
"emulated IDE disks,\n\t choose an xvd device name"
|
|
"emulated IDE disks,\n\t choose an xvd device name"
|
|
"from xvde on\n", info->vdevice);
|
|
"from xvde on\n", info->vdevice);
|
|
}
|
|
}
|
|
- err = -ENODEV;
|
|
|
|
|
|
+ if (minor >> MINORBITS) {
|
|
|
|
+ pr_warn("blkfront: %#x's minor (%#x) out of range; ignoring\n",
|
|
|
|
+ info->vdevice, minor);
|
|
|
|
+ return -ENODEV;
|
|
|
|
+ }
|
|
|
|
|
|
if ((minor % nr_parts) == 0)
|
|
if ((minor % nr_parts) == 0)
|
|
nr_minors = nr_parts;
|
|
nr_minors = nr_parts;
|
|
@@ -574,23 +587,14 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
|
|
if (gd == NULL)
|
|
if (gd == NULL)
|
|
goto release;
|
|
goto release;
|
|
|
|
|
|
- if (nr_minors > 1) {
|
|
|
|
- if (offset < 26)
|
|
|
|
- sprintf(gd->disk_name, "%s%c", DEV_NAME, 'a' + offset);
|
|
|
|
- else
|
|
|
|
- sprintf(gd->disk_name, "%s%c%c", DEV_NAME,
|
|
|
|
- 'a' + ((offset / 26)-1), 'a' + (offset % 26));
|
|
|
|
- } else {
|
|
|
|
- if (offset < 26)
|
|
|
|
- sprintf(gd->disk_name, "%s%c%d", DEV_NAME,
|
|
|
|
- 'a' + offset,
|
|
|
|
- minor & (nr_parts - 1));
|
|
|
|
- else
|
|
|
|
- sprintf(gd->disk_name, "%s%c%c%d", DEV_NAME,
|
|
|
|
- 'a' + ((offset / 26) - 1),
|
|
|
|
- 'a' + (offset % 26),
|
|
|
|
- minor & (nr_parts - 1));
|
|
|
|
- }
|
|
|
|
|
|
+ strcpy(gd->disk_name, DEV_NAME);
|
|
|
|
+ ptr = encode_disk_name(gd->disk_name + sizeof(DEV_NAME) - 1, offset);
|
|
|
|
+ BUG_ON(ptr >= gd->disk_name + DISK_NAME_LEN);
|
|
|
|
+ if (nr_minors > 1)
|
|
|
|
+ *ptr = 0;
|
|
|
|
+ else
|
|
|
|
+ snprintf(ptr, gd->disk_name + DISK_NAME_LEN - ptr,
|
|
|
|
+ "%d", minor & (nr_parts - 1));
|
|
|
|
|
|
gd->major = XENVBD_MAJOR;
|
|
gd->major = XENVBD_MAJOR;
|
|
gd->first_minor = minor;
|
|
gd->first_minor = minor;
|
|
@@ -1496,7 +1500,9 @@ module_init(xlblk_init);
|
|
|
|
|
|
static void __exit xlblk_exit(void)
|
|
static void __exit xlblk_exit(void)
|
|
{
|
|
{
|
|
- return xenbus_unregister_driver(&blkfront_driver);
|
|
|
|
|
|
+ xenbus_unregister_driver(&blkfront_driver);
|
|
|
|
+ unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
|
|
|
|
+ kfree(minors);
|
|
}
|
|
}
|
|
module_exit(xlblk_exit);
|
|
module_exit(xlblk_exit);
|
|
|
|
|