|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] linux-2.6.18/blkfront: properly name all devices
- devices beyond xvdzz didn't get proper names assigned at all
- devices using SCSI_CDROM_MAJOR got named sdXX rather than srNN
- devices with unknown majors got mistakenly converted to use major 202
- extended devices with minors not representable within the kernel's
major/minor bit split spilled into foreign majors
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/drivers/xen/blkfront/block.h
+++ b/drivers/xen/blkfront/block.h
@@ -64,20 +64,12 @@
#define DPRINTK_IOCTL(_f, _a...) ((void)0)
#endif
-struct xlbd_type_info
-{
- int partn_shift;
- int disks_per_major;
- char *devname;
- char *diskname;
-};
-
struct xlbd_major_info
{
int major;
int index;
int usage;
- struct xlbd_type_info *type;
+ const struct xlbd_type_info *type;
struct xlbd_minor_state *minors;
};
--- a/drivers/xen/blkfront/vbd.c
+++ b/drivers/xen/blkfront/vbd.c
@@ -65,46 +65,63 @@ struct xlbd_minor_state {
*/
#define NUM_IDE_MAJORS 10
-#define NUM_SCSI_MAJORS 17
+#define NUM_SD_MAJORS 16
#define NUM_VBD_MAJORS 2
-static struct xlbd_type_info xlbd_ide_type = {
+struct xlbd_type_info
+{
+ int partn_shift;
+ int disks_per_major;
+ char *devname;
+ char *diskname;
+};
+
+static const struct xlbd_type_info xlbd_ide_type = {
.partn_shift = 6,
.disks_per_major = 2,
.devname = "ide",
.diskname = "hd",
};
-static struct xlbd_type_info xlbd_scsi_type = {
+static const struct xlbd_type_info xlbd_sd_type = {
.partn_shift = 4,
.disks_per_major = 16,
.devname = "sd",
.diskname = "sd",
};
-static struct xlbd_type_info xlbd_vbd_type = {
+static const struct xlbd_type_info xlbd_sr_type = {
+ .partn_shift = 0,
+ .disks_per_major = 256,
+ .devname = "sr",
+ .diskname = "sr",
+};
+
+static const struct xlbd_type_info xlbd_vbd_type = {
.partn_shift = 4,
.disks_per_major = 16,
.devname = "xvd",
.diskname = "xvd",
};
-static struct xlbd_type_info xlbd_vbd_type_ext = {
+static const struct xlbd_type_info xlbd_vbd_type_ext = {
.partn_shift = 8,
.disks_per_major = 256,
.devname = "xvd",
.diskname = "xvd",
};
-static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SCSI_MAJORS +
+static struct xlbd_major_info *major_info[NUM_IDE_MAJORS + NUM_SD_MAJORS + 1 +
NUM_VBD_MAJORS];
#define XLBD_MAJOR_IDE_START 0
-#define XLBD_MAJOR_SCSI_START (NUM_IDE_MAJORS)
-#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SCSI_MAJORS)
-
-#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SCSI_START
- 1
-#define XLBD_MAJOR_SCSI_RANGE XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START
- 1
+#define XLBD_MAJOR_SD_START (NUM_IDE_MAJORS)
+#define XLBD_MAJOR_SR_START (NUM_IDE_MAJORS + NUM_SD_MAJORS)
+#define XLBD_MAJOR_VBD_START (NUM_IDE_MAJORS + NUM_SD_MAJORS + 1)
+
+#define XLBD_MAJOR_IDE_RANGE XLBD_MAJOR_IDE_START ... XLBD_MAJOR_SD_START - 1
+#define XLBD_MAJOR_SD_RANGE XLBD_MAJOR_SD_START ... XLBD_MAJOR_SR_START - 1
+#define XLBD_MAJOR_SR_RANGE XLBD_MAJOR_SR_START
#define XLBD_MAJOR_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START +
NUM_VBD_MAJORS - 1
#define XLBD_MAJOR_VBD_ALT(idx) ((idx) ^ XLBD_MAJOR_VBD_START ^
(XLBD_MAJOR_VBD_START + 1))
@@ -155,9 +172,13 @@ xlbd_alloc_major_info(int major, int min
ptr->type = &xlbd_ide_type;
ptr->index = index - XLBD_MAJOR_IDE_START;
break;
- case XLBD_MAJOR_SCSI_RANGE:
- ptr->type = &xlbd_scsi_type;
- ptr->index = index - XLBD_MAJOR_SCSI_START;
+ case XLBD_MAJOR_SD_RANGE:
+ ptr->type = &xlbd_sd_type;
+ ptr->index = index - XLBD_MAJOR_SD_START;
+ break;
+ case XLBD_MAJOR_SR_RANGE:
+ ptr->type = &xlbd_sr_type;
+ ptr->index = index - XLBD_MAJOR_SR_START;
break;
case XLBD_MAJOR_VBD_RANGE:
ptr->index = 0;
@@ -213,20 +234,21 @@ xlbd_get_major_info(int major, int minor
case IDE7_MAJOR: index = 7; break;
case IDE8_MAJOR: index = 8; break;
case IDE9_MAJOR: index = 9; break;
- case SCSI_DISK0_MAJOR: index = 10; break;
+ case SCSI_DISK0_MAJOR: index = XLBD_MAJOR_SD_START; break;
case SCSI_DISK1_MAJOR ... SCSI_DISK7_MAJOR:
- index = 11 + major - SCSI_DISK1_MAJOR;
+ index = XLBD_MAJOR_SD_START + 1 + major - SCSI_DISK1_MAJOR;
break;
- case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
- index = 18 + major - SCSI_DISK8_MAJOR;
- break;
- case SCSI_CDROM_MAJOR: index = 26; break;
- default:
- if (!VDEV_IS_EXTENDED(vdevice))
- index = 27;
- else
- index = 28;
+ case SCSI_DISK8_MAJOR ... SCSI_DISK15_MAJOR:
+ index = XLBD_MAJOR_SD_START + 8 + major - SCSI_DISK8_MAJOR;
+ break;
+ case SCSI_CDROM_MAJOR:
+ index = XLBD_MAJOR_SR_START;
break;
+ case XENVBD_MAJOR:
+ index = XLBD_MAJOR_VBD_START + !!VDEV_IS_EXTENDED(vdevice);
+ break;
+ default:
+ return NULL;
}
mi = ((major_info[index] != NULL) ? major_info[index] :
@@ -324,6 +346,14 @@ xlbd_release_minors(struct xlbd_major_in
spin_unlock(&ms->lock);
}
+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_init_blk_queue(struct gendisk *gd, u16 sector_size,
struct blkfront_info *info)
@@ -369,6 +399,7 @@ xlvbd_alloc_gendisk(int major, int minor
struct xlbd_major_info *mi;
int nr_minors = 1;
int err = -ENODEV;
+ char *ptr;
unsigned int offset;
BUG_ON(info->gd != NULL);
@@ -392,33 +423,21 @@ xlvbd_alloc_gendisk(int major, int minor
if (gd == NULL)
goto release;
- offset = mi->index * mi->type->disks_per_major +
- (minor >> mi->type->partn_shift);
- if (nr_minors > 1) {
- if (offset < 26) {
- sprintf(gd->disk_name, "%s%c",
- mi->type->diskname, 'a' + offset );
- }
- else {
- sprintf(gd->disk_name, "%s%c%c",
- mi->type->diskname,
- 'a' + ((offset/26)-1), 'a' + (offset%26) );
- }
- }
- else {
- if (offset < 26) {
- sprintf(gd->disk_name, "%s%c%d",
- mi->type->diskname,
- 'a' + offset,
- minor & ((1 << mi->type->partn_shift) - 1));
- }
- else {
- sprintf(gd->disk_name, "%s%c%c%d",
- mi->type->diskname,
- 'a' + ((offset/26)-1), 'a' + (offset%26),
- minor & ((1 << mi->type->partn_shift) - 1));
- }
- }
+ strcpy(gd->disk_name, mi->type->diskname);
+ ptr = gd->disk_name + strlen(mi->type->diskname);
+ offset = mi->index * mi->type->disks_per_major +
+ (minor >> mi->type->partn_shift);
+ if (mi->type->partn_shift) {
+ ptr = encode_disk_name(ptr, offset);
+ offset = minor & ((1 << mi->type->partn_shift) - 1);
+ } else
+ gd->flags |= GENHD_FL_CD;
+ BUG_ON(ptr >= gd->disk_name + ARRAY_SIZE(gd->disk_name));
+ if (nr_minors > 1)
+ *ptr = 0;
+ else
+ snprintf(ptr, gd->disk_name + ARRAY_SIZE(gd->disk_name) - ptr,
+ "%u", offset);
gd->major = mi->major;
gd->first_minor = minor;
@@ -478,6 +497,11 @@ xlvbd_add(blkif_sector_t capacity, int v
else {
major = XENVBD_MAJOR;
minor = BLKIF_MINOR_EXT(vdevice);
+ if (minor >> MINORBITS) {
+ printk(KERN_WARNING "blkfront: %#x's minor (%#x)"
+ " out of range; ignoring\n", vdevice, minor);
+ return -ENODEV;
+ }
}
info->dev = MKDEV(major, minor);
Attachment:
xen-blkfront-all-devices.patch _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |