Skip to contentSkip to conversation

: Blkfront greater than 16 vbd fixes

PATCH In review Chris Lalancette 1 participant 1 message Jul 9, 2008 Xen hypervisor interface

lore
Share & tools
lore
#0 lore raw

PATCH 3/3 : Blkfront greater than 16 vbd fixes

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.

drivers/xen/blkfront/vbd.c +30 -12
diff -r db4f08203b8a drivers/xen/blkfront/vbd.c
@@ -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
[email protected]
http://lists.xensource.com/xen-devel