git: 9a465b37ea17 - stable/15 - nda: React to namespace change events

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

URL: https://cgit.FreeBSD.org/src/commit/?id=9a465b37ea17642d45597d4ee7d3283b02dfa6f0

commit 9a465b37ea17642d45597d4ee7d3283b02dfa6f0
Author:     Wanpeng Qian <wanpengqian@gmail.com>
AuthorDate: 2025-11-18 15:24:23 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2025-11-19 04:10:53 +0000

    nda: React to namespace change events
    
    Register for AC_GETDEV_CHANGED. When we receive a namespace
    notification, we only create a new device if it was unconfigured. If it
    was configured, generate this async event. Rely on the fact that we
    reconstruct namespace to just get the data from the identify data and
    call disk_resised.
    
    Reviewed by: imp
    Differential Revision: https://reviews.freebsd.org/D33032
    
    (cherry picked from commit 86d3ec359a56d1b5d015718bd19ef4bda681a032)
---
 sys/cam/nvme/nvme_da.c  | 29 ++++++++++++++++++++---------
 sys/cam/nvme/nvme_xpt.c |  2 ++
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 330f4ca66e1e..2eb43809f4b1 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -673,12 +673,11 @@ ndasetgeom(struct nda_softc *softc, struct cam_periph *periph)
 }
 
 static void
-ndaasync(void *callback_arg, uint32_t code,
-	struct cam_path *path, void *arg)
+ndaasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
 {
-	struct cam_periph *periph;
+	struct cam_periph *periph = callback_arg;
+	struct nda_softc *softc;
 
-	periph = (struct cam_periph *)callback_arg;
 	switch (code) {
 	case AC_FOUND_DEVICE:
 	{
@@ -709,17 +708,29 @@ ndaasync(void *callback_arg, uint32_t code,
 				"due to status 0x%x\n", status);
 		break;
 	}
+	case AC_GETDEV_CHANGED:
+	{
+		int error;
+
+		softc = periph->softc;
+		ndasetgeom(softc, periph);
+		error = disk_resize(softc->disk, M_NOWAIT);
+		if (error != 0) {
+			xpt_print(periph->path, "disk_resize(9) failed, error = %d\n", error);
+			break;
+		}
+		break;
+
+	}
 	case AC_ADVINFO_CHANGED:
 	{
 		uintptr_t buftype;
 
+		softc = periph->softc;
 		buftype = (uintptr_t)arg;
 		if (buftype == CDAI_TYPE_PHYS_PATH) {
-			struct nda_softc *softc;
-
-			softc = periph->softc;
 			disk_attr_changed(softc->disk, "GEOM::physpath",
-					  M_NOWAIT);
+			    M_NOWAIT);
 		}
 		break;
 	}
@@ -997,7 +1008,7 @@ ndaregister(struct cam_periph *periph, void *arg)
 	 * Register for device going away and info about the drive
 	 * changing (though with NVMe, it can't)
 	 */
-	xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED,
+	xpt_register_async(AC_LOST_DEVICE | AC_ADVINFO_CHANGED | AC_GETDEV_CHANGED,
 	    ndaasync, periph, periph->path);
 
 	softc->state = NDA_STATE_NORMAL;
diff --git a/sys/cam/nvme/nvme_xpt.c b/sys/cam/nvme/nvme_xpt.c
index f6667df07be0..c22d5fed350c 100644
--- a/sys/cam/nvme/nvme_xpt.c
+++ b/sys/cam/nvme/nvme_xpt.c
@@ -463,6 +463,8 @@ device_fail:	if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 			done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 			xpt_action(done_ccb);
 			xpt_async(AC_FOUND_DEVICE, path, done_ccb);
+		} else {
+			xpt_async(AC_GETDEV_CHANGED, path, NULL);
 		}
 		NVME_PROBE_SET_ACTION(softc, NVME_PROBE_DONE);
 		break;