]> www.infradead.org Git - nvme.git/commitdiff
nvme: reset delayed remove_work after reconnect
authorChristoph Hellwig <hch@lst.de>
Wed, 11 Jun 2025 04:50:47 +0000 (06:50 +0200)
committerChristoph Hellwig <hch@lst.de>
Tue, 17 Jun 2025 10:57:26 +0000 (12:57 +0200)
The remove_work will proceed with permanently disconnecting on the
initial final path failure if the head shows no paths after the delay.
If a new path connects while the remove_work is pending, and if that new
path happens to disconnect before that remove_work executes, the delayed
removal should reset based on the most recent path disconnect time, but
queue_delayed_work() won't do anything if the work is already pending.
Attempt to cancel the delayed work when a new path connects, and use
mod_delayed_work() in case the remove_work remains pending anyway.

Signed-off-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c
drivers/nvme/host/multipath.c

index 92697f98c601d4b89a1681bdfa1adca45e86af4a..724f5732786c071b5a87e6a7773f859e0f64ffbc 100644 (file)
@@ -4036,6 +4036,10 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
        list_add_tail_rcu(&ns->siblings, &head->list);
        ns->head = head;
        mutex_unlock(&ctrl->subsys->lock);
+
+#ifdef CONFIG_NVME_MULTIPATH
+       cancel_delayed_work(&head->remove_work);
+#endif
        return 0;
 
 out_put_ns_head:
index 140079ff86e6b80e8be5394301edddc8d4c52a45..1062467595f3351a14e82af098769552665077de 100644 (file)
@@ -1311,7 +1311,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head)
                 */
                if (!try_module_get(THIS_MODULE))
                        goto out;
-               queue_delayed_work(nvme_wq, &head->remove_work,
+               mod_delayed_work(nvme_wq, &head->remove_work,
                                head->delayed_removal_secs * HZ);
        } else {
                list_del_init(&head->entry);