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).
Changes since v1:
- Restructure the changes to remove duplicate code
- Add some error checks on the xlvbd_add() path. Note that I did not do full
error checking on the existing numbering scheme (i.e. the 202<<8 for xvd, 3<<8
for IDE, 8<<8 for SCSI, etc). The reason I didn't do full checking is that it
is perfectly legal to do something like: "xm block-attach pv tap:aio:/disk
0xCB10 w" (which is major 203), which then maps onto the 202 xvd device. It's
not particularly nice behavior, in my opinion, but changing it now would change
this behavior. So the only check I added was to make sure we weren't above the
extended device range (1<<28).
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 Wed Jun 25 15:34:09 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 Wed Jun 25 15:34:09 2008 +0200
@@ -43,6 +43,11 @@
#define BLKIF_MAJOR(dev) ((dev)>>8)
#define BLKIF_MINOR(dev) ((dev) & 0xff)
+#define EXT_SHIFT 28
+#define EXTENDED (1<<EXT_SHIFT)
+#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
+#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
+
/*
* 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
@@ -74,6 +79,13 @@ static struct xlbd_type_info xlbd_vbd_ty
.diskname = "xvd",
};
+static 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 +
NUM_VBD_MAJORS];
@@ -84,10 +96,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 =
{
@@ -139,13 +147,10 @@ xlbd_alloc_major_info(int major, int min
}
static struct xlbd_major_info *
-xlbd_get_major_info(int vdevice)
+xlbd_get_major_info(int major, int minor)
{
struct xlbd_major_info *mi;
- int major, minor, index;
-
- major = BLKIF_MAJOR(vdevice);
- minor = BLKIF_MINOR(vdevice);
+ int index;
switch (major) {
case IDE0_MAJOR: index = 0; break;
@@ -222,7 +227,7 @@ xlvbd_init_blk_queue(struct gendisk *gd,
}
static int
-xlvbd_alloc_gendisk(int minor, blkif_sector_t capacity, int vdevice,
+xlvbd_alloc_gendisk(int major, int minor, blkif_sector_t capacity, int vdevice,
u16 vdisk_info, u16 sector_size,
struct blkfront_info *info)
{
@@ -236,9 +241,11 @@ xlvbd_alloc_gendisk(int minor, blkif_sec
BUG_ON(info->mi != NULL);
BUG_ON(info->rq != NULL);
- mi = xlbd_get_major_info(vdevice);
+ mi = xlbd_get_major_info(major, minor);
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)
@@ -318,15 +325,30 @@ xlvbd_add(blkif_sector_t capacity, int v
{
struct block_device *bd;
int err = 0;
+ int major, minor;
- info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice));
+ if ((vdevice>>EXT_SHIFT) > 1) {
+ /* this is above the extended range; something is wrong */
+ printk(KERN_WARNING "blkfront: vdevice 0x%x is above the
extended range; ignoring\n", vdevice);
+ return -ENODEV;
+ }
+ if (!VDEV_IS_EXTENDED(vdevice)) {
+ major = BLKIF_MAJOR(vdevice);
+ minor = BLKIF_MINOR(vdevice);
+ }
+ else {
+ major = 202;
+ minor = BLKIF_MINOR_EXT(vdevice);
+ }
+
+ info->dev = MKDEV(major, minor);
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(major, minor, capacity, vdevice, vdisk_info,
+ sector_size, info);
bdput(bd);
return err;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|