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 <vincent@xensource.com>
This commit is contained in:
vh249@arcadians.cl.cam.ac.uk committed 2005-03-15 14:27:36 +00:00
1 parent d434af3fab
commit 96d4259a85
4 files changed
+42 -67

No files matched your search

+1
View File
@@ -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
@@ -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 )
@@ -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 */
@@ -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;
BUG_ON(minor != gd->first_minor);
/* The VBD is mapped to an entire unit. */
invalidate_partition(gd, 0);
set_capacity(gd, 0);
/*
* 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--;
}
}
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
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.