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

[Xen-devel] [PATCH] linux-2.6.18/blkfront: properly name all devices


  • To: "xen-devel" <xen-devel@xxxxxxxxxxxxx>
  • From: "Jan Beulich" <JBeulich@xxxxxxxx>
  • Date: Tue, 06 Mar 2012 09:04:15 +0000
  • Delivery-date: Tue, 06 Mar 2012 09:04:57 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xen.org>

- 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
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

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