summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorJames Bottomley <JBottomley@Parallels.com>2011-07-23 21:09:03 +0400
committerJames Bottomley <JBottomley@Parallels.com>2011-07-23 21:09:03 +0400
commit87045b033a62777337ae4aa62834876da09b5fb5 (patch)
tree26aefd28e436668ff906e42b1e0d75c056e33e01 /block
parent0d83ab65ff1b54ce8b6cd172285cf71a38c4cceb (diff)
parentbfe159a51203c15d23cb3158fffdc25ec4b4dda1 (diff)
downloadlinux-stable-87045b033a62777337ae4aa62834876da09b5fb5.tar.gz
linux-stable-87045b033a62777337ae4aa62834876da09b5fb5.tar.bz2
linux-stable-87045b033a62777337ae4aa62834876da09b5fb5.zip
Merge branch 'scsi-fixes'
Diffstat (limited to 'block')
-rw-r--r--block/blk-core.c3
-rw-r--r--block/blk-exec.c7
-rw-r--r--block/cfq-iosched.c8
3 files changed, 16 insertions, 2 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index d2f8f4049abd..1d49e1c7c905 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -839,6 +839,9 @@ struct request *blk_get_request(struct request_queue *q, int rw, gfp_t gfp_mask)
{
struct request *rq;
+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags)))
+ return NULL;
+
BUG_ON(rw != READ && rw != WRITE);
spin_lock_irq(q->queue_lock);
diff --git a/block/blk-exec.c b/block/blk-exec.c
index 8a0e7ec056e7..a1ebceb332f9 100644
--- a/block/blk-exec.c
+++ b/block/blk-exec.c
@@ -50,6 +50,13 @@ void blk_execute_rq_nowait(struct request_queue *q, struct gendisk *bd_disk,
{
int where = at_head ? ELEVATOR_INSERT_FRONT : ELEVATOR_INSERT_BACK;
+ if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
+ rq->errors = -ENXIO;
+ if (rq->end_io)
+ rq->end_io(rq, rq->errors);
+ return;
+ }
+
rq->rq_disk = bd_disk;
rq->end_io = done;
WARN_ON(irqs_disabled());
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
index f3799432676d..ae21919f15e1 100644
--- a/block/cfq-iosched.c
+++ b/block/cfq-iosched.c
@@ -2773,11 +2773,14 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
smp_wmb();
cic->key = cfqd_dead_key(cfqd);
+ rcu_read_lock();
if (rcu_dereference(ioc->ioc_data) == cic) {
+ rcu_read_unlock();
spin_lock(&ioc->lock);
rcu_assign_pointer(ioc->ioc_data, NULL);
spin_unlock(&ioc->lock);
- }
+ } else
+ rcu_read_unlock();
if (cic->cfqq[BLK_RW_ASYNC]) {
cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
@@ -3084,7 +3087,8 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
spin_lock_irqsave(&ioc->lock, flags);
- BUG_ON(ioc->ioc_data == cic);
+ BUG_ON(rcu_dereference_check(ioc->ioc_data,
+ lockdep_is_held(&ioc->lock)) == cic);
radix_tree_delete(&ioc->radix_root, cfqd->cic_index);
hlist_del_rcu(&cic->cic_list);