Commit eece695f authored by Mike Miller's avatar Mike Miller Committed by Jens Axboe

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: default avatarStephen M. Cameron <scameron@beardog.cca.cpqcorp.net>
Signed-off-by: default avatarMike Miller <mike.miller@hp.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 6ae5ce8e
...@@ -1533,15 +1533,18 @@ mem_msg: ...@@ -1533,15 +1533,18 @@ mem_msg:
* where new drives will be added. If the index to be returned is greater * where new drives will be added. If the index to be returned is greater
* than the highest_lun index for the controller then highest_lun is set * than the highest_lun index for the controller then highest_lun is set
* to this new index. If there are no available indexes then -1 is returned. * to this new index. If there are no available indexes then -1 is returned.
* "controller_node" is used to know if this is a real logical drive, or just
* the controller node, which determines if this counts towards highest_lun.
*/ */
static int cciss_find_free_drive_index(int ctlr) static int cciss_find_free_drive_index(int ctlr, int controller_node)
{ {
int i; int i;
for (i = 0; i < CISS_MAX_LUN; i++) { for (i = 0; i < CISS_MAX_LUN; i++) {
if (hba[ctlr]->drv[i].raid_level == -1) { if (hba[ctlr]->drv[i].raid_level == -1) {
if (i > hba[ctlr]->highest_lun) if (i > hba[ctlr]->highest_lun)
hba[ctlr]->highest_lun = i; if (!controller_node)
hba[ctlr]->highest_lun = i;
return i; return i;
} }
} }
...@@ -1557,11 +1560,11 @@ static int cciss_find_free_drive_index(int ctlr) ...@@ -1557,11 +1560,11 @@ static int cciss_find_free_drive_index(int ctlr)
* a means to talk to the controller in case no logical * a means to talk to the controller in case no logical
* drives have yet been configured. * drives have yet been configured.
*/ */
static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid) static int cciss_add_gendisk(ctlr_info_t *h, __u32 lunid, int controller_node)
{ {
int drv_index; int drv_index;
drv_index = cciss_find_free_drive_index(h->ctlr); drv_index = cciss_find_free_drive_index(h->ctlr, controller_node);
if (drv_index == -1) if (drv_index == -1)
return -1; return -1;
/*Check if the gendisk needs to be allocated */ /*Check if the gendisk needs to be allocated */
...@@ -1598,7 +1601,7 @@ static void cciss_add_controller_node(ctlr_info_t *h) ...@@ -1598,7 +1601,7 @@ static void cciss_add_controller_node(ctlr_info_t *h)
if (h->gendisk[0] != NULL) /* already did this? Then bail. */ if (h->gendisk[0] != NULL) /* already did this? Then bail. */
return; return;
drv_index = cciss_add_gendisk(h, 0); drv_index = cciss_add_gendisk(h, 0, 1);
if (drv_index == -1) { if (drv_index == -1) {
printk(KERN_WARNING "cciss%d: could not " printk(KERN_WARNING "cciss%d: could not "
"add disk 0.\n", h->ctlr); "add disk 0.\n", h->ctlr);
...@@ -1732,7 +1735,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) ...@@ -1732,7 +1735,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
/* check if the drive was found already in the array */ /* check if the drive was found already in the array */
if (!drv_found) { if (!drv_found) {
drv_index = cciss_add_gendisk(h, lunid); drv_index = cciss_add_gendisk(h, lunid, 0);
if (drv_index == -1) if (drv_index == -1)
goto freeret; goto freeret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment