On (24/10/04 05:20), Christoph Hellwig wrote: > This needs to check for a NULL disk. And now that I'm looking at the > code a bit more this makes me worried that checking for q->disk here > sounds like a good way to hit a race with clearing it. So I fear we > need the other hack variant that sets QUEUE_FLAG_DYING unconditionally > in __blk_mark_disk_dead and then clears it again (for GD_OWNS_QUEUE > only) toward the end of del_gendisk. Something like this? --- diff --git a/block/genhd.c b/block/genhd.c index 1c05dd4c6980..aca43c8fa4ed 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -589,9 +589,6 @@ static void __blk_mark_disk_dead(struct gendisk *disk) if (test_and_set_bit(GD_DEAD, &disk->state)) return; - if (test_bit(GD_OWNS_QUEUE, &disk->state)) - blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue); - /* * Stop buffered writers from dirtying pages that can't be written out. */ @@ -649,6 +646,9 @@ void del_gendisk(struct gendisk *disk) disk_del_events(disk); + blk_queue_flag_set(QUEUE_FLAG_DYING, disk->queue); + wake_up_all(&disk->queue->mq_freeze_wq); + /* * Prevent new openers by unlinked the bdev inode. */ @@ -725,6 +725,9 @@ void del_gendisk(struct gendisk *disk) if (queue_is_mq(q)) blk_mq_exit_queue(q); } + + if (!test_bit(GD_OWNS_QUEUE, &disk->state)) + blk_queue_flag_clear(QUEUE_FLAG_DYING, disk->queue); } EXPORT_SYMBOL(del_gendisk);