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

Commit 2d11d993 authored by Stephen M. Cameron's avatar Stephen M. Cameron Committed by Jens Axboe
Browse files

cciss: Fix usage_count check in rebuild_lun_table when triggered via sysfs.



When rebuild_lun_table is reached via sysfs, the usage count that
is checked prior to messing with c0d0 has different constraints
(must be zero) than if rebuild_lun_table is reached via ioctl
(must be one.)  Fix rebuild_lun_table to take that into account.

Signed-off-by: default avatarStephen M. Cameron <scameron@beardog.cce.hp.com>
Signed-off-by: default avatarJens Axboe <jens.axboe@oracle.com>
parent 9ddb27b4
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -170,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);

static int cciss_revalidate(struct gendisk *disk);
static int rebuild_lun_table(ctlr_info_t *h, int first_time);
static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
static int deregister_disk(ctlr_info_t *h, int drv_index,
			   int clear_all);
			   int clear_all, int via_ioctl);

static void cciss_read_capacity(int ctlr, int logvol, int withirq,
			sector_t *total_size, unsigned int *block_size);
@@ -1211,7 +1211,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	case CCISS_DEREGDISK:
	case CCISS_REGNEWD:
	case CCISS_REVALIDVOLS:
		return rebuild_lun_table(host, 0);
		return rebuild_lun_table(host, 0, 1);

	case CCISS_GETLUNINFO:{
			LogvolInfo_struct luninfo;
@@ -1757,7 +1757,8 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk,
 * is also the controller node.  Any changes to disk 0 will show up on
 * the next reboot.
 */
static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
	int via_ioctl)
{
	ctlr_info_t *h = hba[ctlr];
	struct gendisk *disk;
@@ -1835,7 +1836,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
		 * which keeps the interrupt handler from starting
		 * the queue.
		 */
		ret = deregister_disk(h, drv_index, 0);
		ret = deregister_disk(h, drv_index, 0, via_ioctl);
		h->drv[drv_index].busy_configuring = 0;
	}

@@ -2000,7 +2001,8 @@ static void cciss_add_controller_node(ctlr_info_t *h)
 * INPUT
 * h		= The controller to perform the operations on
 */
static int rebuild_lun_table(ctlr_info_t *h, int first_time)
static int rebuild_lun_table(ctlr_info_t *h, int first_time,
	int via_ioctl)
{
	int ctlr = h->ctlr;
	int num_luns;
@@ -2079,7 +2081,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
			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, i, 1);
			return_code = deregister_disk(h, i, 1, via_ioctl);
			h->drv[i].busy_configuring = 0;
		}
	}
@@ -2117,7 +2119,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
			if (drv_index == -1)
				goto freeret;
		}
		cciss_update_drive_info(ctlr, drv_index, first_time);
		cciss_update_drive_info(ctlr, drv_index, first_time,
			via_ioctl);
	}		/* end for */

freeret:
@@ -2167,9 +2170,15 @@ static void cciss_clear_drive_info(drive_info_struct *drive_info)
 *             the disk in preparation for re-adding it.  In this case
 *             the highest_lun should be left unchanged and the LunID
 *             should not be cleared.
 * via_ioctl
 *    This indicates whether we've reached this path via ioctl.
 *    This affects the maximum usage count allowed for c0d0 to be messed with.
 *    If this path is reached via ioctl(), then the max_usage_count will
 *    be 1, as the process calling ioctl() has got to have the device open.
 *    If we get here via sysfs, then the max usage count will be zero.
*/
static int deregister_disk(ctlr_info_t *h, int drv_index,
			   int clear_all)
			   int clear_all, int via_ioctl)
{
	int i;
	struct gendisk *disk;
@@ -2183,7 +2192,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,

	/* make sure logical volume is NOT is use */
	if (clear_all || (h->gendisk[0] == disk)) {
		if (drv->usage_count > 1)
		if (drv->usage_count > via_ioctl)
			return -EBUSY;
	} else if (drv->usage_count > 0)
		return -EBUSY;
@@ -3452,7 +3461,7 @@ static int scan_thread(void *data)
			mutex_unlock(&scan_mutex);

			if (h) {
				rebuild_lun_table(h, 0);
				rebuild_lun_table(h, 0, 0);
				complete_all(&h->scan_wait);
				mutex_lock(&scan_mutex);
				h->busy_scanning = 0;
@@ -4253,7 +4262,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,

	hba[i]->cciss_max_sectors = 2048;

	rebuild_lun_table(hba[i], 1);
	rebuild_lun_table(hba[i], 1, 0);
	hba[i]->busy_initializing = 0;
	return 1;