nvme: fix possible io failures when removing multipathed ns
[platform/kernel/linux-rpi.git] / drivers / nvme / host / core.c
index d8869d9..e26d119 100644 (file)
@@ -3168,6 +3168,14 @@ static void nvme_ns_remove(struct nvme_ns *ns)
                return;
 
        nvme_fault_inject_fini(ns);
+
+       mutex_lock(&ns->ctrl->subsys->lock);
+       list_del_rcu(&ns->siblings);
+       mutex_unlock(&ns->ctrl->subsys->lock);
+       synchronize_rcu(); /* guarantee not available in head->list */
+       nvme_mpath_clear_current_path(ns);
+       synchronize_srcu(&ns->head->srcu); /* wait for concurrent submissions */
+
        if (ns->disk && ns->disk->flags & GENHD_FL_UP) {
                sysfs_remove_group(&disk_to_dev(ns->disk)->kobj,
                                        &nvme_ns_id_attr_group);
@@ -3179,16 +3187,10 @@ static void nvme_ns_remove(struct nvme_ns *ns)
                        blk_integrity_unregister(ns->disk);
        }
 
-       mutex_lock(&ns->ctrl->subsys->lock);
-       list_del_rcu(&ns->siblings);
-       nvme_mpath_clear_current_path(ns);
-       mutex_unlock(&ns->ctrl->subsys->lock);
-
        down_write(&ns->ctrl->namespaces_rwsem);
        list_del_init(&ns->list);
        up_write(&ns->ctrl->namespaces_rwsem);
 
-       synchronize_srcu(&ns->head->srcu);
        nvme_mpath_check_last_path(ns);
        nvme_put_ns(ns);
 }