This patch implements the new extended allocation scheme on the blkfront end.
Note that there is a new xenbus node for the extended stuff, called
"virtual-device-ext". On a blkfront_probe(), if nothing is found in
"virtual-device", then it will go looking in "virtual-device-ext". This
prevents old guest kernels from potentially mis-interpreting data in
"virtual-device" (and then subsequently crashing).
Signed-off-by: Chris Lalancette <clalance@xxxxxxxxxx>
diff -r 5201a184f513 drivers/xen/blkfront/blkfront.c
--- a/drivers/xen/blkfront/blkfront.c Fri Jun 20 17:43:16 2008 +0100
+++ b/drivers/xen/blkfront/blkfront.c Mon Jun 23 17:56:00 2008 +0200
@@ -92,8 +92,13 @@ static int blkfront_probe(struct xenbus_
err = xenbus_scanf(XBT_NIL, dev->nodename,
"virtual-device", "%i", &vdevice);
if (err != 1) {
- xenbus_dev_fatal(dev, err, "reading virtual-device");
- return err;
+ /* go looking in the extended area instead */
+ err = xenbus_scanf(XBT_NIL, dev->nodename, "virtual-device-ext",
+ "%i", &vdevice);
+ if (err != 1) {
+ xenbus_dev_fatal(dev, err, "reading virtual-device");
+ return err;
+ }
}
info = kzalloc(sizeof(*info), GFP_KERNEL);
diff -r 5201a184f513 drivers/xen/blkfront/vbd.c
--- a/drivers/xen/blkfront/vbd.c Fri Jun 20 17:43:16 2008 +0100
+++ b/drivers/xen/blkfront/vbd.c Mon Jun 23 17:56:00 2008 +0200
@@ -43,6 +43,9 @@
#define BLKIF_MAJOR(dev) ((dev)>>8)
#define BLKIF_MINOR(dev) ((dev) & 0xff)
+#define VDEV_IS_EXTENDED(dev) (dev & (1<<28))
+#define BLKIF_MINOR_EXT(dev) ((dev)&0x0FFFFFFF)
+
/*
* For convenience we distinguish between ide, scsi and 'other' (i.e.,
* potentially combinations of the two) in the naming scheme and in a few other
@@ -84,10 +87,6 @@ static struct xlbd_major_info *major_inf
#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_VBD_RANGE XLBD_MAJOR_VBD_START ... XLBD_MAJOR_VBD_START +
NUM_VBD_MAJORS - 1
-
-/* Information about our VBDs. */
-#define MAX_VBDS 64
-static LIST_HEAD(vbds_list);
static struct block_device_operations xlvbd_block_fops =
{
@@ -144,8 +143,14 @@ xlbd_get_major_info(int vdevice)
struct xlbd_major_info *mi;
int major, minor, index;
- major = BLKIF_MAJOR(vdevice);
- minor = BLKIF_MINOR(vdevice);
+ if (!VDEV_IS_EXTENDED(vdevice)) {
+ major = BLKIF_MAJOR(vdevice);
+ minor = BLKIF_MINOR(vdevice);
+ }
+ else {
+ major = 202;
+ minor = BLKIF_MINOR_EXT(vdevice);
+ }
switch (major) {
case IDE0_MAJOR: index = 0; break;
@@ -231,6 +236,7 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
int nr_minors = 1;
int err = -ENODEV;
unsigned int offset;
+ int part_shift;
BUG_ON(info->gd != NULL);
BUG_ON(info->mi != NULL);
@@ -241,15 +247,19 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
goto out;
info->mi = mi;
- if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)
- nr_minors = 1 << mi->type->partn_shift;
+ part_shift = mi->type->partn_shift;
+ if (VDEV_IS_EXTENDED(vdevice))
+ part_shift += 4;
+
+ if ((minor & ((1 << part_shift) - 1)) == 0)
+ nr_minors = 1 << part_shift;
gd = alloc_disk(nr_minors);
if (gd == NULL)
goto out;
- offset = mi->index * mi->type->disks_per_major +
- (minor >> mi->type->partn_shift);
+ offset = mi->index * mi->type->disks_per_major + (minor >> part_shift);
+
if (nr_minors > 1) {
if (offset < 26) {
sprintf(gd->disk_name, "%s%c",
@@ -266,13 +276,13 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
sprintf(gd->disk_name, "%s%c%d",
mi->type->diskname,
'a' + offset,
- minor & ((1 << mi->type->partn_shift) - 1));
+ minor & ((1 << part_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));
+ minor & ((1 << part_shift) - 1));
}
}
@@ -319,14 +329,26 @@ xlvbd_add(blkif_sector_t capacity, int v
struct block_device *bd;
int err = 0;
- info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
+ if (!VDEV_IS_EXTENDED(vdevice)) {
+ info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
+ bd = bdget(info->dev);
+ if (bd == NULL)
+ return -ENODEV;
- bd = bdget(info->dev);
- if (bd == NULL)
- return -ENODEV;
+ err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity,
+ vdevice, vdisk_info, sector_size,
+ info);
+ }
+ else {
+ info->dev = MKDEV(202, BLKIF_MINOR_EXT(vdevice));
+ bd = bdget(info->dev);
+ if (bd == NULL)
+ return -ENODEV;
- err = xlvbd_alloc_gendisk(BLKIF_MINOR(vdevice), capacity, vdevice,
- vdisk_info, sector_size, info);
+ err = xlvbd_alloc_gendisk(BLKIF_MINOR_EXT(vdevice), capacity,
+ vdevice, vdisk_info, sector_size,
+ info);
+ }
bdput(bd);
return err;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|