diff options
| author | Kiyoshi Ueda <k-ueda@ct.jp.nec.com> | 2008-10-04 14:11:35 -0400 |
|---|---|---|
| committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-23 12:42:16 -0400 |
| commit | 6c5121b78ba5c70a9990e2af6cb4d6bbffe0d4d8 (patch) | |
| tree | e64e5c0420f502e18a76a06f07434f631bf3870f | |
| parent | 9d11251709f31d49c8167a619d4475fdf6cd7f73 (diff) | |
[SCSI] export busy state via q->lld_busy_fn()
This patch implements q->lld_busy_fn() for scsi mid layer to export
its busy state for request stacking drivers.
For efficiency, no lock is taken to check the busy state of
shost/starget/sdev, since the returned value is not guaranteed and
may be changed after request stacking drivers call the function,
regardless of taking lock or not.
When scsi can't dispatch I/Os anymore and needs to kill I/Os
(e.g. !sdev), scsi needs to return 'not busy'.
Otherwise, request stacking drivers may hold requests forever.
Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com>
Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
| -rw-r--r-- | drivers/scsi/scsi_lib.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1e7c9e9ef772..f5d3b96890dc 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
| @@ -1465,6 +1465,37 @@ static inline int scsi_host_queue_ready(struct request_queue *q, | |||
| 1465 | } | 1465 | } |
| 1466 | 1466 | ||
| 1467 | /* | 1467 | /* |
| 1468 | * Busy state exporting function for request stacking drivers. | ||
| 1469 | * | ||
| 1470 | * For efficiency, no lock is taken to check the busy state of | ||
| 1471 | * shost/starget/sdev, since the returned value is not guaranteed and | ||
| 1472 | * may be changed after request stacking drivers call the function, | ||
| 1473 | * regardless of taking lock or not. | ||
| 1474 | * | ||
| 1475 | * When scsi can't dispatch I/Os anymore and needs to kill I/Os | ||
| 1476 | * (e.g. !sdev), scsi needs to return 'not busy'. | ||
| 1477 | * Otherwise, request stacking drivers may hold requests forever. | ||
| 1478 | */ | ||
| 1479 | static int scsi_lld_busy(struct request_queue *q) | ||
| 1480 | { | ||
| 1481 | struct scsi_device *sdev = q->queuedata; | ||
| 1482 | struct Scsi_Host *shost; | ||
| 1483 | struct scsi_target *starget; | ||
| 1484 | |||
| 1485 | if (!sdev) | ||
| 1486 | return 0; | ||
| 1487 | |||
| 1488 | shost = sdev->host; | ||
| 1489 | starget = scsi_target(sdev); | ||
| 1490 | |||
| 1491 | if (scsi_host_in_recovery(shost) || scsi_host_is_busy(shost) || | ||
| 1492 | scsi_target_is_busy(starget) || scsi_device_is_busy(sdev)) | ||
| 1493 | return 1; | ||
| 1494 | |||
| 1495 | return 0; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | /* | ||
| 1468 | * Kill a request for a dead device | 1499 | * Kill a request for a dead device |
| 1469 | */ | 1500 | */ |
| 1470 | static void scsi_kill_request(struct request *req, struct request_queue *q) | 1501 | static void scsi_kill_request(struct request *req, struct request_queue *q) |
| @@ -1767,6 +1798,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) | |||
| 1767 | blk_queue_prep_rq(q, scsi_prep_fn); | 1798 | blk_queue_prep_rq(q, scsi_prep_fn); |
| 1768 | blk_queue_softirq_done(q, scsi_softirq_done); | 1799 | blk_queue_softirq_done(q, scsi_softirq_done); |
| 1769 | blk_queue_rq_timed_out(q, scsi_times_out); | 1800 | blk_queue_rq_timed_out(q, scsi_times_out); |
| 1801 | blk_queue_lld_busy(q, scsi_lld_busy); | ||
| 1770 | return q; | 1802 | return q; |
| 1771 | } | 1803 | } |
| 1772 | 1804 | ||
