aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-06-04 23:40:54 -0400
committerJens Axboe <axboe@kernel.dk>2012-06-25 05:53:48 -0400
commit86072d8112595ea1b6beeb33f578e7c2839e014e (patch)
treead49aefc355232e099c07c4a371b437e5241981f
parenta91a5ac6858fbf7477131e1210cb3e897b668e6f (diff)
block: drop custom queue draining used by scsi_transport_{iscsi|fc}
iscsi_remove_host() uses bsg_remove_queue() which implements custom queue draining. fc_bsg_remove() open-codes mostly identical logic. The draining logic isn't correct in that blk_stop_queue() doesn't prevent new requests from being queued - it just stops processing, so nothing prevents new requests to be queued after the logic determines that the queue is drained. blk_cleanup_queue() now implements proper queue draining and these custom draining logics aren't necessary. Drop them and use bsg_unregister_queue() + blk_cleanup_queue() instead. Signed-off-by: Tejun Heo <tj@kernel.org> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Acked-by: Vivek Goyal <vgoyal@redhat.com> Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Cc: James Smart <james.smart@emulex.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/bsg-lib.c53
-rw-r--r--drivers/scsi/scsi_transport_fc.c38
-rw-r--r--drivers/scsi/scsi_transport_iscsi.c2
-rw-r--r--include/linux/bsg-lib.h1
4 files changed, 1 insertions, 93 deletions
diff --git a/block/bsg-lib.c b/block/bsg-lib.c
index 7ad49c88f6b1..deee61fbb741 100644
--- a/block/bsg-lib.c
+++ b/block/bsg-lib.c
@@ -243,56 +243,3 @@ int bsg_setup_queue(struct device *dev, struct request_queue *q,
243 return 0; 243 return 0;
244} 244}
245EXPORT_SYMBOL_GPL(bsg_setup_queue); 245EXPORT_SYMBOL_GPL(bsg_setup_queue);
246
247/**
248 * bsg_remove_queue - Deletes the bsg dev from the q
249 * @q: the request_queue that is to be torn down.
250 *
251 * Notes:
252 * Before unregistering the queue empty any requests that are blocked
253 */
254void bsg_remove_queue(struct request_queue *q)
255{
256 struct request *req; /* block request */
257 int counts; /* totals for request_list count and starved */
258
259 if (!q)
260 return;
261
262 /* Stop taking in new requests */
263 spin_lock_irq(q->queue_lock);
264 blk_stop_queue(q);
265
266 /* drain all requests in the queue */
267 while (1) {
268 /* need the lock to fetch a request
269 * this may fetch the same reqeust as the previous pass
270 */
271 req = blk_fetch_request(q);
272 /* save requests in use and starved */
273 counts = q->rq.count[0] + q->rq.count[1] +
274 q->rq.starved[0] + q->rq.starved[1];
275 spin_unlock_irq(q->queue_lock);
276 /* any requests still outstanding? */
277 if (counts == 0)
278 break;
279
280 /* This may be the same req as the previous iteration,
281 * always send the blk_end_request_all after a prefetch.
282 * It is not okay to not end the request because the
283 * prefetch started the request.
284 */
285 if (req) {
286 /* return -ENXIO to indicate that this queue is
287 * going away
288 */
289 req->errors = -ENXIO;
290 blk_end_request_all(req, -ENXIO);
291 }
292
293 msleep(200); /* allow bsg to possibly finish */
294 spin_lock_irq(q->queue_lock);
295 }
296 bsg_unregister_queue(q);
297}
298EXPORT_SYMBOL_GPL(bsg_remove_queue);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 579760420d53..a9617ad05f33 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -4130,45 +4130,7 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport)
4130static void 4130static void
4131fc_bsg_remove(struct request_queue *q) 4131fc_bsg_remove(struct request_queue *q)
4132{ 4132{
4133 struct request *req; /* block request */
4134 int counts; /* totals for request_list count and starved */
4135
4136 if (q) { 4133 if (q) {
4137 /* Stop taking in new requests */
4138 spin_lock_irq(q->queue_lock);
4139 blk_stop_queue(q);
4140
4141 /* drain all requests in the queue */
4142 while (1) {
4143 /* need the lock to fetch a request
4144 * this may fetch the same reqeust as the previous pass
4145 */
4146 req = blk_fetch_request(q);
4147 /* save requests in use and starved */
4148 counts = q->rq.count[0] + q->rq.count[1] +
4149 q->rq.starved[0] + q->rq.starved[1];
4150 spin_unlock_irq(q->queue_lock);
4151 /* any requests still outstanding? */
4152 if (counts == 0)
4153 break;
4154
4155 /* This may be the same req as the previous iteration,
4156 * always send the blk_end_request_all after a prefetch.
4157 * It is not okay to not end the request because the
4158 * prefetch started the request.
4159 */
4160 if (req) {
4161 /* return -ENXIO to indicate that this queue is
4162 * going away
4163 */
4164 req->errors = -ENXIO;
4165 blk_end_request_all(req, -ENXIO);
4166 }
4167
4168 msleep(200); /* allow bsg to possibly finish */
4169 spin_lock_irq(q->queue_lock);
4170 }
4171
4172 bsg_unregister_queue(q); 4134 bsg_unregister_queue(q);
4173 blk_cleanup_queue(q); 4135 blk_cleanup_queue(q);
4174 } 4136 }
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index 1cf640e575da..c737a16b0a1d 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -575,7 +575,7 @@ static int iscsi_remove_host(struct transport_container *tc,
575 struct iscsi_cls_host *ihost = shost->shost_data; 575 struct iscsi_cls_host *ihost = shost->shost_data;
576 576
577 if (ihost->bsg_q) { 577 if (ihost->bsg_q) {
578 bsg_remove_queue(ihost->bsg_q); 578 bsg_unregister_queue(ihost->bsg_q);
579 blk_cleanup_queue(ihost->bsg_q); 579 blk_cleanup_queue(ihost->bsg_q);
580 } 580 }
581 return 0; 581 return 0;
diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h
index f55ab8cdc106..4d0fb3df2f4a 100644
--- a/include/linux/bsg-lib.h
+++ b/include/linux/bsg-lib.h
@@ -67,7 +67,6 @@ void bsg_job_done(struct bsg_job *job, int result,
67int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name, 67int bsg_setup_queue(struct device *dev, struct request_queue *q, char *name,
68 bsg_job_fn *job_fn, int dd_job_size); 68 bsg_job_fn *job_fn, int dd_job_size);
69void bsg_request_fn(struct request_queue *q); 69void bsg_request_fn(struct request_queue *q);
70void bsg_remove_queue(struct request_queue *q);
71void bsg_goose_queue(struct request_queue *q); 70void bsg_goose_queue(struct request_queue *q);
72 71
73#endif 72#endif