Subject: cciss driver may panic if a logical volume is deleted From: Hannes Reinecke Date: Wed Jan 7 12:32:12 2009 +0100: References: bnc#459553 If the customer uses either ACUXE or hpacucli to delete a logical volume the Smart Array driver may panic. If the logical volume is in the middle of an array the driver will panic every time. Signed-off-by: Mike Miller Signed-off-by: Hannes Reinecke --- drivers/block/cciss.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -164,7 +164,7 @@ static int cciss_getgeo(struct block_dev static int cciss_revalidate(struct gendisk *disk); static int rebuild_lun_table(ctlr_info_t *h, int first_time); -static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, +static int deregister_disk(ctlr_info_t *h, int drv_index, int clear_all); static void cciss_read_capacity(int ctlr, int logvol, int withirq, @@ -1491,8 +1491,7 @@ static void cciss_update_drive_info(int * which keeps the interrupt handler from starting * the queue. */ - ret = deregister_disk(h->gendisk[drv_index], - &h->drv[drv_index], 0); + ret = deregister_disk(h, drv_index, 0); h->drv[drv_index].busy_configuring = 0; } @@ -1710,8 +1709,7 @@ static int rebuild_lun_table(ctlr_info_t spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); h->drv[i].busy_configuring = 1; spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); - return_code = deregister_disk(h->gendisk[i], - &h->drv[i], 1); + return_code = deregister_disk(h, i, 1); h->drv[i].busy_configuring = 0; } } @@ -1781,15 +1779,19 @@ mem_msg: * the highest_lun should be left unchanged and the LunID * should not be cleared. */ -static int deregister_disk(struct gendisk *disk, drive_info_struct *drv, +static int deregister_disk(ctlr_info_t *h, int drv_index, int clear_all) { int i; - ctlr_info_t *h = get_host(disk); + struct gendisk *disk; + drive_info_struct *drv; if (!capable(CAP_SYS_RAWIO)) return -EPERM; + drv = &h->drv[drv_index]; + disk = h->gendisk[drv_index]; + /* make sure logical volume is NOT is use */ if (clear_all || (h->gendisk[0] == disk)) { if (drv->usage_count > 1)