Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+9 −6
Original line number Original line Diff line number Diff line
@@ -1533,14 +1533,17 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
 * 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)
				if (!controller_node)
					hba[ctlr]->highest_lun = i;
					hba[ctlr]->highest_lun = i;
			return i;
			return i;
		}
		}
@@ -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)
	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)


		/* 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;
		}
		}