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

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun May 27 17:25:46 EDT 2018


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

Modified Paths:
--------------
    trunk/sys/geom/geom_kern.c
    trunk/sys/geom/geom_map.c
    trunk/sys/geom/geom_mbr.c
    trunk/sys/geom/geom_mbr_enc.c
    trunk/sys/geom/geom_pc98.c
    trunk/sys/geom/geom_pc98_enc.c
    trunk/sys/geom/geom_redboot.c
    trunk/sys/geom/geom_slice.c
    trunk/sys/geom/geom_slice.h
    trunk/sys/geom/geom_subr.c
    trunk/sys/geom/geom_sunlabel.c
    trunk/sys/geom/geom_sunlabel_enc.c
    trunk/sys/geom/geom_vfs.c
    trunk/sys/geom/geom_vfs.h
    trunk/sys/geom/geom_vol_ffs.c

Modified: trunk/sys/geom/geom_kern.c
===================================================================
--- trunk/sys/geom/geom_kern.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_kern.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/geom_kern.c,v 1.4 2011/12/10 22:55:34 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Poul-Henning Kamp
  * Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_kern.c,v 1.41.2.1 2009/01/11 21:45:23 sam Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_kern.c 273736 2014-10-27 14:38:00Z hselasky $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -67,6 +67,7 @@
 int g_debugflags;
 int g_collectstats = 1;
 int g_shutdown;
+int g_notaste;
 
 /*
  * G_UP and G_DOWN are the two threads which push I/O through the
@@ -124,6 +125,13 @@
 	/* NOTREACHED */
 }
 
+int
+g_is_geom_thread(struct thread *td)
+{
+
+	return (td == g_up_td || td == g_down_td || td == g_event_td);
+}
+
 static void
 geom_shutdown(void *foo __unused)
 {
@@ -209,17 +217,20 @@
 SYSCTL_INT(_kern_geom, OID_AUTO, debugflags, CTLFLAG_RW,
 	&g_debugflags, 0, "Set various trace levels for GEOM debugging");
 
+SYSCTL_INT(_kern_geom, OID_AUTO, notaste, CTLFLAG_RW,
+	&g_notaste, 0, "Prevent GEOM tasting");
+
 SYSCTL_INT(_kern_geom, OID_AUTO, collectstats, CTLFLAG_RW,
 	&g_collectstats, 0,
 	"Control statistics collection on GEOM providers and consumers");
 
 SYSCTL_INT(_debug_sizeof, OID_AUTO, g_class, CTLFLAG_RD,
-	0, sizeof(struct g_class), "sizeof(struct g_class)");
+	SYSCTL_NULL_INT_PTR, sizeof(struct g_class), "sizeof(struct g_class)");
 SYSCTL_INT(_debug_sizeof, OID_AUTO, g_geom, CTLFLAG_RD,
-	0, sizeof(struct g_geom), "sizeof(struct g_geom)");
+	SYSCTL_NULL_INT_PTR, sizeof(struct g_geom), "sizeof(struct g_geom)");
 SYSCTL_INT(_debug_sizeof, OID_AUTO, g_provider, CTLFLAG_RD,
-	0, sizeof(struct g_provider), "sizeof(struct g_provider)");
+	SYSCTL_NULL_INT_PTR, sizeof(struct g_provider), "sizeof(struct g_provider)");
 SYSCTL_INT(_debug_sizeof, OID_AUTO, g_consumer, CTLFLAG_RD,
-	0, sizeof(struct g_consumer), "sizeof(struct g_consumer)");
+	SYSCTL_NULL_INT_PTR, sizeof(struct g_consumer), "sizeof(struct g_consumer)");
 SYSCTL_INT(_debug_sizeof, OID_AUTO, g_bioq, CTLFLAG_RD,
-	0, sizeof(struct g_bioq), "sizeof(struct g_bioq)");
+	SYSCTL_NULL_INT_PTR, sizeof(struct g_bioq), "sizeof(struct g_bioq)");

Modified: trunk/sys/geom/geom_map.c
===================================================================
--- trunk/sys/geom/geom_map.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_map.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2010-2011 Aleksandr Rybalko <ray at dlink.ua>
  *   based on geom_redboot.c
@@ -30,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_map.c 237875 2012-07-01 05:22:13Z imp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -119,13 +120,13 @@
 	g_slice_dumpconf(sb, indent, gp, cp, pp);
 	if (pp != NULL) {
 		if (indent == NULL) {
-			sbuf_printf(sb, " entry %lld", sc->entry[pp->index]);
-			sbuf_printf(sb, " dsize %lld", sc->dsize[pp->index]);
+			sbuf_printf(sb, " entry %jd", (intmax_t)sc->entry[pp->index]);
+			sbuf_printf(sb, " dsize %jd", (intmax_t)sc->dsize[pp->index]);
 		} else {
-			sbuf_printf(sb, "%s<entry>%lld</entry>\n", indent,
-			    sc->entry[pp->index]);
-			sbuf_printf(sb, "%s<dsize>%lld</dsize>\n", indent,
-			    sc->dsize[pp->index]);
+			sbuf_printf(sb, "%s<entry>%jd</entry>\n", indent,
+			    (intmax_t)sc->entry[pp->index]);
+			sbuf_printf(sb, "%s<dsize>%jd</dsize>\n", indent,
+			    (intmax_t)sc->dsize[pp->index]);
 		}
 	}
 }
@@ -153,8 +154,8 @@
 		return (1);
 
 	if (bootverbose) {
-		printf("MAP: search key \"%s\" from 0x%llx, step 0x%llx\n",
-		    search_key, search_start, search_step);
+		printf("MAP: search key \"%s\" from 0x%jx, step 0x%jx\n",
+		    search_key, (intmax_t)search_start, (intmax_t)search_step);
 	}
 
 	/* error if search_key is empty */
@@ -321,9 +322,10 @@
 	}
 
 	if (bootverbose) {
-		printf("MAP: %llxx%llx, data=%llxx%llx "
+		printf("MAP: %jxx%jx, data=%jxx%jx "
 		    "\"/dev/map/%s\"\n",
-		    start, size, offset, dsize, name);
+		    (intmax_t)start, (intmax_t)size, (intmax_t)offset,
+		    (intmax_t)dsize, name);
 	}
 
 	sc->offset[i] = start;

Modified: trunk/sys/geom/geom_mbr.c
===================================================================
--- trunk/sys/geom/geom_mbr.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_mbr.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_mbr.c,v 1.68 2005/11/30 22:15:00 sobomax Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_mbr.c 243333 2012-11-20 12:32:18Z jh $");
 
 #include <sys/param.h>
 #include <sys/errno.h>

Modified: trunk/sys/geom/geom_mbr_enc.c
===================================================================
--- trunk/sys/geom/geom_mbr_enc.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_mbr_enc.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_mbr_enc.c,v 1.3 2005/01/06 18:27:29 imp Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_mbr_enc.c 139778 2005-01-06 18:27:30Z imp $");
 
 #include <sys/types.h>
 #include <sys/diskmbr.h>

Modified: trunk/sys/geom/geom_pc98.c
===================================================================
--- trunk/sys/geom/geom_pc98.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_pc98.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Poul-Henning Kamp
  * Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -31,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_pc98.c 254015 2013-08-07 00:00:48Z marcel $");
 
 #include <sys/param.h>
 #include <sys/endian.h>
@@ -56,7 +57,7 @@
 
 struct g_pc98_softc {
 	u_int fwsectors, fwheads, sectorsize;
-	int type[NDOSPART];
+	int type[PC98_NPARTS];
 	u_char sec[8192];
 };
 
@@ -84,8 +85,8 @@
 g_pc98_modify(struct g_geom *gp, struct g_pc98_softc *ms, u_char *sec, int len __unused)
 {
 	int i, error;
-	off_t s[NDOSPART], l[NDOSPART];
-	struct pc98_partition dp[NDOSPART];
+	off_t s[PC98_NPARTS], l[PC98_NPARTS];
+	struct pc98_partition dp[PC98_NPARTS];
 
 	g_topology_assert();
 	
@@ -114,11 +115,11 @@
 		return (EBUSY);
 #endif
 
-	for (i = 0; i < NDOSPART; i++)
+	for (i = 0; i < PC98_NPARTS; i++)
 		pc98_partition_dec(
 			sec + 512 + i * sizeof(struct pc98_partition), &dp[i]);
 
-	for (i = 0; i < NDOSPART; i++) {
+	for (i = 0; i < PC98_NPARTS; i++) {
 		/* If start and end are identical it's bogus */
 		if (dp[i].dp_ssect == dp[i].dp_esect &&
 		    dp[i].dp_shd == dp[i].dp_ehd &&
@@ -146,7 +147,7 @@
 			return (error);
 	}
 
-	for (i = 0; i < NDOSPART; i++) {
+	for (i = 0; i < PC98_NPARTS; i++) {
 		ms->type[i] = (dp[i].dp_sid << 8) | dp[i].dp_mid;
 		g_slice_config(gp, i, G_SLICE_CONFIG_SET, s[i], l[i],
 			       ms->sectorsize, "%ss%d", gp->name, i + 1);
@@ -269,7 +270,8 @@
 	if (flags == G_TF_NORMAL &&
 	    !strcmp(pp->geom->class->name, PC98_CLASS_NAME))
 		return (NULL);
-	gp = g_slice_new(mp, NDOSPART, pp, &cp, &ms, sizeof *ms, g_pc98_start);
+	gp = g_slice_new(mp, PC98_NPARTS, pp, &cp, &ms, sizeof *ms,
+	    g_pc98_start);
 	if (gp == NULL)
 		return (NULL);
 	g_topology_unlock();

Modified: trunk/sys/geom/geom_pc98_enc.c
===================================================================
--- trunk/sys/geom/geom_pc98_enc.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_pc98_enc.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 TAKAHASHI Yoshihiro
  * All rights reserved.
@@ -25,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_pc98_enc.c 145761 2005-05-01 09:44:50Z nyan $");
 
 #include <sys/types.h>
 #include <sys/diskpc98.h>

Modified: trunk/sys/geom/geom_redboot.c
===================================================================
--- trunk/sys/geom/geom_redboot.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_redboot.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2009 Sam Leffler, Errno Consulting
  * All rights reserved.
@@ -28,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_redboot.c 203411 2010-02-03 01:12:19Z gonzo $");
 
 #include <sys/param.h>
 #include <sys/errno.h>

Modified: trunk/sys/geom/geom_slice.c
===================================================================
--- trunk/sys/geom/geom_slice.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_slice.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_slice.c,v 1.62.2.1 2009/01/11 21:45:23 sam Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_slice.c 325908 2017-11-16 22:37:03Z avg $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -44,7 +44,6 @@
 #include <sys/bio.h>
 #include <sys/sysctl.h>
 #include <sys/proc.h>
-#include <sys/kthread.h>
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/errno.h>
@@ -73,10 +72,19 @@
 }
 
 static void
-g_slice_free(struct g_slicer *gsp)
+g_slice_free(struct g_geom *gp)
 {
+	struct g_slicer *gsp;
 
-	if (gsp == NULL)	/* XXX: phk thinks about this */
+	gsp = gp->softc;
+	gp->softc = NULL;
+
+	/*
+	 * We can get multiple spoiled events before wither-washer
+	 * detaches our consumer, so this can get called multiple
+	 * times.
+	 */
+	if (gsp == NULL)
 		return;
 	g_free(gsp->slices);
 	if (gsp->hotspot != NULL)
@@ -128,6 +136,15 @@
 	if ((cp->acr + dr) == 0 && (cp->acw + dw) == 0 && (cp->ace + de) == 1)
 		de--;
 	error = g_access(cp, dr, dw, de);
+
+	/*
+	 * Free the softc if all providers have been closed and this geom
+	 * is being removed.
+	 */
+	if (error == 0 && (gp->flags & G_GEOM_WITHER) != 0 &&
+	    (cp->acr + cp->acw + cp->ace) == 0)
+		g_slice_free(gp);
+
 	return (error);
 }
 
@@ -383,7 +400,7 @@
 			printf("GEOM: Reconfigure %s, start %jd length %jd end %jd\n",
 			    pp->name, (intmax_t)offset, (intmax_t)length,
 			    (intmax_t)(offset + length - 1));
-		pp->mediasize = gsl->length;
+		g_resize_provider(pp, gsl->length);
 		return (0);
 	}
 	sb = sbuf_new_auto();
@@ -393,11 +410,14 @@
 	sbuf_finish(sb);
 	pp = g_new_providerf(gp, "%s", sbuf_data(sb));
 	pp2 = LIST_FIRST(&gp->consumer)->provider;
-	pp->flags = pp2->flags & G_PF_CANDELETE;
 	pp->stripesize = pp2->stripesize;
 	pp->stripeoffset = pp2->stripeoffset + offset;
 	if (pp->stripesize > 0)
 		pp->stripeoffset %= pp->stripesize;
+	if (gsp->nhotspot == 0) {
+		pp->flags |= pp2->flags & G_PF_ACCEPT_UNMAPPED;
+		pp->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
+	}
 	if (0 && bootverbose)
 		printf("GEOM: Configure %s, start %jd length %jd end %jd\n",
 		    pp->name, (intmax_t)offset, (intmax_t)length,
@@ -430,11 +450,21 @@
 {
 	struct g_slicer *gsp;
 	struct g_slice_hot *gsl, *gsl2;
+	struct g_consumer *cp;
+	struct g_provider *pp;
 
 	g_trace(G_T_TOPOLOGY, "g_slice_conf_hot(%s, idx: %d, off: %jd, len: %jd)",
 	    gp->name, idx, (intmax_t)offset, (intmax_t)length);
 	g_topology_assert();
 	gsp = gp->softc;
+	/* Deny unmapped I/O and direct dispatch if hotspots are used. */
+	if (gsp->nhotspot == 0) {
+		LIST_FOREACH(pp, &gp->provider, provider)
+			pp->flags &= ~(G_PF_ACCEPT_UNMAPPED |
+			    G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE);
+		LIST_FOREACH(cp, &gp->consumer, consumer)
+			cp->flags &= ~(G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE);
+	}
 	gsl = gsp->hotspot;
 	if(idx >= gsp->nhotspot) {
 		gsl2 = g_malloc((idx + 1) * sizeof *gsl2, M_WAITOK | M_ZERO);
@@ -458,21 +488,32 @@
 }
 
 void
-g_slice_spoiled(struct g_consumer *cp)
+g_slice_orphan(struct g_consumer *cp)
 {
 	struct g_geom *gp;
-	struct g_slicer *gsp;
 
 	g_topology_assert();
 	gp = cp->geom;
-	g_trace(G_T_TOPOLOGY, "g_slice_spoiled(%p/%s)", cp, gp->name);
-	cp->flags |= G_CF_ORPHAN;
-	gsp = gp->softc;
-	gp->softc = NULL;
-	g_slice_free(gsp);
+	g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, gp->name);
 	g_wither_geom(gp, ENXIO);
+
+	/*
+	 * We can safely free the softc now if there are no accesses,
+	 * otherwise g_slice_access() will do that after the last close.
+	 */
+	if ((cp->acr + cp->acw + cp->ace) == 0)
+		g_slice_free(gp);
 }
 
+void
+g_slice_spoiled(struct g_consumer *cp)
+{
+
+	g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->geom->name);
+	cp->flags |= G_CF_ORPHAN;
+	g_slice_orphan(cp);
+}
+
 int
 g_slice_destroy_geom(struct gctl_req *req, struct g_class *mp, struct g_geom *gp)
 {
@@ -495,10 +536,10 @@
 	gp = g_new_geomf(mp, "%s", pp->name);
 	gsp = g_slice_alloc(slices, extra);
 	gsp->start = start;
+	gp->softc = gsp;
+	gp->start = g_slice_start;
 	gp->access = g_slice_access;
 	gp->orphan = g_slice_orphan;
-	gp->softc = gsp;
-	gp->start = g_slice_start;
 	gp->spoiled = g_slice_spoiled;
 	if (gp->dumpconf == NULL)
 		gp->dumpconf = g_slice_dumpconf;
@@ -505,6 +546,7 @@
 	if (gp->class->destroy_geom == NULL)
 		gp->class->destroy_geom = g_slice_destroy_geom;
 	cp = g_new_consumer(gp);
+	cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
 	error = g_attach(cp, pp);
 	if (error == 0)
 		error = g_access(cp, 1, 0, 0);
@@ -517,15 +559,3 @@
 	*cpp = cp;
 	return (gp);
 }
-
-void
-g_slice_orphan(struct g_consumer *cp)
-{
-
-	g_trace(G_T_TOPOLOGY, "g_slice_orphan(%p/%s)", cp, cp->provider->name);
-	g_topology_assert();
-
-	/* XXX: Not good enough we leak the softc and its suballocations */
-	g_slice_free(cp->geom->softc);
-	g_wither_geom(cp->geom, ENXIO);
-}

Modified: trunk/sys/geom/geom_slice.h
===================================================================
--- trunk/sys/geom/geom_slice.h	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_slice.h	2018-05-27 21:25:45 UTC (rev 10008)
@@ -33,7 +33,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/geom_slice.h,v 1.18 2006/02/18 11:21:17 pjd Exp $
+ * $FreeBSD: stable/10/sys/geom/geom_slice.h 243333 2012-11-20 12:32:18Z jh $
  */
 
 #ifndef _GEOM_GEOM_SLICE_H_

Modified: trunk/sys/geom/geom_subr.c
===================================================================
--- trunk/sys/geom/geom_subr.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_subr.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Poul-Henning Kamp
  * Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -34,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_subr.c,v 1.91.2.6 2009/05/29 19:37:17 lulf Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_subr.c 332096 2018-04-06 12:23:59Z avg $");
 
 #include "opt_ddb.h"
 
@@ -68,9 +69,11 @@
 char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
 
 struct g_hh00 {
-	struct g_class	*mp;
-	int		error;
-	int		post;
+	struct g_class		*mp;
+	struct g_provider	*pp;
+	off_t			size;
+	int			error;
+	int			post;
 };
 
 /*
@@ -269,7 +272,7 @@
 	g_topology_assert();
 	if (flag == EV_CANCEL)  /* XXX: can't happen ? */
 		return;
-	if (g_shutdown)
+	if (g_shutdown || g_notaste)
 		return;
 
 	hh = arg;
@@ -360,6 +363,7 @@
 	gp->access = mp->access;
 	gp->orphan = mp->orphan;
 	gp->ioctl = mp->ioctl;
+	gp->resize = mp->resize;
 	return (gp);
 }
 
@@ -537,6 +541,8 @@
 		    cp->geom->attrchanged != NULL)
 			cp->geom->attrchanged(cp, "GEOM::media");
 	}
+	if (g_notaste)
+		return;
 	LIST_FOREACH(mp, &g_classes, class) {
 		if (mp->taste == NULL)
 			continue;
@@ -597,6 +603,78 @@
 	pp->error = error;
 }
 
+static void
+g_resize_provider_event(void *arg, int flag)
+{
+	struct g_hh00 *hh;
+	struct g_class *mp;
+	struct g_geom *gp;
+	struct g_provider *pp;
+	struct g_consumer *cp, *cp2;
+	off_t size;
+
+	g_topology_assert();
+	if (g_shutdown)
+		return;
+
+	hh = arg;
+	pp = hh->pp;
+	size = hh->size;
+	g_free(hh);
+
+	G_VALID_PROVIDER(pp);
+	g_trace(G_T_TOPOLOGY, "g_resize_provider_event(%p)", pp);
+
+	LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
+		gp = cp->geom;
+		if (gp->resize == NULL && size < pp->mediasize) {
+			cp->flags |= G_CF_ORPHAN;
+			cp->geom->orphan(cp);
+		}
+	}
+
+	pp->mediasize = size;
+	
+	LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
+		gp = cp->geom;
+		if (gp->resize != NULL)
+			gp->resize(cp);
+	}
+
+	/*
+	 * After resizing, the previously invalid GEOM class metadata
+	 * might become valid.  This means we should retaste.
+	 */
+	LIST_FOREACH(mp, &g_classes, class) {
+		if (mp->taste == NULL)
+			continue;
+		LIST_FOREACH(cp, &pp->consumers, consumers)
+			if (cp->geom->class == mp &&
+			    (cp->flags & G_CF_ORPHAN) == 0)
+				break;
+		if (cp != NULL)
+			continue;
+		mp->taste(mp, pp, 0);
+		g_topology_assert();
+	}
+}
+
+void
+g_resize_provider(struct g_provider *pp, off_t size)
+{
+	struct g_hh00 *hh;
+
+	G_VALID_PROVIDER(pp);
+
+	if (size == pp->mediasize)
+		return;
+
+	hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
+	hh->pp = pp;
+	hh->size = size;
+	g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL);
+}
+
 #ifndef	_PATH_DEV
 #define	_PATH_DEV	"/dev/"
 #endif
@@ -606,21 +684,27 @@
 {
 	struct g_class *cp;
 	struct g_geom *gp;
-	struct g_provider *pp;
+	struct g_provider *pp, *wpp;
 
 	if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
 		arg += sizeof(_PATH_DEV) - 1;
 
+	wpp = NULL;
 	LIST_FOREACH(cp, &g_classes, class) {
 		LIST_FOREACH(gp, &cp->geom, geom) {
 			LIST_FOREACH(pp, &gp->provider, provider) {
-				if (!strcmp(arg, pp->name))
+				if (strcmp(arg, pp->name) != 0)
+					continue;
+				if ((gp->flags & G_GEOM_WITHER) == 0 &&
+				    (pp->flags & G_PF_WITHER) == 0)
 					return (pp);
+				else
+					wpp = pp;
 			}
 		}
 	}
 
-	return (NULL);
+	return (wpp);
 }
 
 void
@@ -776,7 +860,11 @@
 g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
 {
 	struct g_provider *pp;
-	int pr,pw,pe;
+	struct g_geom *gp;
+	int pw, pe;
+#ifdef INVARIANTS
+	int sr, sw, se;
+#endif
 	int error;
 
 	g_topology_assert();
@@ -784,6 +872,7 @@
 	pp = cp->provider;
 	KASSERT(pp != NULL, ("access but not attached"));
 	G_VALID_PROVIDER(pp);
+	gp = pp->geom;
 
 	g_trace(G_T_ACCESS, "g_access(%p(%s), %d, %d, %d)",
 	    cp, pp->name, dcr, dcw, dce);
@@ -792,7 +881,7 @@
 	KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
 	KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
 	KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
-	KASSERT(pp->geom->access != NULL, ("NULL geom->access"));
+	KASSERT(gp->access != NULL, ("NULL geom->access"));
 
 	/*
 	 * If our class cares about being spoiled, and we have been, we
@@ -804,10 +893,30 @@
 		return (ENXIO);
 
 	/*
+	 * A number of GEOM classes either need to perform an I/O on the first
+	 * open or to acquire a different subsystem's lock.  To do that they
+	 * may have to drop the topology lock.
+	 * Other GEOM classes perform special actions when opening a lower rank
+	 * geom for the first time.  As a result, more than one thread may
+	 * end up performing the special actions.
+	 * So, we prevent concurrent "first" opens by marking the consumer with
+	 * special flag.
+	 *
+	 * Note that if the geom's access method never drops the topology lock,
+	 * then we will never see G_GEOM_IN_ACCESS here.
+	 */
+	while ((gp->flags & G_GEOM_IN_ACCESS) != 0) {
+		g_trace(G_T_ACCESS,
+		    "%s: race on geom %s via provider %s and consumer of %s",
+		    __func__, gp->name, pp->name, cp->geom->name);
+		gp->flags |= G_GEOM_ACCESS_WAIT;
+		g_topology_sleep(gp, 0);
+	}
+
+	/*
 	 * Figure out what counts the provider would have had, if this
 	 * consumer had (r0w0e0) at this time.
 	 */
-	pr = pp->acr - cp->acr;
 	pw = pp->acw - cp->acw;
 	pe = pp->ace - cp->ace;
 
@@ -819,7 +928,7 @@
 	    pp, pp->name);
 
 	/* If foot-shooting is enabled, any open on rank#1 is OK */
-	if ((g_debugflags & 16) && pp->geom->rank == 1)
+	if ((g_debugflags & 16) && gp->rank == 1)
 		;
 	/* If we try exclusive but already write: fail */
 	else if (dce > 0 && pw > 0)
@@ -833,10 +942,27 @@
 
 	/* Ok then... */
 
-	error = pp->geom->access(pp, dcr, dcw, dce);
+#ifdef INVARIANTS
+	sr = cp->acr;
+	sw = cp->acw;
+	se = cp->ace;
+#endif
+	gp->flags |= G_GEOM_IN_ACCESS;
+	error = gp->access(pp, dcr, dcw, dce);
 	KASSERT(dcr > 0 || dcw > 0 || dce > 0 || error == 0,
-	    ("Geom provider %s::%s failed closing ->access()",
-	    pp->geom->class->name, pp->name));
+	    ("Geom provider %s::%s dcr=%d dcw=%d dce=%d error=%d failed "
+	    "closing ->access()", gp->class->name, pp->name, dcr, dcw,
+	    dce, error));
+
+	g_topology_assert();
+	gp->flags &= ~G_GEOM_IN_ACCESS;
+	KASSERT(cp->acr == sr && cp->acw == sw && cp->ace == se,
+	    ("Access counts changed during geom->access"));
+	if ((gp->flags & G_GEOM_ACCESS_WAIT) != 0) {
+		gp->flags &= ~G_GEOM_ACCESS_WAIT;
+		wakeup(gp);
+	}
+
 	if (!error) {
 		/*
 		 * If we open first write, spoil any partner consumers.
@@ -846,7 +972,7 @@
 		if (pp->acw == 0 && dcw != 0)
 			g_spoil(pp, cp);
 		else if (pp->acw != 0 && pp->acw == -dcw && pp->error == 0 &&
-		    !(pp->geom->flags & G_GEOM_WITHER))
+		    !(gp->flags & G_GEOM_WITHER))
 			g_post_event(g_new_provider_event, pp, M_WAITOK, 
 			    pp, NULL);
 
@@ -874,6 +1000,13 @@
 }
 
 int
+g_handleattr_uint16_t(struct bio *bp, const char *attribute, uint16_t val)
+{
+
+	return (g_handleattr(bp, attribute, &val, sizeof val));
+}
+
+int
 g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val)
 {
 
@@ -986,6 +1119,8 @@
 		return;
 	pp = arg;
 	G_VALID_PROVIDER(pp);
+	g_trace(G_T_TOPOLOGY, "%s %p(%s:%s:%s)", __func__, pp,
+	    pp->geom->class->name, pp->geom->name, pp->name);
 	for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) {
 		cp2 = LIST_NEXT(cp, consumers);
 		if ((cp->flags & G_CF_SPOILED) == 0)
@@ -1183,7 +1318,6 @@
 		strlcpy(str, "NONE", size);
 		return (str);
 	}
-	ADDFLAG(pp, G_PF_CANDELETE, "G_PF_CANDELETE");
 	ADDFLAG(pp, G_PF_WITHER, "G_PF_WITHER");
 	ADDFLAG(pp, G_PF_ORPHAN, "G_PF_ORPHAN");
 	return (str);

Modified: trunk/sys/geom/geom_sunlabel.c
===================================================================
--- trunk/sys/geom/geom_sunlabel.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_sunlabel.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/geom_sunlabel.c,v 1.3 2008/12/03 00:25:46 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Poul-Henning Kamp
  * Copyright (c) 2002 Networks Associates Technology, Inc.
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_sunlabel.c,v 1.46 2005/11/30 22:15:00 sobomax Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_sunlabel.c 223921 2011-07-11 05:22:31Z ae $");
 
 #include <sys/param.h>
 #include <sys/endian.h>

Modified: trunk/sys/geom/geom_sunlabel_enc.c
===================================================================
--- trunk/sys/geom/geom_sunlabel_enc.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_sunlabel_enc.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_sunlabel_enc.c,v 1.6 2005/03/30 09:33:09 joerg Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_sunlabel_enc.c 144328 2005-03-30 09:33:10Z joerg $");
 
 #include <sys/types.h>
 #include <sys/endian.h>

Modified: trunk/sys/geom/geom_vfs.c
===================================================================
--- trunk/sys/geom/geom_vfs.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_vfs.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_vfs.c,v 1.11.2.4 2011/02/24 10:45:41 brucec Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_vfs.c 260385 2014-01-07 01:32:23Z scottl $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -36,7 +36,7 @@
 #include <sys/malloc.h>
 #include <sys/mutex.h>
 #include <sys/vnode.h>
-#include <sys/mount.h>	/* XXX Temporary for VFS_LOCK_GIANT */
+#include <sys/mount.h>
 
 #include <geom/geom.h>
 #include <geom/geom_vfs.h>
@@ -95,24 +95,18 @@
 	struct g_consumer *cp;
 	struct g_vfs_softc *sc;
 	struct buf *bp;
-	int vfslocked, destroy;
+	int destroy;
 	struct mount *mp;
 	struct vnode *vp;
 	struct cdev *cdevp;
 
-	cp = bip->bio_from;
-	sc = cp->geom->softc;
 	/*
 	 * Collect statistics on synchronous and asynchronous read
 	 * and write counts for disks that have associated filesystems.
-	 * Since this is run by the g_up thread it is single threaded and
-	 * we do not need to use atomic increments on the counters.
 	 */
 	bp = bip->bio_caller2;
 	vp = bp->b_vp;
-	if (vp == NULL) {
-		mp = NULL;
-	} else {
+	if (vp != NULL) {
 		/*
 		 * If not a disk vnode, use its associated mount point
 		 * otherwise use the mountpoint associated with the disk.
@@ -125,22 +119,24 @@
 			mp = vp->v_mount;
 		else
 			mp = cdevp->si_mountpt;
+		if (mp != NULL) {
+			if (bp->b_iocmd == BIO_READ) {
+				if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
+					mp->mnt_stat.f_asyncreads++;
+				else
+					mp->mnt_stat.f_syncreads++;
+			} else if (bp->b_iocmd == BIO_WRITE) {
+				if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
+					mp->mnt_stat.f_asyncwrites++;
+				else
+					mp->mnt_stat.f_syncwrites++;
+			}
+		}
 		VI_UNLOCK(vp);
 	}
-	if (mp != NULL) {
-		if (bp->b_iocmd == BIO_WRITE) {
-			if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
-				mp->mnt_stat.f_asyncwrites++;
-			else
-				mp->mnt_stat.f_syncwrites++;
-		} else {
-			if (LK_HOLDER(bp->b_lock.lk_lock) == LK_KERNPROC)
-				mp->mnt_stat.f_asyncreads++;
-			else
-				mp->mnt_stat.f_syncreads++;
-		}
-	}
 
+	cp = bip->bio_from;
+	sc = cp->geom->softc;
 	if (bip->bio_error) {
 		printf("g_vfs_done():");
 		g_print_bio(bip);
@@ -159,9 +155,7 @@
 	if (destroy)
 		g_post_event(g_vfs_destroy, cp, M_WAITOK, NULL);
 
-	vfslocked = VFS_LOCK_GIANT(((struct mount *)NULL));
 	bufdone(bp);
-	VFS_UNLOCK_GIANT(vfslocked);
 }
 
 void
@@ -170,7 +164,6 @@
 	struct g_vfs_softc *sc;
 	struct g_consumer *cp;
 	struct bio *bip;
-	int vfslocked;
 
 	cp = bo->bo_private;
 	sc = cp->geom->softc;
@@ -183,9 +176,7 @@
 		mtx_unlock(&sc->sc_mtx);
 		bp->b_error = ENXIO;
 		bp->b_ioflags |= BIO_ERROR;
-		vfslocked = VFS_LOCK_GIANT(((struct mount *)NULL));
 		bufdone(bp);
-		VFS_UNLOCK_GIANT(vfslocked);
 		return;
 	}
 	sc->sc_active++;
@@ -194,10 +185,14 @@
 	bip = g_alloc_bio();
 	bip->bio_cmd = bp->b_iocmd;
 	bip->bio_offset = bp->b_iooffset;
-	bip->bio_data = bp->b_data;
+	bip->bio_length = bp->b_bcount;
+	bdata2bio(bp, bip);
+	if ((bp->b_flags & B_BARRIER) != 0) {
+		bip->bio_flags |= BIO_ORDERED;
+		bp->b_flags &= ~B_BARRIER;
+	}
 	bip->bio_done = g_vfs_done;
 	bip->bio_caller2 = bp;
-	bip->bio_length = bp->b_bcount;
 	g_io_request(bip, cp);
 }
 
@@ -235,7 +230,6 @@
 	struct g_consumer *cp;
 	struct g_vfs_softc *sc;
 	struct bufobj *bo;
-	int vfslocked;
 	int error;
 
 	g_topology_assert();
@@ -260,11 +254,10 @@
 		g_wither_geom(gp, ENXIO);
 		return (error);
 	}
-	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 	vnode_create_vobject(vp, pp->mediasize, curthread);
-	VFS_UNLOCK_GIANT(vfslocked);
 	*cpp = cp;
 	cp->private = vp;
+	cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
 	bo->bo_ops = g_vfs_bufops;
 	bo->bo_private = cp;
 	bo->bo_bsize = pp->sectorsize;

Modified: trunk/sys/geom/geom_vfs.h
===================================================================
--- trunk/sys/geom/geom_vfs.h	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_vfs.h	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/geom_vfs.h,v 1.2 2008/12/03 00:25:46 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2004 Poul-Henning Kamp
  * All rights reserved.
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/geom_vfs.h,v 1.3 2005/02/10 12:10:35 phk Exp $
+ * $FreeBSD: stable/10/sys/geom/geom_vfs.h 183754 2008-10-10 21:23:50Z attilio $
  */
 
 #ifndef _GEOM_GEOM_VFS_H_

Modified: trunk/sys/geom/geom_vol_ffs.c
===================================================================
--- trunk/sys/geom/geom_vol_ffs.c	2018-05-27 21:22:55 UTC (rev 10007)
+++ trunk/sys/geom/geom_vol_ffs.c	2018-05-27 21:25:45 UTC (rev 10008)
@@ -1,4 +1,4 @@
-/* $MidnightBSD: src/sys/geom/geom_vol_ffs.c,v 1.3 2008/12/03 00:25:46 laffer1 Exp $ */
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002, 2003 Gordon Tetlow
  * All rights reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/geom_vol_ffs.c,v 1.16 2005/11/30 22:15:00 sobomax Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/geom_vol_ffs.c 219029 2011-02-25 10:24:35Z netchild $");
 
 #include <sys/param.h>
 #include <sys/errno.h>



More information about the Midnightbsd-cvs mailing list