While reading through the code again, I realized that if you did something like:
block-attach xvdb
block-attach xvdq
block-attach xvdc
The extended blkfront code would allocate the wrong device for xvdc, since we
had changed mi->type along the way. To fix this, have a separate "major_info"
entry for the extended block devices, even though it isn't technically a
different major number. With these fixes in place, the above sequence works
for me.
Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx>
diff -r db4f08203b8a drivers/xen/blkfront/vbd.c
--- a/drivers/xen/blkfront/vbd.c Tue Jul 08 09:31:24 2008 +0100
+++ b/drivers/xen/blkfront/vbd.c Wed Jul 09 02:13:37 2008 +0200
@@ -56,7 +56,7 @@
#define NUM_IDE_MAJORS 10
#define NUM_SCSI_MAJORS 17
-#define NUM_VBD_MAJORS 1
+#define NUM_VBD_MAJORS 2
static struct xlbd_type_info xlbd_ide_type = {
.partn_shift = 6,
@@ -114,12 +114,14 @@
xlbd_alloc_major_info(int major, int minor, int index)
{
struct xlbd_major_info *ptr;
+ int do_register;
ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
if (ptr == NULL)
return NULL;
ptr->major = major;
+ do_register = 1;
switch (index) {
case XLBD_MAJOR_IDE_RANGE:
@@ -131,23 +133,36 @@
ptr->index = index - XLBD_MAJOR_SCSI_START;
break;
case XLBD_MAJOR_VBD_RANGE:
- ptr->type = &xlbd_vbd_type;
- ptr->index = index - XLBD_MAJOR_VBD_START;
+ ptr->index = 0;
+ if ((index - XLBD_MAJOR_VBD_START) == 0)
+ ptr->type = &xlbd_vbd_type;
+ else
+ ptr->type = &xlbd_vbd_type_ext;
+
+ /*
+ * if someone already registered block major 202,
+ * don't try to register it again
+ */
+ if (major_info[XLBD_MAJOR_VBD_START] != NULL)
+ do_register = 0;
break;
}
- if (register_blkdev(ptr->major, ptr->type->devname)) {
- kfree(ptr);
- return NULL;
+ if (do_register) {
+ if (register_blkdev(ptr->major, ptr->type->devname)) {
+ kfree(ptr);
+ return NULL;
+ }
+
+ printk("xen-vbd: registered block device major %i\n",
ptr->major);
}
- printk("xen-vbd: registered block device major %i\n", ptr->major);
major_info[index] = ptr;
return ptr;
}
static struct xlbd_major_info *
-xlbd_get_major_info(int major, int minor)
+xlbd_get_major_info(int major, int minor, int vdevice)
{
struct xlbd_major_info *mi;
int index;
@@ -171,7 +186,12 @@
index = 18 + major - SCSI_DISK8_MAJOR;
break;
case SCSI_CDROM_MAJOR: index = 26; break;
- default: index = 27; break;
+ default:
+ if (!VDEV_IS_EXTENDED(vdevice))
+ index = 27;
+ else
+ index = 28;
+ break;
}
mi = ((major_info[index] != NULL) ? major_info[index] :
@@ -241,11 +261,9 @@
BUG_ON(info->mi != NULL);
BUG_ON(info->rq != NULL);
- mi = xlbd_get_major_info(major, minor);
+ mi = xlbd_get_major_info(major, minor, vdevice);
if (mi == NULL)
goto out;
- if (VDEV_IS_EXTENDED(vdevice))
- mi->type = &xlbd_vbd_type_ext;
info->mi = mi;
if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|