diff options
author | Christoph Hellwig <hch@lst.de> | 2020-09-28 12:11:42 +0200 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2020-10-07 07:56:18 +0200 |
commit | f9d5f4579feafa721dba2f350fc064a1852c6f8c (patch) | |
tree | 0ba5a6ebdd7676008f8bebe6d2430cca9581769c /drivers/nvme/host | |
parent | d4609ea8b3d3fb3423f35805843a82774cb4ef2f (diff) | |
download | lwn-f9d5f4579feafa721dba2f350fc064a1852c6f8c.tar.gz lwn-f9d5f4579feafa721dba2f350fc064a1852c6f8c.zip |
nvme: freeze the queue over ->lba_shift updates
Ensure that there can't be any I/O in flight went we change the disk
geometry in nvme_update_ns_info, most notable the LBA size by lifting
the queue free from nvme_update_disk_info into the caller
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Damien Le Moal <damien.lemoal@wdc.com>
Diffstat (limited to 'drivers/nvme/host')
-rw-r--r-- | drivers/nvme/host/core.c | 20 |
1 files changed, 14 insertions, 6 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 443aba9c9fdd..82cd03c0ba21 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2021,7 +2021,7 @@ static void nvme_update_disk_info(struct gendisk *disk, /* unsupported block size, set capacity to 0 later */ bs = (1 << 9); } - blk_mq_freeze_queue(disk->queue); + blk_integrity_unregister(disk); atomic_bs = phys_bs = bs; @@ -2086,8 +2086,6 @@ static void nvme_update_disk_info(struct gendisk *disk, set_disk_ro(disk, true); else set_disk_ro(disk, false); - - blk_mq_unfreeze_queue(disk->queue); } static inline bool nvme_first_scan(struct gendisk *disk) @@ -2133,6 +2131,7 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) struct nvme_ctrl *ctrl = ns->ctrl; int ret; + blk_mq_freeze_queue(ns->disk->queue); /* * If identify namespace failed, use default 512 byte block size so * block layer can use before failing read/write for 0 capacity. @@ -2150,30 +2149,39 @@ static int nvme_update_ns_info(struct nvme_ns *ns, struct nvme_id_ns *id) dev_warn(ctrl->device, "failed to add zoned namespace:%u ret:%d\n", ns->head->ns_id, ret); - return ret; + goto out_unfreeze; } break; default: dev_warn(ctrl->device, "unknown csi:%u ns:%u\n", ns->head->ids.csi, ns->head->ns_id); - return -ENODEV; + ret = -ENODEV; + goto out_unfreeze; } ret = nvme_configure_metadata(ns, id); if (ret) - return ret; + goto out_unfreeze; nvme_set_chunk_sectors(ns, id); nvme_update_disk_info(ns->disk, ns, id); + blk_mq_unfreeze_queue(ns->disk->queue); + #ifdef CONFIG_NVME_MULTIPATH if (ns->head->disk) { + blk_mq_freeze_queue(ns->head->disk->queue); nvme_update_disk_info(ns->head->disk, ns, id); blk_stack_limits(&ns->head->disk->queue->limits, &ns->queue->limits, 0); blk_queue_update_readahead(ns->head->disk->queue); nvme_update_bdev_size(ns->head->disk); + blk_mq_unfreeze_queue(ns->head->disk->queue); } #endif return 0; + +out_unfreeze: + blk_mq_unfreeze_queue(ns->disk->queue); + return ret; } static int nvme_validate_ns(struct nvme_ns *ns) |