The branch main has been updated by imp:

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

commit 5c2186b992546bce212dfad3e49012f4c69c2d0c
Author:     Warner Losh <[email protected]>
AuthorDate: 2026-03-03 17:59:31 +0000
Commit:     Warner Losh <[email protected]>
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);

Reply via email to