From: vh249@arcadians.cl.cam.ac.uk Date: Tue, 15 Mar 2005 14:27:36 +0000 (+0000) Subject: bitkeeper revision 1.1159.258.56 (4236f0d8NTb8nv3JBClhBcw3-6u3oQ) X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~17400^2~116 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=96d4259a85a75f16f31840fe2b4635bb70bd603e;p=xen.git bitkeeper revision 1.1159.258.56 (4236f0d8NTb8nv3JBClhBcw3-6u3oQ) update code for having dynamic update of vbd for blkfront driver on 2.6 add some protection for kmalloc failure on 2.4 and 2.6 Signed-off-by: Vincent Hanquez --- diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 05d987fd88..e671b4583f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -66,4 +66,5 @@ tlh20@labyrinth.cl.cam.ac.uk tw275@labyrinth.cl.cam.ac.uk tw275@striker.cl.cam.ac.uk vh249@airwolf.cl.cam.ac.uk +vh249@arcadians.cl.cam.ac.uk xenbk@gandalf.hpl.hp.com diff --git a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c index 74a43cdd4a..81a873e4e0 100644 --- a/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c +++ b/linux-2.4.29-xen-sparse/arch/xen/drivers/blkif/frontend/vbd.c @@ -442,11 +442,11 @@ void xlvbd_update_vbds(void) old_nr = nr_vbds; new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); - if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) - { - kfree(new_info); + if (!new_info) return; - } + + if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) + goto out; /* * Final list maximum size is old list + new list. This occurs only when @@ -454,6 +454,8 @@ void xlvbd_update_vbds(void) * VBDs in the old list because the usage counts are busy. */ merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL); + if (!merged_info) + goto out; /* @i tracks old list; @j tracks new list; @k tracks merged list. */ i = j = k = 0; @@ -500,6 +502,7 @@ void xlvbd_update_vbds(void) nr_vbds = k; kfree(old_info); +out: kfree(new_info); } @@ -543,6 +546,9 @@ int xlvbd_init(void) } vbd_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); + if (!vbd_info) + return -ENOMEM; + nr_vbds = xlvbd_get_vbd_info(vbd_info); if ( nr_vbds < 0 ) diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c index e28db67411..c6035b7b4d 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -170,8 +170,15 @@ static inline void flush_requests(void) module_init(xlblk_init); #if ENABLE_VBD_UPDATE +static void update_vbds_task(void *unused) +{ + xlvbd_update_vbds(); +} + static void vbd_update(void) { + static DECLARE_WORK(update_tq, update_vbds_task, NULL); + schedule_work(&update_tq); } #endif /* ENABLE_VBD_UPDATE */ diff --git a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c index 8050e756ca..95f2bd4b3b 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/blkfront/vbd.c @@ -354,7 +354,6 @@ static int xlvbd_init_device(vdisk_t *xd) return err; } -#if 0 /* * xlvbd_remove_device - remove a device node if possible * @device: numeric device ID @@ -364,14 +363,16 @@ static int xlvbd_init_device(vdisk_t *xd) * This is OK for now but in future, should perhaps consider where this should * deallocate gendisks / unregister devices. */ -static int xlvbd_remove_device(int device) +static int xlvbd_remove_device(int dev16) { - int i, rc = 0, minor = MINOR(device); + int i, rc = 0, minor = MINOR(dev16); struct gendisk *gd; struct block_device *bd; - xen_block_t *disk = NULL; + struct xlbd_disk_info *di; + dev_t device = MKDEV(MAJOR_XEN(dev16), MINOR_XEN(dev16)); - if ( (bd = bdget(device)) == NULL ) + bd = bdget(device); + if (!bd) return -1; /* @@ -380,67 +381,25 @@ static int xlvbd_remove_device(int device) */ down(&bd->bd_sem); - if ( ((gd = get_gendisk(device)) == NULL) || - ((disk = xldev_to_xldisk(device)) == NULL) ) - BUG(); + gd = get_gendisk(device, &i); + BUG_ON(gd == NULL); + di = (struct xlbd_disk_info *) gd->private_data; + BUG_ON(di == NULL); - if ( disk->usage != 0 ) + if ( di->mi->usage != 0 ) { printk(KERN_ALERT "VBD removal failed - in use [dev=%x]\n", device); rc = -1; goto out; } - - if ( (minor & (gd->max_p-1)) != 0 ) - { - /* 1: The VBD is mapped to a partition rather than a whole unit. */ - invalidate_device(device, 1); - gd->part[minor].start_sect = 0; - gd->part[minor].nr_sects = 0; - gd->sizes[minor] = 0; - - /* Clear the consists-of-virtual-partitions flag if possible. */ - gd->flags[minor >> gd->minor_shift] &= ~GENHD_FL_VIRT_PARTNS; - for ( i = 1; i < gd->max_p; i++ ) - if ( gd->sizes[(minor & ~(gd->max_p-1)) + i] != 0 ) - gd->flags[minor >> gd->minor_shift] |= GENHD_FL_VIRT_PARTNS; - /* - * If all virtual partitions are now gone, and a 'whole unit' VBD is - * present, then we can try to grok the unit's real partition table. - */ - if ( !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS) && - (gd->sizes[minor & ~(gd->max_p-1)] != 0) && - !(gd->flags[minor >> gd->minor_shift] & GENHD_FL_REMOVABLE) ) - { - register_disk(gd, - device&~(gd->max_p-1), - gd->max_p, - &xlvbd_block_fops, - gd->part[minor&~(gd->max_p-1)].nr_sects); - } - } - else - { - /* - * 2: The VBD is mapped to an entire 'unit'. Clear all partitions. - * NB. The partition entries are only cleared if there are no VBDs - * mapped to individual partitions on this unit. - */ - i = gd->max_p - 1; /* Default: clear subpartitions as well. */ - if ( gd->flags[minor >> gd->minor_shift] & GENHD_FL_VIRT_PARTNS ) - i = 0; /* 'Virtual' mode: only clear the 'whole unit' entry. */ - while ( i >= 0 ) - { - invalidate_device(device+i, 1); - gd->part[minor+i].start_sect = 0; - gd->part[minor+i].nr_sects = 0; - gd->sizes[minor+i] = 0; - i--; - } - } + BUG_ON(minor != gd->first_minor); + /* The VBD is mapped to an entire unit. */ + + invalidate_partition(gd, 0); + set_capacity(gd, 0); - out: +out: up(&bd->bd_sem); bdput(bd); return rc; @@ -460,11 +419,11 @@ void xlvbd_update_vbds(void) old_nr = nr_vbds; new_info = kmalloc(MAX_VBDS * sizeof(vdisk_t), GFP_KERNEL); - if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) - { - kfree(new_info); + if (!new_info) return; - } + + if ( unlikely(new_nr = xlvbd_get_vbd_info(new_info)) < 0 ) + goto out; /* * Final list maximum size is old list + new list. This occurs only when @@ -472,6 +431,8 @@ void xlvbd_update_vbds(void) * VBDs in the old list because the usage counts are busy. */ merged_info = kmalloc((old_nr + new_nr) * sizeof(vdisk_t), GFP_KERNEL); + if (!merged_info) + goto out; /* @i tracks old list; @j tracks new list; @k tracks merged list. */ i = j = k = 0; @@ -518,9 +479,9 @@ void xlvbd_update_vbds(void) nr_vbds = k; kfree(old_info); +out: kfree(new_info); } -#endif /* * Set up all the linux device goop for the virtual block devices