[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] blkfront: properly name all devices



# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1331127193 -3600
# Node ID 0db21b31377ffd8e08d5aa43e346be6a8e9a304f
# Parent  99dc6737898bb6f83bcaa78db18aa0253fc08c24
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>
---


diff -r 99dc6737898b -r 0db21b31377f drivers/xen/blkfront/block.h
--- a/drivers/xen/blkfront/block.h      Wed Mar 07 14:28:54 2012 +0100
+++ b/drivers/xen/blkfront/block.h      Wed Mar 07 14:33:13 2012 +0100
@@ -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;
 };
 
diff -r 99dc6737898b -r 0db21b31377f drivers/xen/blkfront/vbd.c
--- a/drivers/xen/blkfront/vbd.c        Wed Mar 07 14:28:54 2012 +0100
+++ b/drivers/xen/blkfront/vbd.c        Wed Mar 07 14:33:13 2012 +0100
@@ -65,46 +65,63 @@
  */
 
 #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_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_SCSI_START 
- 1
-#define XLBD_MAJOR_SCSI_RANGE  XLBD_MAJOR_SCSI_START ... XLBD_MAJOR_VBD_START 
- 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 @@
                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;
@@ -212,20 +233,21 @@
        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] :
@@ -323,6 +345,14 @@
        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)
@@ -366,6 +396,7 @@
        struct xlbd_major_info *mi;
        int nr_minors = 1;
        int err = -ENODEV;
+       char *ptr;
        unsigned int offset;
 
        BUG_ON(info->gd != NULL);
@@ -389,33 +420,21 @@
        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;
@@ -475,6 +494,11 @@
        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);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.