ia64/linux-2.6.18-xen.hg

changeset 599:29228a5f9fea

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.

Signed-off-by: Chris Lalancette <clalance@redhat.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jul 09 10:45:09 2008 +0100 (2008-07-09)
parents f1d726b984a3
children 1bd3dbfdaf0f
files drivers/xen/blkfront/vbd.c
line diff
     1.1 --- a/drivers/xen/blkfront/vbd.c	Wed Jul 09 10:44:08 2008 +0100
     1.2 +++ b/drivers/xen/blkfront/vbd.c	Wed Jul 09 10:45:09 2008 +0100
     1.3 @@ -56,7 +56,7 @@
     1.4  
     1.5  #define NUM_IDE_MAJORS 10
     1.6  #define NUM_SCSI_MAJORS 17
     1.7 -#define NUM_VBD_MAJORS 1
     1.8 +#define NUM_VBD_MAJORS 2
     1.9  
    1.10  static struct xlbd_type_info xlbd_ide_type = {
    1.11  	.partn_shift = 6,
    1.12 @@ -114,12 +114,14 @@ static struct xlbd_major_info *
    1.13  xlbd_alloc_major_info(int major, int minor, int index)
    1.14  {
    1.15  	struct xlbd_major_info *ptr;
    1.16 +	int do_register;
    1.17  
    1.18  	ptr = kzalloc(sizeof(struct xlbd_major_info), GFP_KERNEL);
    1.19  	if (ptr == NULL)
    1.20  		return NULL;
    1.21  
    1.22  	ptr->major = major;
    1.23 +	do_register = 1;
    1.24  
    1.25  	switch (index) {
    1.26  	case XLBD_MAJOR_IDE_RANGE:
    1.27 @@ -131,23 +133,36 @@ xlbd_alloc_major_info(int major, int min
    1.28  		ptr->index = index - XLBD_MAJOR_SCSI_START;
    1.29  		break;
    1.30  	case XLBD_MAJOR_VBD_RANGE:
    1.31 -		ptr->type = &xlbd_vbd_type;
    1.32 -		ptr->index = index - XLBD_MAJOR_VBD_START;
    1.33 +		ptr->index = 0;
    1.34 +		if ((index - XLBD_MAJOR_VBD_START) == 0)
    1.35 +			ptr->type = &xlbd_vbd_type;
    1.36 +		else
    1.37 +			ptr->type = &xlbd_vbd_type_ext;
    1.38 +
    1.39 +		/* 
    1.40 +		 * if someone already registered block major 202,
    1.41 +		 * don't try to register it again
    1.42 +		 */
    1.43 +		if (major_info[XLBD_MAJOR_VBD_START] != NULL)
    1.44 +			do_register = 0;
    1.45  		break;
    1.46  	}
    1.47  
    1.48 -	if (register_blkdev(ptr->major, ptr->type->devname)) {
    1.49 -		kfree(ptr);
    1.50 -		return NULL;
    1.51 +	if (do_register) {
    1.52 +		if (register_blkdev(ptr->major, ptr->type->devname)) {
    1.53 +			kfree(ptr);
    1.54 +			return NULL;
    1.55 +		}
    1.56 +
    1.57 +		printk("xen-vbd: registered block device major %i\n", ptr->major);
    1.58  	}
    1.59  
    1.60 -	printk("xen-vbd: registered block device major %i\n", ptr->major);
    1.61  	major_info[index] = ptr;
    1.62  	return ptr;
    1.63  }
    1.64  
    1.65  static struct xlbd_major_info *
    1.66 -xlbd_get_major_info(int major, int minor)
    1.67 +xlbd_get_major_info(int major, int minor, int vdevice)
    1.68  {
    1.69  	struct xlbd_major_info *mi;
    1.70  	int index;
    1.71 @@ -171,7 +186,12 @@ xlbd_get_major_info(int major, int minor
    1.72                  index = 18 + major - SCSI_DISK8_MAJOR;
    1.73                  break;
    1.74          case SCSI_CDROM_MAJOR: index = 26; break;
    1.75 -        default: index = 27; break;
    1.76 +        default:
    1.77 +		if (!VDEV_IS_EXTENDED(vdevice))
    1.78 +			index = 27;
    1.79 +		else
    1.80 +			index = 28;
    1.81 +		break;
    1.82  	}
    1.83  
    1.84  	mi = ((major_info[index] != NULL) ? major_info[index] :
    1.85 @@ -241,11 +261,9 @@ xlvbd_alloc_gendisk(int major, int minor
    1.86  	BUG_ON(info->mi != NULL);
    1.87  	BUG_ON(info->rq != NULL);
    1.88  
    1.89 -	mi = xlbd_get_major_info(major, minor);
    1.90 +	mi = xlbd_get_major_info(major, minor, vdevice);
    1.91  	if (mi == NULL)
    1.92  		goto out;
    1.93 -	if (VDEV_IS_EXTENDED(vdevice))
    1.94 -		mi->type = &xlbd_vbd_type_ext;
    1.95  	info->mi = mi;
    1.96  
    1.97  	if ((minor & ((1 << mi->type->partn_shift) - 1)) == 0)