[Midnightbsd-cvs] src [10006] trunk/sys/geom: sync with freebsd 10 stable

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 17:21:05 EDT 2018


Revision: 10006
          http://svnweb.midnightbsd.org/src/?rev=10006
Author:   laffer1
Date:     2018-05-27 17:21:04 -0400 (Sun, 27 May 2018)
Log Message:
-----------
sync with freebsd 10 stable

Modified Paths:
--------------
    trunk/sys/geom/geom_disk.c
    trunk/sys/geom/geom_disk.h
    trunk/sys/geom/geom_dump.c
    trunk/sys/geom/geom_event.c

Modified: trunk/sys/geom/geom_disk.c
===================================================================
--- trunk/sys/geom/geom_disk.c	2018-05-27 21:18:26 UTC (rev 10005)
+++ trunk/sys/geom/geom_disk.c	2018-05-27 21:21:04 UTC (rev 10006)
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_disk.c,v 1.104.2.1 2009/01/11 21:45:23 sam Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_disk.c 329319 2018-02-15 16:31:35Z avg $");
 
 #include "opt_geom.h"
 
@@ -44,11 +44,11 @@
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
 #include <sys/bio.h>
+#include <sys/bus.h>
 #include <sys/ctype.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
 #include <sys/sbuf.h>
-#include <sys/sysctl.h>
 #include <sys/devicestat.h>
 #include <machine/md_var.h>
 
@@ -60,6 +60,8 @@
 
 #include <dev/led/led.h>
 
+#include <machine/bus.h>
+
 struct g_disk_softc {
 	struct mtx		 done_mtx;
 	struct disk		*dp;
@@ -67,6 +69,7 @@
 	struct sysctl_oid	*sysctl_tree;
 	char			led[64];
 	uint32_t		state;
+	struct mtx		 start_mtx;
 };
 
 static g_access_t g_disk_access;
@@ -76,7 +79,7 @@
 static g_provgone_t g_disk_providergone;
 
 static struct g_class g_disk_class = {
-	.name = "DISK",
+	.name = G_DISK_CLASS_NAME,
 	.version = G_VERSION,
 	.start = g_disk_start,
 	.access = g_disk_access,
@@ -132,28 +135,38 @@
 	e += pp->ace;
 	error = 0;
 	if ((pp->acr + pp->acw + pp->ace) == 0 && (r + w + e) > 0) {
-		if (dp->d_open != NULL) {
+		/*
+		 * It would be better to defer this decision to d_open if
+		 * it was able to take flags.
+		 */
+		if (w > 0 && (dp->d_flags & DISKFLAG_WRITE_PROTECT) != 0)
+			error = EROFS;
+		if (error == 0 && dp->d_open != NULL) {
 			g_disk_lock_giant(dp);
 			error = dp->d_open(dp);
-			if (bootverbose && error != 0)
-				printf("Opened disk %s -> %d\n",
-				    pp->name, error);
 			g_disk_unlock_giant(dp);
 		}
+		if (bootverbose && error != 0)
+			printf("Opened disk %s -> %d\n", pp->name, error);
+		if (error != 0)
+			return (error);
 		pp->mediasize = dp->d_mediasize;
 		pp->sectorsize = dp->d_sectorsize;
-		if (dp->d_flags & DISKFLAG_CANDELETE)
-			pp->flags |= G_PF_CANDELETE;
-		else
-			pp->flags &= ~G_PF_CANDELETE;
-		pp->stripeoffset = dp->d_stripeoffset;
-		pp->stripesize = dp->d_stripesize;
-		dp->d_flags |= DISKFLAG_OPEN;
 		if (dp->d_maxsize == 0) {
 			printf("WARNING: Disk drive %s%d has no d_maxsize\n",
 			    dp->d_name, dp->d_unit);
 			dp->d_maxsize = DFLTPHYS;
 		}
+		if (dp->d_delmaxsize == 0) {
+			if (bootverbose && dp->d_flags & DISKFLAG_CANDELETE) {
+				printf("WARNING: Disk drive %s%d has no "
+				    "d_delmaxsize\n", dp->d_name, dp->d_unit);
+			}
+			dp->d_delmaxsize = dp->d_maxsize;
+		}
+		pp->stripeoffset = dp->d_stripeoffset;
+		pp->stripesize = dp->d_stripesize;
+		dp->d_flags |= DISKFLAG_OPEN;
 	} else if ((pp->acr + pp->acw + pp->ace) > 0 && (r + w + e) == 0) {
 		if (dp->d_close != NULL) {
 			g_disk_lock_giant(dp);
@@ -179,7 +192,7 @@
 
 	gkd = (struct g_kerneldump*)bp->bio_data;
 	gp = bp->bio_to->geom;
-	g_trace(G_T_TOPOLOGY, "g_disk_kernedump(%s, %jd, %jd)",
+	g_trace(G_T_TOPOLOGY, "g_disk_kerneldump(%s, %jd, %jd)",
 		gp->name, (intmax_t)gkd->offset, (intmax_t)gkd->length);
 	if (dp->d_dump == NULL) {
 		g_io_deliver(bp, ENODEV);
@@ -225,6 +238,7 @@
 static void
 g_disk_done(struct bio *bp)
 {
+	struct bintime now;
 	struct bio *bp2;
 	struct g_disk_softc *sc;
 
@@ -233,19 +247,21 @@
 	bp2 = bp->bio_parent;
 	sc = bp2->bio_to->private;
 	bp->bio_completed = bp->bio_length - bp->bio_resid;
+	binuptime(&now);
 	mtx_lock(&sc->done_mtx);
 	if (bp2->bio_error == 0)
 		bp2->bio_error = bp->bio_error;
 	bp2->bio_completed += bp->bio_completed;
-	if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE)) != 0)
-		devstat_end_transaction_bio(sc->dp->d_devstat, bp);
-	g_destroy_bio(bp);
+	if ((bp->bio_cmd & (BIO_READ|BIO_WRITE|BIO_DELETE|BIO_FLUSH)) != 0)
+		devstat_end_transaction_bio_bt(sc->dp->d_devstat, bp, &now);
 	bp2->bio_inbed++;
 	if (bp2->bio_children == bp2->bio_inbed) {
+		mtx_unlock(&sc->done_mtx);
 		bp2->bio_resid = bp2->bio_bcount - bp2->bio_completed;
 		g_io_deliver(bp2, bp2->bio_error);
-	}
-	mtx_unlock(&sc->done_mtx);
+	} else
+		mtx_unlock(&sc->done_mtx);
+	g_destroy_bio(bp);
 }
 
 static int
@@ -266,7 +282,146 @@
 	return (error);
 }
 
+static off_t
+g_disk_maxsize(struct disk *dp, struct bio *bp)
+{
+	if (bp->bio_cmd == BIO_DELETE)
+		return (dp->d_delmaxsize);
+	return (dp->d_maxsize);
+}
+
+static int
+g_disk_maxsegs(struct disk *dp, struct bio *bp)
+{
+	return ((g_disk_maxsize(dp, bp) / PAGE_SIZE) + 1);
+}
+
 static void
+g_disk_advance(struct disk *dp, struct bio *bp, off_t off)
+{
+
+	bp->bio_offset += off;
+	bp->bio_length -= off;
+
+	if ((bp->bio_flags & BIO_VLIST) != 0) {
+		bus_dma_segment_t *seg, *end;
+
+		seg = (bus_dma_segment_t *)bp->bio_data;
+		end = (bus_dma_segment_t *)bp->bio_data + bp->bio_ma_n;
+		off += bp->bio_ma_offset;
+		while (off >= seg->ds_len) {
+			KASSERT((seg != end),
+			    ("vlist request runs off the end"));
+			off -= seg->ds_len;
+			seg++;
+		}
+		bp->bio_ma_offset = off;
+		bp->bio_ma_n = end - seg;
+		bp->bio_data = (void *)seg;
+	} else if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+		bp->bio_ma += off / PAGE_SIZE;
+		bp->bio_ma_offset += off;
+		bp->bio_ma_offset %= PAGE_SIZE;
+		bp->bio_ma_n -= off / PAGE_SIZE;
+	} else {
+		bp->bio_data += off;
+	}
+}
+
+static void
+g_disk_seg_limit(bus_dma_segment_t *seg, off_t *poffset,
+    off_t *plength, int *ppages)
+{
+	uintptr_t seg_page_base;
+	uintptr_t seg_page_end;
+	off_t offset;
+	off_t length;
+	int seg_pages;
+
+	offset = *poffset;
+	length = *plength;
+
+	if (length > seg->ds_len - offset)
+		length = seg->ds_len - offset;
+
+	seg_page_base = trunc_page(seg->ds_addr + offset);
+	seg_page_end  = round_page(seg->ds_addr + offset + length);
+	seg_pages = (seg_page_end - seg_page_base) >> PAGE_SHIFT;
+
+	if (seg_pages > *ppages) {
+		seg_pages = *ppages;
+		length = (seg_page_base + (seg_pages << PAGE_SHIFT)) -
+		    (seg->ds_addr + offset);
+	}
+
+	*poffset = 0;
+	*plength -= length;
+	*ppages -= seg_pages;
+}
+
+static off_t
+g_disk_vlist_limit(struct disk *dp, struct bio *bp, bus_dma_segment_t **pendseg)
+{
+	bus_dma_segment_t *seg, *end;
+	off_t residual;
+	off_t offset;
+	int pages;
+
+	seg = (bus_dma_segment_t *)bp->bio_data;
+	end = (bus_dma_segment_t *)bp->bio_data + bp->bio_ma_n;
+	residual = bp->bio_length;
+	offset = bp->bio_ma_offset;
+	pages = g_disk_maxsegs(dp, bp);
+	while (residual != 0 && pages != 0) {
+		KASSERT((seg != end),
+		    ("vlist limit runs off the end"));
+		g_disk_seg_limit(seg, &offset, &residual, &pages);
+		seg++;
+	}
+	if (pendseg != NULL)
+		*pendseg = seg;
+	return (residual);
+}
+
+static bool
+g_disk_limit(struct disk *dp, struct bio *bp)
+{
+	bool limited = false;
+	off_t maxsz;
+
+	maxsz = g_disk_maxsize(dp, bp);
+
+	/*
+	 * XXX: If we have a stripesize we should really use it here.
+	 *      Care should be taken in the delete case if this is done
+	 *      as deletes can be very sensitive to size given how they
+	 *      are processed.
+	 */
+	if (bp->bio_length > maxsz) {
+		bp->bio_length = maxsz;
+		limited = true;
+	}
+
+	if ((bp->bio_flags & BIO_VLIST) != 0) {
+		bus_dma_segment_t *firstseg, *endseg;
+		off_t residual;
+
+		firstseg = (bus_dma_segment_t*)bp->bio_data;
+		residual = g_disk_vlist_limit(dp, bp, &endseg);
+		if (residual != 0) {
+			bp->bio_ma_n = endseg - firstseg;
+			bp->bio_length -= residual;
+			limited = true;
+		}
+	} else if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+		bp->bio_ma_n =
+		    howmany(bp->bio_ma_offset + bp->bio_length, PAGE_SIZE);
+	}
+
+	return (limited);
+}
+
+static void
 g_disk_start(struct bio *bp)
 {
 	struct bio *bp2, *bp3;
@@ -290,6 +445,9 @@
 		/* fall-through */
 	case BIO_READ:
 	case BIO_WRITE:
+		KASSERT((dp->d_flags & DISKFLAG_UNMAPPED_BIO) != 0 ||
+		    (bp->bio_flags & BIO_UNMAPPED) == 0,
+		    ("unmapped bio not supported by disk %s", dp->d_name));
 		off = 0;
 		bp3 = NULL;
 		bp2 = g_clone_bio(bp);
@@ -297,18 +455,11 @@
 			error = ENOMEM;
 			break;
 		}
-		do {
-			bp2->bio_offset += off;
-			bp2->bio_length -= off;
-			bp2->bio_data += off;
-			if (bp2->bio_length > dp->d_maxsize) {
+		for (;;) {
+			if (g_disk_limit(dp, bp2)) {
+				off += bp2->bio_length;
+
 				/*
-				 * XXX: If we have a stripesize we should really
-				 * use it here.
-				 */
-				bp2->bio_length = dp->d_maxsize;
-				off += dp->d_maxsize;
-				/*
 				 * To avoid a race, we need to grab the next bio
 				 * before we schedule this one.  See "notes".
 				 */
@@ -320,13 +471,20 @@
 			bp2->bio_pblkno = bp2->bio_offset / dp->d_sectorsize;
 			bp2->bio_bcount = bp2->bio_length;
 			bp2->bio_disk = dp;
+			mtx_lock(&sc->start_mtx); 
 			devstat_start_transaction_bio(dp->d_devstat, bp2);
+			mtx_unlock(&sc->start_mtx); 
 			g_disk_lock_giant(dp);
 			dp->d_strategy(bp2);
 			g_disk_unlock_giant(dp);
+
+			if (bp3 == NULL)
+				break;
+
 			bp2 = bp3;
 			bp3 = NULL;
-		} while (bp2 != NULL);
+			g_disk_advance(dp, bp2, off);
+		}
 		break;
 	case BIO_GETATTR:
 		/* Give the driver a chance to override */
@@ -350,23 +508,34 @@
 			break;
 		else if (g_handleattr_str(bp, "GEOM::ident", dp->d_ident))
 			break;
-		else if (g_handleattr(bp, "GEOM::hba_vendor",
-		    &dp->d_hba_vendor, 2))
+		else if (g_handleattr_str(bp, "GEOM::descr", dp->d_descr))
 			break;
-		else if (g_handleattr(bp, "GEOM::hba_device",
-		    &dp->d_hba_device, 2))
+		else if (g_handleattr_uint16_t(bp, "GEOM::hba_vendor",
+		    dp->d_hba_vendor))
 			break;
-		else if (g_handleattr(bp, "GEOM::hba_subvendor",
-		    &dp->d_hba_subvendor, 2))
+		else if (g_handleattr_uint16_t(bp, "GEOM::hba_device",
+		    dp->d_hba_device))
 			break;
-		else if (g_handleattr(bp, "GEOM::hba_subdevice",
-		    &dp->d_hba_subdevice, 2))
+		else if (g_handleattr_uint16_t(bp, "GEOM::hba_subvendor",
+		    dp->d_hba_subvendor))
 			break;
+		else if (g_handleattr_uint16_t(bp, "GEOM::hba_subdevice",
+		    dp->d_hba_subdevice))
+			break;
 		else if (!strcmp(bp->bio_attribute, "GEOM::kerneldump"))
 			g_disk_kerneldump(bp, dp);
 		else if (!strcmp(bp->bio_attribute, "GEOM::setstate"))
 			g_disk_setstate(bp, sc);
-		else 
+		else if (!strcmp(bp->bio_attribute, "GEOM::rotation_rate")) {
+			uint64_t v;
+
+			if ((dp->d_flags & DISKFLAG_LACKS_ROTRATE) == 0)
+				v = dp->d_rotation_rate;
+			else
+				v = 0; /* rate unknown */
+			g_handleattr_uint16_t(bp, "GEOM::rotation_rate", v);
+			break;
+		} else 
 			error = ENOIOCTL;
 		break;
 	case BIO_FLUSH:
@@ -383,6 +552,9 @@
 		}
 		bp2->bio_done = g_disk_done;
 		bp2->bio_disk = dp;
+		mtx_lock(&sc->start_mtx);
+		devstat_start_transaction_bio(dp->d_devstat, bp2);
+		mtx_unlock(&sc->start_mtx);
 		g_disk_lock_giant(dp);
 		dp->d_strategy(bp2);
 		g_disk_unlock_giant(dp);
@@ -399,8 +571,11 @@
 static void
 g_disk_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp)
 {
+	struct bio *bp;
 	struct disk *dp;
 	struct g_disk_softc *sc;
+	char *buf;
+	int res = 0;
 
 	sc = gp->softc;
 	if (sc == NULL || (dp = sc->dp) == NULL)
@@ -415,12 +590,91 @@
 		    indent, dp->d_fwheads);
 		sbuf_printf(sb, "%s<fwsectors>%u</fwsectors>\n",
 		    indent, dp->d_fwsectors);
-		sbuf_printf(sb, "%s<ident>%s</ident>\n", indent, dp->d_ident);
-		sbuf_printf(sb, "%s<descr>%s</descr>\n", indent, dp->d_descr);
+
+		/*
+		 * "rotationrate" is a little complicated, because the value
+		 * returned by the drive might not be the RPM; 0 and 1 are
+		 * special cases, and there's also a valid range.
+		 */
+		sbuf_printf(sb, "%s<rotationrate>", indent);
+		if (dp->d_rotation_rate == DISK_RR_UNKNOWN) /* Old drives */
+			sbuf_printf(sb, "unknown");	/* don't report RPM. */
+		else if (dp->d_rotation_rate == DISK_RR_NON_ROTATING)
+			sbuf_printf(sb, "0");
+		else if ((dp->d_rotation_rate >= DISK_RR_MIN) &&
+		    (dp->d_rotation_rate <= DISK_RR_MAX))
+			sbuf_printf(sb, "%u", dp->d_rotation_rate);
+		else
+			sbuf_printf(sb, "invalid");
+		sbuf_printf(sb, "</rotationrate>\n");
+		if (dp->d_getattr != NULL) {
+			buf = g_malloc(DISK_IDENT_SIZE, M_WAITOK);
+			bp = g_alloc_bio();
+			bp->bio_disk = dp;
+			bp->bio_attribute = "GEOM::ident";
+			bp->bio_length = DISK_IDENT_SIZE;
+			bp->bio_data = buf;
+			res = dp->d_getattr(bp);
+			sbuf_printf(sb, "%s<ident>", indent);
+			g_conf_printf_escaped(sb, "%s",
+			    res == 0 ? buf: dp->d_ident);
+			sbuf_printf(sb, "</ident>\n");
+			bp->bio_attribute = "GEOM::lunid";
+			bp->bio_length = DISK_IDENT_SIZE;
+			bp->bio_data = buf;
+			if (dp->d_getattr(bp) == 0) {
+				sbuf_printf(sb, "%s<lunid>", indent);
+				g_conf_printf_escaped(sb, "%s", buf);
+				sbuf_printf(sb, "</lunid>\n");
+			}
+			bp->bio_attribute = "GEOM::lunname";
+			bp->bio_length = DISK_IDENT_SIZE;
+			bp->bio_data = buf;
+			if (dp->d_getattr(bp) == 0) {
+				sbuf_printf(sb, "%s<lunname>", indent);
+				g_conf_printf_escaped(sb, "%s", buf);
+				sbuf_printf(sb, "</lunname>\n");
+			}
+			g_destroy_bio(bp);
+			g_free(buf);
+		} else {
+			sbuf_printf(sb, "%s<ident>", indent);
+			g_conf_printf_escaped(sb, "%s", dp->d_ident);
+			sbuf_printf(sb, "</ident>\n");
+		}
+		sbuf_printf(sb, "%s<descr>", indent);
+		g_conf_printf_escaped(sb, "%s", dp->d_descr);
+		sbuf_printf(sb, "</descr>\n");
 	}
 }
 
 static void
+g_disk_resize(void *ptr, int flag)
+{
+	struct disk *dp;
+	struct g_geom *gp;
+	struct g_provider *pp;
+
+	if (flag == EV_CANCEL)
+		return;
+	g_topology_assert();
+
+	dp = ptr;
+	gp = dp->d_geom;
+
+	if (dp->d_destroyed || gp == NULL)
+		return;
+
+	LIST_FOREACH(pp, &gp->provider, provider) {
+		if (pp->sectorsize != 0 &&
+		    pp->sectorsize != dp->d_sectorsize)
+			g_wither_provider(pp, ENXIO);
+		else
+			g_resize_provider(pp, dp->d_mediasize);
+	}
+}
+
+static void
 g_disk_create(void *arg, int flag)
 {
 	struct g_geom *gp;
@@ -434,17 +688,24 @@
 	g_topology_assert();
 	dp = arg;
 	sc = g_malloc(sizeof(*sc), M_WAITOK | M_ZERO);
+	mtx_init(&sc->start_mtx, "g_disk_start", NULL, MTX_DEF);
 	mtx_init(&sc->done_mtx, "g_disk_done", NULL, MTX_DEF);
 	sc->dp = dp;
 	gp = g_new_geomf(&g_disk_class, "%s%d", dp->d_name, dp->d_unit);
 	gp->softc = sc;
 	pp = g_new_providerf(gp, "%s", gp->name);
+	devstat_remove_entry(pp->stat);
+	pp->stat = NULL;
+	dp->d_devstat->id = pp;
 	pp->mediasize = dp->d_mediasize;
 	pp->sectorsize = dp->d_sectorsize;
-	if (dp->d_flags & DISKFLAG_CANDELETE)
-		pp->flags |= G_PF_CANDELETE;
 	pp->stripeoffset = dp->d_stripeoffset;
 	pp->stripesize = dp->d_stripesize;
+	if ((dp->d_flags & DISKFLAG_UNMAPPED_BIO) != 0)
+		pp->flags |= G_PF_ACCEPT_UNMAPPED;
+	if ((dp->d_flags & DISKFLAG_DIRECT_COMPLETION) != 0)
+		pp->flags |= G_PF_DIRECT_SEND;
+	pp->flags |= G_PF_DIRECT_RECEIVE;
 	if (bootverbose)
 		printf("GEOM: new disk %s\n", gp->name);
 	sysctl_ctx_init(&sc->sysctl_ctx);
@@ -480,16 +741,7 @@
 
 	sc = (struct g_disk_softc *)pp->private;
 	dp = sc->dp;
-
-	/*
-	 * FreeBSD 9 started with VERSION_01 of the struct disk structure.
-	 * However, g_gone was added in the middle of the branch.  To
-	 * cope with version being missing from struct disk, we set a flag
-	 * in g_disk_create for VERSION_01 and avoid touching the d_gone
-	 * field for old consumers.
-	 */
-	if (dp != NULL && (dp->d_flags & DISKFLAG_LACKS_GONE) == 0 &&
-	    dp->d_gone != NULL)
+	if (dp != NULL && dp->d_gone != NULL)
 		dp->d_gone(dp);
 	if (sc->sysctl_tree != NULL) {
 		sysctl_ctx_free(&sc->sysctl_ctx);
@@ -502,6 +754,7 @@
 	pp->private = NULL;
 	pp->geom->softc = NULL;
 	mtx_destroy(&sc->done_mtx);
+	mtx_destroy(&sc->start_mtx);
 	g_free(sc);
 }
 
@@ -561,7 +814,7 @@
 disk_create(struct disk *dp, int version)
 {
 
-	if (version != DISK_VERSION_02 && version != DISK_VERSION_01) {
+	if (version != DISK_VERSION) {
 		printf("WARNING: Attempt to add disk %s%d %s",
 		    dp->d_name, dp->d_unit,
 		    " using incompatible ABI version of disk(9)\n");
@@ -569,8 +822,8 @@
 		    dp->d_name, dp->d_unit);
 		return;
 	}
-	if (version == DISK_VERSION_01)
-		dp->d_flags |= DISKFLAG_LACKS_GONE;
+	if (version < DISK_VERSION_04)
+		dp->d_flags |= DISKFLAG_LACKS_ROTRATE;
 	KASSERT(dp->d_strategy != NULL, ("disk_create need d_strategy"));
 	KASSERT(dp->d_name != NULL, ("disk_create need d_name"));
 	KASSERT(*dp->d_name != 0, ("disk_create need d_name"));
@@ -617,11 +870,15 @@
 {
 	struct g_geom *gp;
 	struct g_provider *pp;
+	char devnamebuf[128];
 
 	gp = dp->d_geom;
 	if (gp != NULL)
 		LIST_FOREACH(pp, &gp->provider, provider)
 			(void)g_attr_changed(pp, attr, flag);
+	snprintf(devnamebuf, sizeof(devnamebuf), "devname=%s%d", dp->d_name,
+	    dp->d_unit);
+	devctl_notify("GEOM", "disk", attr, devnamebuf);
 }
 
 void
@@ -658,6 +915,16 @@
 	}
 }
 
+int
+disk_resize(struct disk *dp, int flag)
+{
+
+	if (dp->d_destroyed || dp->d_geom == NULL)
+		return (0);
+
+	return (g_post_event(g_disk_resize, dp, flag, NULL));
+}
+
 static void
 g_kern_disks(void *p, int flag __unused)
 {

Modified: trunk/sys/geom/geom_disk.h
===================================================================
--- trunk/sys/geom/geom_disk.h	2018-05-27 21:18:26 UTC (rev 10005)
+++ trunk/sys/geom/geom_disk.h	2018-05-27 21:21:04 UTC (rev 10006)
@@ -32,7 +32,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/geom_disk.h,v 1.7 2007/05/05 17:12:15 pjd Exp $
+ * $FreeBSD: stable/10/sys/geom/geom_disk.h 329319 2018-02-15 16:31:35Z avg $
  */
 
 #ifndef _GEOM_GEOM_DISK_H_
@@ -45,6 +45,8 @@
 #include <sys/_mutex.h>
 #include <sys/disk.h>
 
+#define G_DISK_CLASS_NAME	"DISK"
+
 struct disk;
 
 typedef	int	disk_open_t(struct disk *);
@@ -79,6 +81,7 @@
 	disk_ioctl_t		*d_ioctl;
 	dumper_t		*d_dump;
 	disk_getattr_t		*d_getattr;
+	disk_gone_t		*d_gone;
 
 	/* Info fields from driver to geom_disk.c. Valid when open */
 	u_int			d_sectorsize;
@@ -86,6 +89,7 @@
 	u_int			d_fwsectors;
 	u_int			d_fwheads;
 	u_int			d_maxsize;
+	off_t			d_delmaxsize;
 	u_int			d_stripeoffset;
 	u_int			d_stripesize;
 	char			d_ident[DISK_IDENT_SIZE];
@@ -98,16 +102,24 @@
 	/* Fields private to the driver */
 	void			*d_drv1;
 
-	/* new fields in stable - don't use if DISKFLAG_LACKS_GONE is set */
-	disk_gone_t		*d_gone;
+	/* New field - don't use if DISKFLAG_LACKS_ROTRATE is set */
+	uint16_t		d_rotation_rate;
 };
 
-#define DISKFLAG_NEEDSGIANT	0x1
-#define DISKFLAG_OPEN		0x2
-#define DISKFLAG_CANDELETE	0x4
-#define DISKFLAG_CANFLUSHCACHE	0x8
-#define DISKFLAG_LACKS_GONE	0x10
+#define	DISKFLAG_NEEDSGIANT		0x0001
+#define	DISKFLAG_OPEN			0x0002
+#define	DISKFLAG_CANDELETE		0x0004
+#define	DISKFLAG_CANFLUSHCACHE		0x0008
+#define	DISKFLAG_UNMAPPED_BIO		0x0010
+#define	DISKFLAG_DIRECT_COMPLETION	0x0020
+#define DISKFLAG_LACKS_ROTRATE		0x0040
+#define	DISKFLAG_WRITE_PROTECT		0x0100
 
+#define	DISK_RR_UNKNOWN		0
+#define	DISK_RR_NON_ROTATING	1
+#define	DISK_RR_MIN		0x0401
+#define	DISK_RR_MAX		0xfffe
+
 struct disk *disk_alloc(void);
 void disk_create(struct disk *disk, int version);
 void disk_destroy(struct disk *disk);
@@ -115,11 +127,14 @@
 void disk_attr_changed(struct disk *dp, const char *attr, int flag);
 void disk_media_changed(struct disk *dp, int flag);
 void disk_media_gone(struct disk *dp, int flag);
+int disk_resize(struct disk *dp, int flag);
 
 #define DISK_VERSION_00		0x58561059
 #define DISK_VERSION_01		0x5856105a
 #define DISK_VERSION_02		0x5856105b
-#define DISK_VERSION		DISK_VERSION_02
+#define DISK_VERSION_03		0x5856105c
+#define DISK_VERSION_04		0x5856105d
+#define DISK_VERSION		DISK_VERSION_04
 
 #endif /* _KERNEL */
 #endif /* _GEOM_GEOM_DISK_H_ */

Modified: trunk/sys/geom/geom_dump.c
===================================================================
--- trunk/sys/geom/geom_dump.c	2018-05-27 21:18:26 UTC (rev 10005)
+++ trunk/sys/geom/geom_dump.c	2018-05-27 21:21:04 UTC (rev 10006)
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_dump.c,v 1.32.2.1 2010/04/22 14:54:54 jh Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_dump.c 281301 2015-04-09 10:08:11Z mav $");
 
 #include <sys/param.h>
 #include <sys/sbuf.h>
@@ -45,6 +45,7 @@
 
 #include <geom/geom.h>
 #include <geom/geom_int.h>
+#include <geom/geom_disk.h>
 
 
 static void
@@ -147,7 +148,7 @@
 	sb = p;
 	g_topology_assert();
 	LIST_FOREACH(mp, &g_classes, class) {
-		if (!strcmp(mp->name, "DISK") || !strcmp(mp->name, "MD"))
+		if (!strcmp(mp->name, G_DISK_CLASS_NAME) || !strcmp(mp->name, "MD"))
 			g_conftxt_class(sb, mp);
 	}
 	sbuf_finish(sb);
@@ -154,25 +155,28 @@
 }
 
 
-static void
-g_conf_print_escaped(struct sbuf *sb, const char *fmt, const char *str)
+void
+g_conf_printf_escaped(struct sbuf *sb, const char *fmt, ...)
 {
 	struct sbuf *s;
 	const u_char *c;
+	va_list ap;
 
 	s = sbuf_new_auto();
+	va_start(ap, fmt);
+	sbuf_vprintf(s, fmt, ap);
+	va_end(ap);
+	sbuf_finish(s);
 
-	for (c = str; *c != '\0'; c++) {
+	for (c = sbuf_data(s); *c != '\0'; c++) {
 		if (*c == '&' || *c == '<' || *c == '>' ||
 		    *c == '\'' || *c == '"' || *c > 0x7e)
-			sbuf_printf(s, "&#x%X;", *c);
+			sbuf_printf(sb, "&#x%X;", *c);
 		else if (*c == '\t' || *c == '\n' || *c == '\r' || *c > 0x1f)
-			sbuf_putc(s, *c);
+			sbuf_putc(sb, *c);
 		else
-			sbuf_putc(s, '?');
+			sbuf_putc(sb, '?');
 	}
-	sbuf_finish(s);
-	sbuf_printf(sb, fmt, sbuf_data(s));
 	sbuf_delete(s);
 }
 
@@ -204,13 +208,17 @@
 	sbuf_printf(sb, "\t  <geom ref=\"%p\"/>\n", pp->geom);
 	sbuf_printf(sb, "\t  <mode>r%dw%de%d</mode>\n",
 	    pp->acr, pp->acw, pp->ace);
-	g_conf_print_escaped(sb, "\t  <name>%s</name>\n", pp->name);
+	sbuf_printf(sb, "\t  <name>");
+	g_conf_printf_escaped(sb, "%s", pp->name);
+	sbuf_printf(sb, "</name>\n");
 	sbuf_printf(sb, "\t  <mediasize>%jd</mediasize>\n",
 	    (intmax_t)pp->mediasize);
 	sbuf_printf(sb, "\t  <sectorsize>%u</sectorsize>\n", pp->sectorsize);
 	sbuf_printf(sb, "\t  <stripesize>%u</stripesize>\n", pp->stripesize);
 	sbuf_printf(sb, "\t  <stripeoffset>%u</stripeoffset>\n", pp->stripeoffset);
-	if (pp->geom->flags & G_GEOM_WITHER)
+	if (pp->flags & G_PF_WITHER)
+		sbuf_printf(sb, "\t  <wither/>\n");
+	else if (pp->geom->flags & G_GEOM_WITHER)
 		;
 	else if (pp->geom->dumpconf != NULL) {
 		sbuf_printf(sb, "\t  <config>\n");
@@ -229,7 +237,9 @@
 
 	sbuf_printf(sb, "    <geom id=\"%p\">\n", gp);
 	sbuf_printf(sb, "      <class ref=\"%p\"/>\n", gp->class);
-	g_conf_print_escaped(sb, "      <name>%s</name>\n", gp->name);
+	sbuf_printf(sb, "      <name>");
+	g_conf_printf_escaped(sb, "%s", gp->name);
+	sbuf_printf(sb, "</name>\n");
 	sbuf_printf(sb, "      <rank>%d</rank>\n", gp->rank);
 	if (gp->flags & G_GEOM_WITHER)
 		sbuf_printf(sb, "      <wither/>\n");
@@ -258,7 +268,9 @@
 	struct g_geom *gp2;
 
 	sbuf_printf(sb, "  <class id=\"%p\">\n", mp);
-	g_conf_print_escaped(sb, "    <name>%s</name>\n", mp->name);
+	sbuf_printf(sb, "    <name>");
+	g_conf_printf_escaped(sb, "%s", mp->name);
+	sbuf_printf(sb, "</name>\n");
 	LIST_FOREACH(gp2, &mp->geom, geom) {
 		if (gp != NULL && gp != gp2)
 			continue;

Modified: trunk/sys/geom/geom_event.c
===================================================================
--- trunk/sys/geom/geom_event.c	2018-05-27 21:18:26 UTC (rev 10005)
+++ trunk/sys/geom/geom_event.c	2018-05-27 21:21:04 UTC (rev 10006)
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_event.c,v 1.56.2.1 2011/01/15 09:36:31 jh Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_event.c 266970 2014-06-02 10:14:03Z ae $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -207,6 +207,14 @@
 		KASSERT(cp->geom->orphan != NULL,
 		    ("geom %s has no orphan, class %s",
 		    cp->geom->name, cp->geom->class->name));
+		/*
+		 * XXX: g_dev_orphan method does deferred destroying
+		 * and it is possible, that other event could already
+		 * call the orphan method. Check consumer's flags to
+		 * do not schedule it twice.
+		 */
+		if (cp->flags & G_CF_ORPHAN)
+			continue;
 		cp->flags |= G_CF_ORPHAN;
 		cp->geom->orphan(cp);
 	}



More information about the Midnightbsd-cvs mailing list