aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2009-09-17 14:47:44 -0400
committerJens Axboe <jens.axboe@oracle.com>2009-10-01 15:15:42 -0400
commit2d11d9931f5968bddac50d9d224c4812d4be869a (patch)
tree6ea99eba85cc2de4d061c5c6d262b91aab6226c5 /drivers/block
parent9ddb27b44ffeb3080b71cc493b2edff2224d9356 (diff)
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: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 09a0f7bb433b..0a3c057c7785 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -170,9 +170,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
170static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo); 170static int cciss_getgeo(struct block_device *bdev, struct hd_geometry *geo);
171 171
172static int cciss_revalidate(struct gendisk *disk); 172static int cciss_revalidate(struct gendisk *disk);
173static int rebuild_lun_table(ctlr_info_t *h, int first_time); 173static int rebuild_lun_table(ctlr_info_t *h, int first_time, int via_ioctl);
174static int deregister_disk(ctlr_info_t *h, int drv_index, 174static int deregister_disk(ctlr_info_t *h, int drv_index,
175 int clear_all); 175 int clear_all, int via_ioctl);
176 176
177static void cciss_read_capacity(int ctlr, int logvol, int withirq, 177static void cciss_read_capacity(int ctlr, int logvol, int withirq,
178 sector_t *total_size, unsigned int *block_size); 178 sector_t *total_size, unsigned int *block_size);
@@ -1211,7 +1211,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1211 case CCISS_DEREGDISK: 1211 case CCISS_DEREGDISK:
1212 case CCISS_REGNEWD: 1212 case CCISS_REGNEWD:
1213 case CCISS_REVALIDVOLS: 1213 case CCISS_REVALIDVOLS:
1214 return rebuild_lun_table(host, 0); 1214 return rebuild_lun_table(host, 0, 1);
1215 1215
1216 case CCISS_GETLUNINFO:{ 1216 case CCISS_GETLUNINFO:{
1217 LogvolInfo_struct luninfo; 1217 LogvolInfo_struct luninfo;
@@ -1757,7 +1757,8 @@ init_queue_failure:
1757 * is also the controller node. Any changes to disk 0 will show up on 1757 * is also the controller node. Any changes to disk 0 will show up on
1758 * the next reboot. 1758 * the next reboot.
1759 */ 1759 */
1760static void cciss_update_drive_info(int ctlr, int drv_index, int first_time) 1760static void cciss_update_drive_info(int ctlr, int drv_index, int first_time,
1761 int via_ioctl)
1761{ 1762{
1762 ctlr_info_t *h = hba[ctlr]; 1763 ctlr_info_t *h = hba[ctlr];
1763 struct gendisk *disk; 1764 struct gendisk *disk;
@@ -1835,7 +1836,7 @@ static void cciss_update_drive_info(int ctlr, int drv_index, int first_time)
1835 * which keeps the interrupt handler from starting 1836 * which keeps the interrupt handler from starting
1836 * the queue. 1837 * the queue.
1837 */ 1838 */
1838 ret = deregister_disk(h, drv_index, 0); 1839 ret = deregister_disk(h, drv_index, 0, via_ioctl);
1839 h->drv[drv_index].busy_configuring = 0; 1840 h->drv[drv_index].busy_configuring = 0;
1840 } 1841 }
1841 1842
@@ -2000,7 +2001,8 @@ error:
2000 * INPUT 2001 * INPUT
2001 * h = The controller to perform the operations on 2002 * h = The controller to perform the operations on
2002 */ 2003 */
2003static int rebuild_lun_table(ctlr_info_t *h, int first_time) 2004static int rebuild_lun_table(ctlr_info_t *h, int first_time,
2005 int via_ioctl)
2004{ 2006{
2005 int ctlr = h->ctlr; 2007 int ctlr = h->ctlr;
2006 int num_luns; 2008 int num_luns;
@@ -2079,7 +2081,7 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
2079 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags); 2081 spin_lock_irqsave(CCISS_LOCK(h->ctlr), flags);
2080 h->drv[i].busy_configuring = 1; 2082 h->drv[i].busy_configuring = 1;
2081 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); 2083 spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags);
2082 return_code = deregister_disk(h, i, 1); 2084 return_code = deregister_disk(h, i, 1, via_ioctl);
2083 h->drv[i].busy_configuring = 0; 2085 h->drv[i].busy_configuring = 0;
2084 } 2086 }
2085 } 2087 }
@@ -2117,7 +2119,8 @@ static int rebuild_lun_table(ctlr_info_t *h, int first_time)
2117 if (drv_index == -1) 2119 if (drv_index == -1)
2118 goto freeret; 2120 goto freeret;
2119 } 2121 }
2120 cciss_update_drive_info(ctlr, drv_index, first_time); 2122 cciss_update_drive_info(ctlr, drv_index, first_time,
2123 via_ioctl);
2121 } /* end for */ 2124 } /* end for */
2122 2125
2123freeret: 2126freeret:
@@ -2167,9 +2170,15 @@ static void cciss_clear_drive_info(drive_info_struct *drive_info)
2167 * the disk in preparation for re-adding it. In this case 2170 * the disk in preparation for re-adding it. In this case
2168 * the highest_lun should be left unchanged and the LunID 2171 * the highest_lun should be left unchanged and the LunID
2169 * should not be cleared. 2172 * should not be cleared.
2173 * via_ioctl
2174 * This indicates whether we've reached this path via ioctl.
2175 * This affects the maximum usage count allowed for c0d0 to be messed with.
2176 * If this path is reached via ioctl(), then the max_usage_count will
2177 * be 1, as the process calling ioctl() has got to have the device open.
2178 * If we get here via sysfs, then the max usage count will be zero.
2170*/ 2179*/
2171static int deregister_disk(ctlr_info_t *h, int drv_index, 2180static int deregister_disk(ctlr_info_t *h, int drv_index,
2172 int clear_all) 2181 int clear_all, int via_ioctl)
2173{ 2182{
2174 int i; 2183 int i;
2175 struct gendisk *disk; 2184 struct gendisk *disk;
@@ -2183,7 +2192,7 @@ static int deregister_disk(ctlr_info_t *h, int drv_index,
2183 2192
2184 /* make sure logical volume is NOT is use */ 2193 /* make sure logical volume is NOT is use */
2185 if (clear_all || (h->gendisk[0] == disk)) { 2194 if (clear_all || (h->gendisk[0] == disk)) {
2186 if (drv->usage_count > 1) 2195 if (drv->usage_count > via_ioctl)
2187 return -EBUSY; 2196 return -EBUSY;
2188 } else if (drv->usage_count > 0) 2197 } else if (drv->usage_count > 0)
2189 return -EBUSY; 2198 return -EBUSY;
@@ -3452,7 +3461,7 @@ static int scan_thread(void *data)
3452 mutex_unlock(&scan_mutex); 3461 mutex_unlock(&scan_mutex);
3453 3462
3454 if (h) { 3463 if (h) {
3455 rebuild_lun_table(h, 0); 3464 rebuild_lun_table(h, 0, 0);
3456 complete_all(&h->scan_wait); 3465 complete_all(&h->scan_wait);
3457 mutex_lock(&scan_mutex); 3466 mutex_lock(&scan_mutex);
3458 h->busy_scanning = 0; 3467 h->busy_scanning = 0;
@@ -4253,7 +4262,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4253 4262
4254 hba[i]->cciss_max_sectors = 2048; 4263 hba[i]->cciss_max_sectors = 2048;
4255 4264
4256 rebuild_lun_table(hba[i], 1); 4265 rebuild_lun_table(hba[i], 1, 0);
4257 hba[i]->busy_initializing = 0; 4266 hba[i]->busy_initializing = 0;
4258 return 1; 4267 return 1;
4259 4268