Messages in this thread Patch in this message | | | Date | Tue, 14 Nov 2006 15:34:25 +0100 | From | Pierre Ossman <> | Subject | Re: How to cleanly shut down a block device |
| |
How about this patch? It is basically the same as the previous, but it also sets queuedata to NULL and tests for that. It does not address if someone still has dependencies on the queue but hasn't gotten itself a reference (as I haven't gotten any word on if that is a problem):
diff --git a/drivers/mmc/mmc_block.c b/drivers/mmc/mmc_block.c index f9027c8..5025abe 100644 --- a/drivers/mmc/mmc_block.c +++ b/drivers/mmc/mmc_block.c @@ -83,7 +83,6 @@ static void mmc_blk_put(struct mmc_blk_d md->usage--; if (md->usage == 0) { put_disk(md->disk); - mmc_cleanup_queue(&md->queue); kfree(md); } mutex_unlock(&open_lock); @@ -553,12 +552,11 @@ static void mmc_blk_remove(struct mmc_ca if (md) { int devidx; + /* Stop new requests from getting into the queue */ del_gendisk(md->disk); - /* - * I think this is needed. - */ - md->disk->queue = NULL; + /* Then flush out any already in there */ + mmc_cleanup_queue(&md->queue); devidx = md->disk->first_minor >> MMC_SHIFT; __clear_bit(devidx, dev_use); diff --git a/drivers/mmc/mmc_queue.c b/drivers/mmc/mmc_queue.c index 4ccdd82..b6769e2 100644 --- a/drivers/mmc/mmc_queue.c +++ b/drivers/mmc/mmc_queue.c @@ -111,6 +111,19 @@ static int mmc_queue_thread(void *d) static void mmc_request(request_queue_t *q) { struct mmc_queue *mq = q->queuedata; + struct request *req; + int ret; + + if (!mq) { + printk(KERN_ERR "MMC: killing requests for dead queue\n"); + while ((req = elv_next_request(q)) != NULL) { + do { + ret = end_that_request_chunk(req, 0, + req->current_nr_sectors << 9); + } while (ret); + } + return; + } if (!mq->req) wake_up(&mq->thread_wq); @@ -179,6 +192,15 @@ EXPORT_SYMBOL(mmc_init_queue); void mmc_cleanup_queue(struct mmc_queue *mq) { + request_queue_t *q = mq->queue; + unsigned long flags; + + /* Mark that we should start throwing out stragglers */ + spin_lock_irqsave(q->queue_lock, flags); + q->queuedata = NULL; + spin_unlock_irqrestore(q->queue_lock, flags); + + /* Then terminate our worker thread */ mq->flags |= MMC_QUEUE_EXIT; wake_up(&mq->thread_wq); wait_for_completion(&mq->thread_complete); Rgds
-- -- Pierre Ossman
Linux kernel, MMC maintainer http://www.kernel.org PulseAudio, core developer http://pulseaudio.org rdesktop, core developer http://www.rdesktop.org
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |