Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Mar 2026 18:01:15 +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: 628d7a3270b6 - main - nda: AC_GETDEV_CHANGED calls media chanaged for sectorsize change
Message-ID:  <69a721eb.42f2e.29157302@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=628d7a3270b64b6c7fae3b0c98068c670162a154

commit 628d7a3270b64b6c7fae3b0c98068c670162a154
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2026-03-03 17:59:36 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2026-03-03 17:59:36 +0000

    nda: AC_GETDEV_CHANGED calls media chanaged for sectorsize change
    
    When the sector size changes, we assume it's new media. When the
    mediasize changes, we'll just resize the disk (we get called for both
    events). When neither have changed, don't call either.
    
    Some NVMe drives (but not all) post a async event on page 4 with the
    sector size changes via a FORMAT command. We'll notice the new media
    right away, rather than the next device open. As a practical effect,
    this just means that certain geom operations will see it sooner. Since
    most drive interaction goes through open, that will catch those drives
    that do not post this event well enough.
    
    Sponsored by:           Netflix
    Differential Revision:  https://reviews.freebsd.org/D55521
---
 sys/cam/nvme/nvme_da.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/sys/cam/nvme/nvme_da.c b/sys/cam/nvme/nvme_da.c
index 2e8e376f985d..a1114ffe8a44 100644
--- a/sys/cam/nvme/nvme_da.c
+++ b/sys/cam/nvme/nvme_da.c
@@ -432,7 +432,7 @@ ndaclose(struct disk *dp)
 	    ("nda %d outstanding commands", softc->outstanding_cmds));
 	cam_periph_unlock(periph);
 	cam_periph_release(periph);
-	return (0);	
+	return (0);
 }
 
 static void
@@ -760,17 +760,23 @@ ndaasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
 	}
 	case AC_GETDEV_CHANGED:
 	{
-		int error;
+		off_t mediasize;
+		u_int sectorsize;
 
 		softc = periph->softc;
+		mediasize = softc->disk->d_mediasize;
+		sectorsize = softc->disk->d_sectorsize;
 		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;
-		}
+		/*
+		 * If the sectorsize changed, then it's new media. Otherwise if
+		 * the media size changed, resize the existing disk. Otherwise
+		 * do nothing.
+		 */
+		if (sectorsize != softc->disk->d_sectorsize)
+			disk_media_changed(softc->disk, M_WAITOK);
+		else if (mediasize != softc->disk->d_mediasize)
+			disk_resize(softc->disk, M_WAITOK);
 		break;
-
 	}
 	case AC_ADVINFO_CHANGED:
 	{


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69a721eb.42f2e.29157302>