Commit 67bd94130015c507011af37858989b199c52e1de

Authored by Bart Van Assche
Committed by James Bottomley
1 parent e81ca6fe85

[SCSI] Fix device removal NULL pointer dereference

Use blk_queue_dead() to test whether the queue is dead instead
of !sdev. Since scsi_prep_fn() may be invoked concurrently with
__scsi_remove_device(), keep the queuedata (sdev) pointer in
__scsi_remove_device(). This patch fixes a kernel oops that
can be triggered by USB device removal. See also
http://www.spinics.net/lists/linux-scsi/msg56254.html.

Other changes included in this patch:
- Swap the blk_cleanup_queue() and kfree() calls in
  scsi_host_dev_release() to make that code easier to grasp.
- Remove the queue dead check from scsi_run_queue() since the
  queue state can change anyway at any point in that function
  where the queue lock is not held.
- Remove the queue dead check from the start of scsi_request_fn()
  since it is redundant with the scsi_device_online() check.

Reported-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Mike Christie <michaelc@cs.wisc.edu>
Reviewed-by: Tejun Heo <tj@kernel.org>
Cc: <stable@kernel.org>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>

Showing 4 changed files with 9 additions and 36 deletions Side-by-side Diff

drivers/scsi/hosts.c
... ... @@ -290,6 +290,7 @@
290 290 struct Scsi_Host *shost = dev_to_shost(dev);
291 291 struct device *parent = dev->parent;
292 292 struct request_queue *q;
  293 + void *queuedata;
293 294  
294 295 scsi_proc_hostdir_rm(shost->hostt);
295 296  
... ... @@ -299,9 +300,9 @@
299 300 destroy_workqueue(shost->work_q);
300 301 q = shost->uspace_req_q;
301 302 if (q) {
302   - kfree(q->queuedata);
303   - q->queuedata = NULL;
304   - scsi_free_queue(q);
  303 + queuedata = q->queuedata;
  304 + blk_cleanup_queue(q);
  305 + kfree(queuedata);
305 306 }
306 307  
307 308 scsi_destroy_command_freelist(shost);
drivers/scsi/scsi_lib.c
... ... @@ -406,10 +406,6 @@
406 406 LIST_HEAD(starved_list);
407 407 unsigned long flags;
408 408  
409   - /* if the device is dead, sdev will be NULL, so no queue to run */
410   - if (!sdev)
411   - return;
412   -
413 409 shost = sdev->host;
414 410 if (scsi_target(sdev)->single_lun)
415 411 scsi_single_lun_run(sdev);
416 412  
... ... @@ -1371,16 +1367,16 @@
1371 1367 * may be changed after request stacking drivers call the function,
1372 1368 * regardless of taking lock or not.
1373 1369 *
1374   - * When scsi can't dispatch I/Os anymore and needs to kill I/Os
1375   - * (e.g. !sdev), scsi needs to return 'not busy'.
1376   - * Otherwise, request stacking drivers may hold requests forever.
  1370 + * When scsi can't dispatch I/Os anymore and needs to kill I/Os scsi
  1371 + * needs to return 'not busy'. Otherwise, request stacking drivers
  1372 + * may hold requests forever.
1377 1373 */
1378 1374 static int scsi_lld_busy(struct request_queue *q)
1379 1375 {
1380 1376 struct scsi_device *sdev = q->queuedata;
1381 1377 struct Scsi_Host *shost;
1382 1378  
1383   - if (!sdev)
  1379 + if (blk_queue_dead(q))
1384 1380 return 0;
1385 1381  
1386 1382 shost = sdev->host;
... ... @@ -1491,12 +1487,6 @@
1491 1487 struct scsi_cmnd *cmd;
1492 1488 struct request *req;
1493 1489  
1494   - if (!sdev) {
1495   - while ((req = blk_peek_request(q)) != NULL)
1496   - scsi_kill_request(req, q);
1497   - return;
1498   - }
1499   -
1500 1490 if(!get_device(&sdev->sdev_gendev))
1501 1491 /* We must be tearing the block queue down already */
1502 1492 return;
... ... @@ -1696,20 +1686,6 @@
1696 1686 blk_queue_rq_timed_out(q, scsi_times_out);
1697 1687 blk_queue_lld_busy(q, scsi_lld_busy);
1698 1688 return q;
1699   -}
1700   -
1701   -void scsi_free_queue(struct request_queue *q)
1702   -{
1703   - unsigned long flags;
1704   -
1705   - WARN_ON(q->queuedata);
1706   -
1707   - /* cause scsi_request_fn() to kill all non-finished requests */
1708   - spin_lock_irqsave(q->queue_lock, flags);
1709   - q->request_fn(q);
1710   - spin_unlock_irqrestore(q->queue_lock, flags);
1711   -
1712   - blk_cleanup_queue(q);
1713 1689 }
1714 1690  
1715 1691 /*
drivers/scsi/scsi_priv.h
... ... @@ -85,7 +85,6 @@
85 85 extern void scsi_io_completion(struct scsi_cmnd *, unsigned int);
86 86 extern void scsi_run_host_queues(struct Scsi_Host *shost);
87 87 extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev);
88   -extern void scsi_free_queue(struct request_queue *q);
89 88 extern int scsi_init_queue(void);
90 89 extern void scsi_exit_queue(void);
91 90 struct request_queue;
drivers/scsi/scsi_sysfs.c
... ... @@ -972,11 +972,8 @@
972 972 sdev->host->hostt->slave_destroy(sdev);
973 973 transport_destroy_device(dev);
974 974  
975   - /* cause the request function to reject all I/O requests */
976   - sdev->request_queue->queuedata = NULL;
977   -
978 975 /* Freeing the queue signals to block that we're done */
979   - scsi_free_queue(sdev->request_queue);
  976 + blk_cleanup_queue(sdev->request_queue);
980 977 put_device(dev);
981 978 }
982 979