On Fri, Apr 25, 2025 at 04:03:08PM +0530, Nilay Shroff wrote: > @@ -4007,10 +4008,6 @@ static void nvme_ns_remove(struct nvme_ns *ns) > > mutex_lock(&ns->ctrl->subsys->lock); > list_del_rcu(&ns->siblings); > - if (list_empty(&ns->head->list)) { > - list_del_init(&ns->head->entry); > - last_path = true; > - } > mutex_unlock(&ns->ctrl->subsys->lock); > > /* guarantee not available in head->list */ > @@ -4028,8 +4025,7 @@ static void nvme_ns_remove(struct nvme_ns *ns) > mutex_unlock(&ns->ctrl->namespaces_lock); > synchronize_srcu(&ns->ctrl->srcu); > > - if (last_path) > - nvme_mpath_shutdown_disk(ns->head); > + nvme_mpath_shutdown_disk(ns->head); This now removes the head list deletion from the first critical section into nvme_mpath_shutdown_disk. I remember we had to do it the way it currently is done because we were running into issues otherwise, the commit history might help a bit with what the issues were. > + if (a == &dev_attr_delayed_removal_secs.attr) { > + struct nvme_ns_head *head = dev_to_ns_head(dev); > + struct gendisk *disk = dev_to_disk(dev); > + > + /* > + * This attribute is only valid for head node and non-fabric > + * setup. > + */ > + if (!nvme_disk_is_ns_head(disk) || > + test_bit(NVME_NSHEAD_FABRICS, &head->flags)) > + return 0; > + } Didn't we say we also want to allow fabrics to use it if explicitly configured?