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

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
...@@ -170,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -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_getgeo(struct block_device *bdev, struct hd_geometry *geo);
static int cciss_revalidate(struct gendisk *disk); 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, 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, static void cciss_read_capacity(int ctlr, int logvol, int withirq,
sector_t *total_size, unsigned int *block_size); sector_t *total_size, unsigned int *block_size);
...@@ -1211,7 +1211,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode, ...@@ -1211,7 +1211,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
case CCISS_DEREGDISK: case CCISS_DEREGDISK:
case CCISS_REGNEWD: case CCISS_REGNEWD:
case CCISS_REVALIDVOLS: case CCISS_REVALIDVOLS:
return rebuild_lun_table(host, 0); return rebuild_lun_table(host, 0, 1);
case CCISS_GETLUNINFO:{ case CCISS_GETLUNINFO:{
LogvolInfo_struct luninfo; LogvolInfo_struct luninfo;
...@@ -1757,7 +1757,8 @@ static int cciss_add_disk(ctlr_info_t *h, struct gendisk *disk, ...@@ -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 * is also the controller node. Any changes to disk 0 will show up on
* the next reboot. * 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]; ctlr_info_t *h = hba[ctlr];
struct gendisk *disk; struct gendisk *disk;
...@@ -1835,7 +1836,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) ...@@ -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 * which keeps the interrupt handler from starting
* the queue. * 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; h->drv[drv_index].busy_configuring = 0;
} }
...@@ -2000,7 +2001,8 @@ static void cciss_add_controller_node(ctlr_info_t *h) ...@@ -2000,7 +2001,8 @@ static void cciss_add_controller_node(ctlr_info_t *h)
* INPUT * INPUT
* h = The controller to perform the operations on * 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 ctlr = h->ctlr;
int num_luns; int num_luns;
...@@ -2079,7 +2081,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) ...@@ -2079,7 +2081,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
h->drv[i].busy_configuring = 1; h->drv[i].busy_configuring = 1;
spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 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; h->drv[i].busy_configuring = 0;
} }
} }
...@@ -2117,7 +2119,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time) ...@@ -2117,7 +2119,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
if (drv_index == -1) if (drv_index == -1)
goto freeret; goto freeret;
} }
cciss_update_drive_info(ctlr, drv_index, first_time); cciss_update_drive_info(ctlr, drv_index, first_time,
via_ioctl);
} /* end for */ } /* end for */
freeret: freeret:
...@@ -2167,9 +2170,15 @@ static void cciss_clear_drive_info(drive_info_struct *drive_info) ...@@ -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 disk in preparation for re-adding it. In this case
* the highest_lun should be left unchanged and the LunID * the highest_lun should be left unchanged and the LunID
* should not be cleared. * 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, static int deregister_disk(ctlr_info_t *h, int drv_index,
int clear_all) int clear_all, int via_ioctl)
{ {
int i; int i;
struct gendisk *disk; struct gendisk *disk;
...@@ -2183,7 +2192,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index, ...@@ -2183,7 +2192,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
/* make sure logical volume is NOT is use */ /* make sure logical volume is NOT is use */
if (clear_all || (h->gendisk[0] == disk)) { if (clear_all || (h->gendisk[0] == disk)) {
if (drv->usage_count > 1) if (drv->usage_count > via_ioctl)
return -EBUSY; return -EBUSY;
} else if (drv->usage_count > 0) } else if (drv->usage_count > 0)
return -EBUSY; return -EBUSY;
...@@ -3452,7 +3461,7 @@ static int scan_thread(void *data) ...@@ -3452,7 +3461,7 @@ static int scan_thread(void *data)
mutex_unlock(&scan_mutex); mutex_unlock(&scan_mutex);
if (h) { if (h) {
rebuild_lun_table(h, 0); rebuild_lun_table(h, 0, 0);
complete_all(&h->scan_wait); complete_all(&h->scan_wait);
mutex_lock(&scan_mutex); mutex_lock(&scan_mutex);
h->busy_scanning = 0; h->busy_scanning = 0;
...@@ -4253,7 +4262,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev, ...@@ -4253,7 +4262,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
hba[i]->cciss_max_sectors = 2048; hba[i]->cciss_max_sectors = 2048;
rebuild_lun_table(hba[i], 1); rebuild_lun_table(hba[i], 1, 0);
hba[i]->busy_initializing = 0; hba[i]->busy_initializing = 0;
return 1; return 1;
......
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