Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Mar 2026 18:01:14 +0000
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 5c2186b99254 - main - nda: Rescan the drive on open
Message-ID:  <69a721ea.43196.3698350a@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=5c2186b992546bce212dfad3e49012f4c69c2d0c

commit 5c2186b992546bce212dfad3e49012f4c69c2d0c
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-03-03 17:59:31 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-03-03 17:59:31 +0000

    nda: Rescan the drive on open
    
    SCSI and ATA drives rescan the drive on opens to catch changes to the
    disk. We do it here to so we catch if a drive has been FORMATed or
    SANITIZEd with different parameters. We don't use xpt_rescan() since we
    don't want to interfere with boot or keep all busses locked (this rescan
    won't change the bus, so we don't need the CAM topo lock).
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D55520
---
 sys/cam/nvme/nvme_da.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 47 insertions(+), 2 deletions(-)

diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 9646b792e9a9..2e8e376f985d 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -73,12 +73,14 @@ typedef enum {
 	NDA_FLAG_OPEN		= 0x0001,
 	NDA_FLAG_DIRTY		= 0x0002,
 	NDA_FLAG_SCTX_INIT	= 0x0004,
+	NDA_FLAG_RESCAN		= 0x0008,
 } nda_flags;
 #define NDA_FLAG_STRING		\
 	"\020"			\
 	"\001OPEN"		\
 	"\002DIRTY"		\
-	"\003SCTX_INIT"
+	"\003SCTX_INIT"		\
+	"\004RESCAN"
 
 typedef enum {
 	NDA_Q_4K   = 0x01,
@@ -318,11 +320,27 @@ ndasetgeom(struct nda_softc *softc, struct cam_periph *periph)
 	disk->d_flags |= flags;
 }
 
+static void
+ndaopen_rescan_done(struct cam_periph *periph, union ccb *ccb)
+{
+	struct nda_softc *softc;
+
+	softc = (struct nda_softc *)periph->softc;
+
+	cam_periph_assert(periph, MA_OWNED);
+
+	softc->flags &= ~NDA_FLAG_RESCAN;
+	xpt_release_ccb(ccb);
+	wakeup(&softc->disk->d_mediasize);
+}
+
+
 static int
 ndaopen(struct disk *dp)
 {
 	struct cam_periph *periph;
 	struct nda_softc *softc;
+	union ccb *ccb;
 	int error;
 
 	periph = (struct cam_periph *)dp->d_drv1;
@@ -337,10 +355,37 @@ ndaopen(struct disk *dp)
 		return (error);
 	}
 
+	softc = (struct nda_softc *)periph->softc;
 	CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
 	    ("ndaopen\n"));
 
-	softc = (struct nda_softc *)periph->softc;
+	/*
+	 * Rescan the lun in case the mediasize or sectorsize has changed since
+	 * we probed the device. Format and secure erase operations can do this,
+	 * but the nvme standard doesn't require a async notification of that
+	 * happening. da/ada do this by restarting their probe, but since
+	 * nvme_xpt gets the identify information we need, we just rescan here
+	 * since it's the easiest way to notice size changes.
+	 *
+	 * Not acquiring / releasing for the geom probe -- it's inline
+	 */
+	ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
+	ccb->ccb_h.func_code = XPT_SCAN_LUN;
+	ccb->ccb_h.cbfcnp = ndaopen_rescan_done;
+	ccb->ccb_h.ppriv_ptr0 = periph;
+	ccb->crcn.flags = 0;
+	xpt_action(ccb);
+
+	softc->flags |= NDA_FLAG_RESCAN;
+	error = 0;
+	while ((softc->flags & NDA_FLAG_RESCAN) != 0 && error == 0)
+		error = cam_periph_sleep(periph, &softc->disk->d_mediasize, PRIBIO,
+		    "ndareprobe", 0);
+	if (error != 0)
+		xpt_print(periph->path, "Unable to retrieve capacity data\n");
+	else
+		ndasetgeom(softc, periph);
+
 	softc->flags |= NDA_FLAG_OPEN;
 
 	cam_periph_unhold(periph);


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69a721ea.43196.3698350a>