git: 96a7ed1e7fb4 - stable/15 - nvd: handle namespace changes

From: Warner Losh <imp_at_FreeBSD.org>
Date: Wed, 19 Nov 2025 04:13:25 UTC
The branch stable/15 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=96a7ed1e7fb41df17e783503371533cc8db98540

commit 96a7ed1e7fb41df17e783503371533cc8db98540
Author:     Wanpeng Qian <wanpengqian@gmail.com>
AuthorDate: 2025-11-18 17:24:13 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-11-19 04:10:53 +0000

    nvd: handle namespace changes
    
    Signal the new media size when the namespace changes size.
    
    Reviewed by:            imp
    Differential Revision:  https://reviews.freebsd.org/D33032
    
    (cherry picked from commit bd769e73d8f1d5141b1c2eb2322b4c6caed5d9e0)
---
 sys/dev/nvd/nvd.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/sys/dev/nvd/nvd.c b/sys/dev/nvd/nvd.c
index 33b43efd24c1..4737b2b03ae9 100644
--- a/sys/dev/nvd/nvd.c
+++ b/sys/dev/nvd/nvd.c
@@ -61,6 +61,7 @@ static void nvd_done(void *arg, const struct nvme_completion *cpl);
 static void nvd_gone(struct nvd_disk *ndisk);
 
 static void *nvd_new_disk(struct nvme_namespace *ns, void *ctrlr);
+static void *nvd_ns_changed(struct nvme_namespace *ns, void *ctrlr);
 
 static void *nvd_new_controller(struct nvme_controller *ctrlr);
 static void nvd_controller_fail(void *ctrlr);
@@ -154,7 +155,7 @@ nvd_load(void)
 	TAILQ_INIT(&ctrlr_head);
 	TAILQ_INIT(&disk_head);
 
-	consumer_handle = nvme_register_consumer(nvd_new_disk,
+	consumer_handle = nvme_register_consumer(nvd_ns_changed,
 	    nvd_new_controller, NULL, nvd_controller_fail);
 
 	return (consumer_handle != NULL ? 0 : -1);
@@ -512,6 +513,48 @@ nvd_new_disk(struct nvme_namespace *ns, void *ctrlr_arg)
 	return (ndisk);
 }
 
+static void
+nvd_resize(struct nvd_disk *ndisk)
+{
+	struct disk		*disk = ndisk->disk;
+	struct nvme_namespace	*ns = ndisk->ns;
+
+	disk->d_sectorsize = nvme_ns_get_sector_size(ns);
+	disk->d_mediasize = (off_t)nvme_ns_get_size(ns);
+	disk->d_maxsize = nvme_ns_get_max_io_xfer_size(ns);
+	disk->d_delmaxsize = (off_t)nvme_ns_get_size(ns);
+	if (disk->d_delmaxsize > nvd_delete_max)
+		disk->d_delmaxsize = nvd_delete_max;
+
+	disk_resize(disk, M_NOWAIT);
+
+	printf(NVD_STR"%u: NVMe namespace resized\n", ndisk->unit);
+	printf(NVD_STR"%u: %juMB (%ju %u byte sectors)\n", disk->d_unit,
+		(uintmax_t)disk->d_mediasize / (1024*1024),
+		(uintmax_t)disk->d_mediasize / disk->d_sectorsize,
+		disk->d_sectorsize);
+}
+
+static void *
+nvd_ns_changed(struct nvme_namespace *ns, void *ctrlr_arg)
+{
+	struct nvd_disk		*ndisk;
+	struct nvd_controller	*ctrlr = ctrlr_arg;
+
+	if ((ns->flags & NVME_NS_CHANGED) == 0)
+		return (nvd_new_disk(ns, ctrlr_arg));
+
+	mtx_lock(&nvd_lock);
+	TAILQ_FOREACH(ndisk, &ctrlr->disk_head, ctrlr_tailq) {
+		if (ndisk->ns->id != ns->id)
+			continue;
+		nvd_resize(ndisk);
+		break;
+	}
+	mtx_unlock(&nvd_lock);
+	return (ctrlr_arg);
+}
+
 static void
 nvd_controller_fail(void *ctrlr_arg)
 {