diff --git a/block/blk-core.c b/block/blk-core.c index 9b2a05d00b9686e5257627bab853c458bd186f72..ffbe326c70b9d9911fa73b761f6db02190eca6fe 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -791,9 +791,12 @@ void blk_cleanup_queue(struct request_queue *q) * from more than one contexts. * * We rely on driver to deal with the race in case that queue - * initialization isn't done. + * initialization isn't done. If driver cannot deal the race, + * we try to call quiesce in kernel for these drivers that have + * set QUEUE_FLAG_FORECE_QUIESCE flag. */ - if (q->mq_ops && blk_queue_init_done(q)) + if (q->mq_ops && (blk_queue_init_done(q) || + test_bit(QUEUE_FLAG_FORECE_QUIESCE, &q->queue_flags))) blk_mq_quiesce_queue(q); /* for synchronous bio-based driver finish in-flight integrity i/o */ diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 009a5b2aa3d028eeebcf6e4c45560a1f644bd67b..27610816ccb8d5a188713d4cc2d2c74490f868ed 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -844,6 +844,10 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, *bflags |= BLIST_NOREPORTLUN; } + if (sdev->type == TYPE_ENCLOSURE) + set_bit(QUEUE_FLAG_FORECE_QUIESCE, + &sdev->request_queue->queue_flags); + /* * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI * spec says: The device server is capable of supporting the diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d3d81b56007fa8a7d51e9f43130de1ec39279c66..ad2b10c4a0797efbf7a4dc12d9650e9e03094aca 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -720,6 +720,7 @@ struct request_queue { #define QUEUE_FLAG_REGISTERED 26 /* queue has been registered to a disk */ #define QUEUE_FLAG_SCSI_PASSTHROUGH 27 /* queue supports SCSI commands */ #define QUEUE_FLAG_QUIESCED 28 /* queue has been quiesced */ +#define QUEUE_FLAG_FORECE_QUIESCE 29 /* force quiesce when cleanup queue */ #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ (1 << QUEUE_FLAG_SAME_COMP) | \