cciss: fix negative logical drive count in procfs

This patch fixes a problem where the logical volume count may go negative.
In some instances if several logical are configured on a controller and all
of them are deleted using the online utilities the volume count in /proc may
go negative with no way get it correct again.

Signed-off-by: Stephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: Mike Miller <mike.miller@hp.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>

authored by Mike Miller and committed by Jens Axboe eece695f 6ae5ce8e

+9 -6
+9 -6
drivers/block/cciss.c
··· 1533 * where new drives will be added. If the index to be returned is greater 1534 * than the highest_lun index for the controller then highest_lun is set 1535 * to this new index. If there are no available indexes then -1 is returned. 1536 */ 1537 - static int cciss_find_free_drive_index(int ctlr) 1538 { 1539 int i; 1540 1541 for (i = 0; i < CISS_MAX_LUN; i++) { 1542 if (hba[ctlr]->drv[i].raid_level == -1) { 1543 if (i > hba[ctlr]->highest_lun) 1544 - hba[ctlr]->highest_lun = i; 1545 return i; 1546 } 1547 } ··· 1560 * a means to talk to the controller in case no logical 1561 * drives have yet been configured. 1562 */ 1563 - static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid) 1564 { 1565 int drv_index; 1566 1567 - drv_index = cciss_find_free_drive_index(h->ctlr); 1568 if (drv_index == -1) 1569 return -1; 1570 /*Check if the gendisk needs to be allocated */ ··· 1601 if (h->gendisk[0] != NULL) /* already did this? Then bail. */ 1602 return; 1603 1604 - drv_index = cciss_add_gendisk(h, 0); 1605 if (drv_index == -1) { 1606 printk(KERN_WARNING "cciss%d: could not " 1607 "add disk 0.\n", h->ctlr); ··· 1735 1736 /* check if the drive was found already in the array */ 1737 if (!drv_found) { 1738 - drv_index = cciss_add_gendisk(h, lunid); 1739 if (drv_index == -1) 1740 goto freeret; 1741 }
··· 1533 * where new drives will be added. If the index to be returned is greater 1534 * than the highest_lun index for the controller then highest_lun is set 1535 * to this new index. If there are no available indexes then -1 is returned. 1536 + * "controller_node" is used to know if this is a real logical drive, or just 1537 + * the controller node, which determines if this counts towards highest_lun. 1538 */ 1539 + static int cciss_find_free_drive_index(int ctlr, int controller_node) 1540 { 1541 int i; 1542 1543 for (i = 0; i < CISS_MAX_LUN; i++) { 1544 if (hba[ctlr]->drv[i].raid_level == -1) { 1545 if (i > hba[ctlr]->highest_lun) 1546 + if (!controller_node) 1547 + hba[ctlr]->highest_lun = i; 1548 return i; 1549 } 1550 } ··· 1557 * a means to talk to the controller in case no logical 1558 * drives have yet been configured. 1559 */ 1560 + static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node) 1561 { 1562 int drv_index; 1563 1564 + drv_index = cciss_find_free_drive_index(h->ctlr, controller_node); 1565 if (drv_index == -1) 1566 return -1; 1567 /*Check if the gendisk needs to be allocated */ ··· 1598 if (h->gendisk[0] != NULL) /* already did this? Then bail. */ 1599 return; 1600 1601 + drv_index = cciss_add_gendisk(h, 0, 1); 1602 if (drv_index == -1) { 1603 printk(KERN_WARNING "cciss%d: could not " 1604 "add disk 0.\n", h->ctlr); ··· 1732 1733 /* check if the drive was found already in the array */ 1734 if (!drv_found) { 1735 + drv_index = cciss_add_gendisk(h, lunid, 0); 1736 if (drv_index == -1) 1737 goto freeret; 1738 }