[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [linux-2.6.18-xen] blkfront: Fix blkfront to accept expanded devices (v2)
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1214579201 -3600 # Node ID 65faf5fc61a1cadb20885dc2e926efe1722956fd # Parent e7b48c70c7270d46ba645fc643b63bb49860ea44 blkfront: Fix blkfront to accept expanded devices (v2) 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> --- drivers/xen/blkfront/blkfront.c | 9 +++++- drivers/xen/blkfront/vbd.c | 54 ++++++++++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 18 deletions(-) diff -r e7b48c70c727 -r 65faf5fc61a1 drivers/xen/blkfront/blkfront.c --- a/drivers/xen/blkfront/blkfront.c Fri Jun 27 14:46:41 2008 +0100 +++ b/drivers/xen/blkfront/blkfront.c Fri Jun 27 16:06:41 2008 +0100 @@ -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 e7b48c70c727 -r 65faf5fc61a1 drivers/xen/blkfront/vbd.c --- a/drivers/xen/blkfront/vbd.c Fri Jun 27 14:46:41 2008 +0100 +++ b/drivers/xen/blkfront/vbd.c Fri Jun 27 16:06:41 2008 +0100 @@ -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; - - info->dev = MKDEV(BLKIF_MAJOR(vdevice), BLKIF_MINOR(vdevice)); - + int major, minor; + + 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-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |