Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 2 May 2003 17:48:25 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 30427 for review
Message-ID:  <200305030048.h430mPtd064622@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=30427

Change 30427 by peter@peter_daintree on 2003/05/02 17:47:58

	IFC @30425

Affected files ...

.. //depot/projects/hammer/etc/Makefile#11 integrate
.. //depot/projects/hammer/sbin/bsdlabel/bsdlabel.c#3 integrate
.. //depot/projects/hammer/sys/amd64/amd64/cpu_switch.S#1 branch
.. //depot/projects/hammer/sys/amd64/amd64/exception.S#1 branch
.. //depot/projects/hammer/sys/amd64/amd64/exception.s#6 delete
.. //depot/projects/hammer/sys/amd64/amd64/locore.S#1 branch
.. //depot/projects/hammer/sys/amd64/amd64/locore.s#6 delete
.. //depot/projects/hammer/sys/amd64/amd64/sigtramp.S#1 branch
.. //depot/projects/hammer/sys/amd64/amd64/sigtramp.s#6 delete
.. //depot/projects/hammer/sys/amd64/amd64/support.S#1 branch
.. //depot/projects/hammer/sys/amd64/amd64/support.s#6 delete
.. //depot/projects/hammer/sys/amd64/amd64/swtch.s#6 delete
.. //depot/projects/hammer/sys/amd64/isa/icu_ipl.S#1 branch
.. //depot/projects/hammer/sys/amd64/isa/icu_ipl.s#6 delete
.. //depot/projects/hammer/sys/amd64/isa/icu_vector.S#1 branch
.. //depot/projects/hammer/sys/amd64/isa/icu_vector.s#6 delete
.. //depot/projects/hammer/sys/amd64/isa/vector.S#1 branch
.. //depot/projects/hammer/sys/amd64/isa/vector.s#6 delete
.. //depot/projects/hammer/sys/cam/scsi/scsi_da.c#13 integrate
.. //depot/projects/hammer/sys/conf/files.amd64#7 integrate
.. //depot/projects/hammer/sys/geom/geom_bsd.c#14 integrate
.. //depot/projects/hammer/sys/geom/geom_bsd_enc.c#3 integrate
.. //depot/projects/hammer/sys/sys/disklabel.h#10 integrate
.. //depot/projects/hammer/usr.bin/xlint/arch/amd64/targparam.h#2 integrate

Differences ...

==== //depot/projects/hammer/etc/Makefile#11 (text+ko) ====

@@ -1,5 +1,5 @@
 #	from: @(#)Makefile	5.11 (Berkeley) 5/21/91
-# $FreeBSD: src/etc/Makefile,v 1.311 2003/05/02 05:27:33 dougb Exp $
+# $FreeBSD: src/etc/Makefile,v 1.312 2003/05/02 22:27:31 dougb Exp $
 
 .if !defined(NO_SENDMAIL)
 SUBDIR=	sendmail
@@ -12,7 +12,7 @@
 	inetd.conf login.access login.conf \
 	mac.conf motd netconfig network.subr networks newsyslog.conf \
 	phones printcap profile protocols \
-	rc rc.firewall rc.firewall6 rc.shutdown \
+	rc rc.firewall rc.firewall6 rc.sendmail rc.shutdown \
 	rc.subr remote rpc services \
 	shells sysctl.conf syslog.conf usbd.conf \
 	etc.${MACHINE_ARCH}/ttys \

==== //depot/projects/hammer/sbin/bsdlabel/bsdlabel.c#3 (text+ko) ====

@@ -54,7 +54,7 @@
 #endif /* not lint */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sbin/bsdlabel/bsdlabel.c,v 1.85 2003/05/02 20:14:48 phk Exp $");
+__FBSDID("$FreeBSD: src/sbin/bsdlabel/bsdlabel.c,v 1.86 2003/05/02 22:46:44 phk Exp $");
 
 #include <sys/param.h>
 #include <stdint.h>
@@ -413,7 +413,8 @@
 	(void)lseek(f, (off_t)0, SEEK_SET);
 	if (read(f, bootarea, BBSIZE) < BBSIZE)
 		err(4, "%s", specname);
-	bsd_disklabel_le_dec((u_char *)bootarea + labeloffset, &lab);
+	bsd_disklabel_le_dec((u_char *)bootarea + labeloffset, &lab,
+	    MAXPARTITIONS);
 	return (&lab);
 }
 

==== //depot/projects/hammer/sys/cam/scsi/scsi_da.c#13 (text+ko) ====

@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.141 2003/05/01 05:16:13 ken Exp $
+ * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.142 2003/05/03 00:21:40 ken Exp $
  */
 
 #ifdef _KERNEL
@@ -1548,8 +1548,8 @@
 					softc->state = DA_STATE_PROBE2;
 					free(rdcap, M_TEMP);
 					xpt_release_ccb(done_ccb);
-					cam_periph_unlock(periph);
-					break;
+					xpt_schedule(periph, /*priority*/5);
+					return;
 				}
 			} else {
 				block_size = scsi_4btoul(rcaplong->length);

==== //depot/projects/hammer/sys/conf/files.amd64#7 (text+ko) ====

@@ -1,7 +1,7 @@
 # This file tells config what files go into building a kernel,
 # files marked standard are always included.
 #
-# $FreeBSD: src/sys/conf/files.amd64,v 1.11 2003/05/01 02:59:24 peter Exp $
+# $FreeBSD: src/sys/conf/files.amd64,v 1.12 2003/05/03 00:19:42 peter Exp $
 #
 # The long compile-with and dependency lines are required because of
 # limitations in config: backslash-newline doesn't work in strings, and
@@ -33,21 +33,21 @@
 
 amd64/amd64/autoconf.c		standard
 amd64/amd64/busdma_machdep.c	standard
+amd64/amd64/cpu_swtch.S		standard
 amd64/amd64/critical.c		standard
 amd64/amd64/dump_machdep.c	standard
 amd64/amd64/elf_machdep.c	standard
-amd64/amd64/exception.s		standard
+amd64/amd64/exception.S		standard
 amd64/amd64/identcpu.c		standard
 amd64/amd64/initcpu.c		standard
 amd64/amd64/legacy.c		standard
-amd64/amd64/locore.s		standard	no-obj
+amd64/amd64/locore.S		standard	no-obj
 amd64/amd64/machdep.c		standard
 amd64/amd64/mem.c		standard
 amd64/amd64/nexus.c		standard
 amd64/amd64/pmap.c		standard
-amd64/amd64/sigtramp.s		standard
-amd64/amd64/support.s		standard
-amd64/amd64/swtch.s		standard
+amd64/amd64/sigtramp.S		standard
+amd64/amd64/support.S		standard
 amd64/amd64/sys_machdep.c	standard
 amd64/amd64/trap.c		standard
 amd64/amd64/tsc.c		standard

==== //depot/projects/hammer/sys/geom/geom_bsd.c#14 (text+ko) ====

@@ -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_bsd.c,v 1.52 2003/05/02 06:33:59 phk Exp $
+ * $FreeBSD: src/sys/geom/geom_bsd.c,v 1.53 2003/05/02 22:46:13 phk Exp $
  *
  * This is the method for dealing with BSD disklabels.  It has been
  * extensively (by my standards at least) commented, in the vain hope that
@@ -58,6 +58,8 @@
 
 #define ALPHA_LABEL_OFFSET	64
 
+#define LABELSIZE (148 + 16 * MAXPARTITIONS)
+
 static void g_bsd_hotwrite(void *arg, int flag);
 /*
  * Our private data about one instance.  All the rest is handled by the
@@ -69,123 +71,16 @@
 	off_t	mbroffset;
 	off_t	rawoffset;
 	struct disklabel ondisk;
-	struct disklabel inram;
+	u_char	label[LABELSIZE];
 	u_char	labelsum[16];
 };
 
-static int
-g_bsd_ondisk_size(void)
-{
-	return (148 + 16 * MAXPARTITIONS);
-}
-
-/*
- * For reasons which were valid and just in their days, FreeBSD/i386 uses
- * absolute disk-addresses in disklabels.  The way it works is that the
- * p_offset field of all partitions have the first sector number of the
- * disk slice added to them.  This was hidden kernel-magic, userland did
- * not see these offsets.  These two functions subtract and add them
- * while converting from the "ondisk" to the "inram" labels and vice
- * versa.
- */
-static void
-ondisk2inram(struct g_bsd_softc *sc)
-{
-	struct partition *ppp;
-	struct disklabel *dl;
-	int i;
-
-	sc->inram = sc->ondisk;
-	dl = &sc->inram;
-
-	/* Basic sanity-check needed to avoid mistakes. */
-	if (dl->d_magic != DISKMAGIC || dl->d_magic2 != DISKMAGIC)
-		return;
-	if (dl->d_npartitions > MAXPARTITIONS)
-		return;
-
-	sc->rawoffset = dl->d_partitions[RAW_PART].p_offset;
-	for (i = 0; i < dl->d_npartitions; i++) {
-		ppp = &dl->d_partitions[i];
-		if (ppp->p_size != 0 && ppp->p_offset < sc->rawoffset)
-			sc->rawoffset = 0;
-	}
-	if (sc->rawoffset > 0) {
-		for (i = 0; i < dl->d_npartitions; i++) {
-			ppp = &dl->d_partitions[i];
-			if (ppp->p_offset != 0)
-				ppp->p_offset -= sc->rawoffset;
-		}
-	}
-	dl->d_checksum = 0;
-	dl->d_checksum = dkcksum(&sc->inram);
-}
-
-static void
-inram2ondisk(struct g_bsd_softc *sc)
-{
-	struct partition *ppp;
-	int i;
-
-	sc->ondisk = sc->inram;
-	if (sc->mbroffset != 0)
-		sc->rawoffset = sc->mbroffset / sc->inram.d_secsize; 
-	if (sc->rawoffset != 0) {
-		for (i = 0; i < sc->inram.d_npartitions; i++) {
-			ppp = &sc->ondisk.d_partitions[i];
-			if (ppp->p_size > 0) 
-				ppp->p_offset += sc->rawoffset;
-			else
-				ppp->p_offset = 0;
-		}
-	}
-	sc->ondisk.d_checksum = 0;
-	sc->ondisk.d_checksum = dkcksum(&sc->ondisk);
-}
-
-/*
- * Check that this looks like a valid disklabel, but be prepared
- * to get any kind of junk.  The checksum must be checked only
- * after this function returns success to prevent a bogus d_npartitions
- * value from tripping us up.
- */
-static int
-g_bsd_checklabel(struct disklabel *dl)
-{
-	struct partition *ppp;
-	int i;
-
-	if (dl->d_magic != DISKMAGIC || dl->d_magic2 != DISKMAGIC)
-		return (EINVAL);
-	/*
-	 * If the label specifies more partitions than we can handle
-	 * we have to reject it:  If people updated the label they would
-	 * trash it, and that would break the checksum.
-	 */
-	if (dl->d_npartitions > MAXPARTITIONS)
-		return (EINVAL);
-
-	for (i = 0; i < dl->d_npartitions; i++) {
-		ppp = &dl->d_partitions[i];
-		/* Cannot extend past unit. */
-		if (ppp->p_size != 0 &&
-		     ppp->p_offset + ppp->p_size > dl->d_secperunit) {
-			return (EINVAL);
-		}
-	}
-	return (0);
-}
-
 /*
  * Modify our slicer to match proposed disklabel, if possible.
- * First carry out all the simple checks, then lock topology
- * and check that no open providers are affected negatively
- * then carry out all the changes.
- *
- * NB: Returns with topology held only if successful return.
+ * This is where we make sure we don't do something stupid.
  */
 static int
-g_bsd_modify(struct g_geom *gp, struct disklabel *dl)
+g_bsd_modify(struct g_geom *gp, u_char *label)
 {
 	int i, error;
 	struct partition *ppp;
@@ -193,33 +88,25 @@
 	struct g_consumer *cp;
 	struct g_bsd_softc *ms;
 	u_int secsize, u;
-	off_t mediasize;
+	off_t mediasize, rawoffset, o;
+	struct disklabel dl;
+	MD5_CTX md5sum;
+
+	g_topology_assert();
+	gsp = gp->softc;
+	ms = gsp->softc;
 
-	/* Basic check that this is indeed a disklabel. */
-	error = g_bsd_checklabel(dl);
-	if (error)
+	error = bsd_disklabel_le_dec(label, &dl, MAXPARTITIONS);
+	if (error) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
 		return (error);
+	}
 
-	/* Make sure the checksum is OK. */
-	if (dkcksum(dl) != 0)
-		return (EINVAL);
-
 	/* Get dimensions of our device. */
 	cp = LIST_FIRST(&gp->consumer);
 	secsize = cp->provider->sectorsize;
 	mediasize = cp->provider->mediasize;
 
-#ifdef nolonger
-	/*
-	 * The raw-partition must start at zero.  We do not check that the
-	 * size == mediasize because this is overly restrictive.  We have
-	 * already tested in g_bsd_checklabel() that it is not longer.
-	 * XXX: RAW_PART is archaic anyway, and we should drop it.
-	 */
-	if (dl->d_partitions[RAW_PART].p_offset != 0)
-		return (EINVAL);
-#endif
-
 #ifdef notyet
 	/*
 	 * Indications are that the d_secperunit is not correctly
@@ -229,71 +116,80 @@
 	 * may be in order.
 	 */
 	/* The label cannot claim a larger size than the media. */
-	if ((off_t)dl->d_secperunit * dl->d_secsize > mediasize)
+	if ((off_t)dl.d_secperunit * dl.d_secsize > mediasize)
 		return (EINVAL);
 #endif
 
-
 	/* ... or a smaller sector size. */
-	if (dl->d_secsize < secsize)
+	if (dl.d_secsize < secsize) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
 		return (EINVAL);
+	}
 
 	/* ... or a non-multiple sector size. */
-	if (dl->d_secsize % secsize != 0)
+	if (dl.d_secsize % secsize != 0) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
 		return (EINVAL);
+	}
+
+	/* Historical braindamage... */
+	rawoffset = (off_t)dl.d_partitions[RAW_PART].p_offset * dl.d_secsize;
+	for (i = 0; i < dl.d_npartitions; i++) {
+		ppp = &dl.d_partitions[i];
+		if (ppp->p_size == 0)
+			continue;
+	        o = (off_t)ppp->p_offset * dl.d_secsize;
 
-	g_topology_lock();
+		if (o < rawoffset)
+			rawoffset = 0;
+	}
 
 	/* Don't munge open partitions. */
-	gsp = gp->softc;
-	ms = gsp->softc;
-	for (i = 0; i < dl->d_npartitions; i++) {
-		ppp = &dl->d_partitions[i];
+	for (i = 0; i < dl.d_npartitions; i++) {
+		ppp = &dl.d_partitions[i];
 
+	        o = (off_t)ppp->p_offset * dl.d_secsize;
+		if (o == 0)
+			o = rawoffset;
 		error = g_slice_config(gp, i, G_SLICE_CONFIG_CHECK,
-		    (off_t)ppp->p_offset * dl->d_secsize,
-		    (off_t)ppp->p_size * dl->d_secsize,
-		     dl->d_secsize,
+		    o - rawoffset,
+		    (off_t)ppp->p_size * dl.d_secsize,
+		     dl.d_secsize,
 		    "%s%c", gp->name, 'a' + i);
-		if (error) {
-			g_topology_unlock();
+		if (error)
 			return (error);
-		}
 	}
 
 	/* Look good, go for it... */
 	for (u = 0; u < gsp->nslice; u++) {
-		ppp = &dl->d_partitions[u];
+		ppp = &dl.d_partitions[u];
+	        o = (off_t)ppp->p_offset * dl.d_secsize;
+		if (o == 0)
+			o = rawoffset;
 		g_slice_config(gp, u, G_SLICE_CONFIG_SET,
-		    (off_t)ppp->p_offset * dl->d_secsize,
-		    (off_t)ppp->p_size * dl->d_secsize,
-		     dl->d_secsize,
+		    o - rawoffset,
+		    (off_t)ppp->p_size * dl.d_secsize,
+		     dl.d_secsize,
 		    "%s%c", gp->name, 'a' + u);
 	}
-	g_slice_conf_hot(gp, 0, ms->labeloffset, g_bsd_ondisk_size(),
-	    G_SLICE_HOT_ALLOW, G_SLICE_HOT_DENY, G_SLICE_HOT_CALL);
-	gsp->hot = g_bsd_hotwrite;
-	return (0);
-}
+
+	/* Update our softc */
+	ms->ondisk = dl;
+	if (label != ms->label)
+		bcopy(label, ms->label, LABELSIZE);
+	ms->rawoffset = rawoffset;
 
-/*
- * Calculate a disklabel checksum for a little-endian byte-stream.
- * We need access to the decoded disklabel because the checksum only
- * covers the partition data for the first d_npartitions.
- */
-static int
-g_bsd_lesum(struct disklabel *dl, u_char *p)
-{
-	u_char *pe;
-	uint16_t sum;
+	/*
+	 * In order to avoid recursively attaching to the same
+	 * on-disk label (it's usually visible through the 'c'
+	 * partition) we calculate an MD5 and ask if other BSD's
+	 * below us love that label.  If they do, we don't.
+	 */
+	MD5Init(&md5sum);
+	MD5Update(&md5sum, ms->label, sizeof(ms->label));
+	MD5Final(ms->labelsum, &md5sum);
 
-	pe = p + 148 + 16 * dl->d_npartitions;
-	sum = 0;
-	while (p < pe) {
-		sum ^= le16dec(p);
-		p += 2;
-	}
-	return (sum);
+	return (0);
 }
 
 /*
@@ -323,18 +219,10 @@
 
 	/* Decode into our native format. */
 	dl = &ms->ondisk;
-	bsd_disklabel_le_dec(buf + secoff, dl);
+	error = bsd_disklabel_le_dec(buf + secoff, dl, MAXPARTITIONS);
+	if (!error)
+		bcopy(buf + secoff, ms->label, LABELSIZE);
 
-	ondisk2inram(ms);
-
-	dl = &ms->inram;
-	/* Does it look like a label at all? */
-	if (g_bsd_checklabel(dl))
-		error = ENOENT;
-	/* ... and does the raw data have a good checksum? */
-	if (error == 0 && g_bsd_lesum(dl, buf + secoff) != 0)
-		error = ENOENT;
-
 	/* Remember to free the buffer g_read_data() gave us. */
 	g_free(buf);
 
@@ -357,47 +245,41 @@
 	struct g_geom *gp;
 	struct g_slicer *gsp;
 	struct g_bsd_softc *ms;
-	struct disklabel *dl;
 	struct g_ioctl *gio;
 	struct g_consumer *cp;
-	u_char *buf;
+	u_char *buf, *label;
 	off_t secoff;
 	u_int secsize;
 	int error, i;
 	uint64_t sum;
 
+	g_topology_assert();
 	bp = arg;
 	if (flag == EV_CANCEL) {
 		g_io_deliver(bp, ENXIO);
 		return;
 	}
-	/* We don't need topology for now. */
-	g_topology_unlock();
 
 	gp = bp->bio_to->geom;
 	gsp = gp->softc;
 	ms = gsp->softc;
 	gio = (struct g_ioctl *)bp->bio_data;
 
+	label = g_malloc(LABELSIZE, M_WAITOK);
+
 	/* The disklabel to set is the ioctl argument. */
-	dl = gio->data;
+	bsd_disklabel_le_enc(label, gio->data);
 
 	/* Validate and modify our slice instance to match. */
-	error = g_bsd_modify(gp, dl);	/* Picks up topology lock on success. */
-	if (error) {
-		g_topology_lock();
+	error = g_bsd_modify(gp, label);	/* Picks up topology lock on success. */
+	g_free(label);
+	if (error || gio->cmd == DIOCSDINFO) {
 		g_io_deliver(bp, error);
 		return;
 	}
-	/* Update our copy of the disklabel. */
-	ms->inram = *dl;
-	inram2ondisk(ms);
+	
+	KASSERT(gio->cmd == DIOCWDINFO, ("Unknown ioctl in g_bsd_ioctl"));
 
-	if (gio->cmd == DIOCSDINFO) {
-		g_io_deliver(bp, 0);
-		return;
-	}
-	KASSERT(gio->cmd == DIOCWDINFO, ("Unknown ioctl in g_bsd_ioctl"));
 	cp = LIST_FIRST(&gp->consumer);
 	/* Get sector size, we need it to read data. */
 	secsize = cp->provider->sectorsize;
@@ -407,8 +289,7 @@
 		g_io_deliver(bp, error);
 		return;
 	}
-	dl = &ms->ondisk;
-	bsd_disklabel_le_enc(buf + secoff, dl);
+	bcopy(ms->label, buf + secoff, sizeof(ms->label));
 	if (ms->labeloffset == ALPHA_LABEL_OFFSET) {
 		sum = 0;
 		for (i = 0; i < 63; i++)
@@ -430,7 +311,6 @@
 	struct g_geom *gp;
 	struct g_slicer *gsp;
 	struct g_bsd_softc *ms;
-	struct disklabel *dl;
 	struct g_consumer *cp;
 	u_char *buf;
 	void *p;
@@ -447,33 +327,26 @@
 	buf = g_malloc(BBSIZE, M_WAITOK);
 	p = *(void **)data;
 	error = copyin(p, buf, BBSIZE);
-	if (error) {
-		g_free(buf);
-		return (error);
-	}
-	/* The disklabel to set is the ioctl argument. */
-	dl = (void *)(buf + ms->labeloffset);
-
-	DROP_GIANT();
-
-	/* Validate and modify our slice instance to match. */
-	error = g_bsd_modify(gp, dl);	/* Picks up topology lock on success. */
 	if (!error) {
-		cp = LIST_FIRST(&gp->consumer);
-		secsize = cp->provider->sectorsize;
-		dl = &ms->ondisk;
-		bsd_disklabel_le_enc(buf + ms->labeloffset, dl);
-		if (ms->labeloffset == ALPHA_LABEL_OFFSET) {
-			sum = 0;
-			for (i = 0; i < 63; i++)
-				sum += le64dec(buf + i * 8);
-			le64enc(buf + 504, sum);
+		DROP_GIANT();
+		g_topology_lock();
+		/* Validate and modify our slice instance to match. */
+		error = g_bsd_modify(gp, buf + ms->labeloffset);
+		if (!error) {
+			cp = LIST_FIRST(&gp->consumer);
+			secsize = cp->provider->sectorsize;
+			if (ms->labeloffset == ALPHA_LABEL_OFFSET) {
+				sum = 0;
+				for (i = 0; i < 63; i++)
+					sum += le64dec(buf + i * 8);
+				le64enc(buf + 504, sum);
+			}
+			error = g_write_data(cp, 0, buf, BBSIZE);
 		}
-		error = g_write_data(cp, 0, buf, BBSIZE);
 		g_topology_unlock();
+		PICKUP_GIANT();
 	}
 	g_free(buf);
-	PICKUP_GIANT();
 	return (error);
 }
 
@@ -490,10 +363,10 @@
 	struct g_slicer *gsp;
 	struct g_slice *gsl;
 	struct g_bsd_softc *ms;
-	struct g_bsd_softc fake;
 	u_char *p;
 	int error;
 	
+	g_topology_assert();
 	/*
 	 * We should never get canceled, because that would amount to a removal
 	 * of the geom while there was outstanding I/O requests.
@@ -506,28 +379,11 @@
 	gsl = &gsp->slices[bp->bio_to->index];
 	p = (u_char*)bp->bio_data + ms->labeloffset 
 	    - (bp->bio_offset + gsl->offset);
-	bsd_disklabel_le_dec(p, &fake.ondisk);
-	
-	ondisk2inram(&fake);
-	if (g_bsd_checklabel(&fake.inram)) {
-		g_io_deliver(bp, EPERM);
-		return;
-	}
-	if (g_bsd_lesum(&fake.ondisk, p) != 0) {
-		g_io_deliver(bp, EPERM);
-		return;
-	}
-	g_topology_unlock();
-	error = g_bsd_modify(gp, &fake.inram);	/* May pick up topology. */
+	error = g_bsd_modify(gp, p);
 	if (error) {
 		g_io_deliver(bp, EPERM);
-		g_topology_lock();
 		return;
 	}
-	/* Update our copy of the disklabel. */
-	ms->inram = fake.inram;
-	inram2ondisk(ms);
-	bsd_disklabel_le_enc(p, &ms->ondisk);
 	g_slice_finish_hot(bp);
 }
 
@@ -577,7 +433,7 @@
 	switch (gio->cmd) {
 	case DIOCGDINFO:
 		/* Return a copy of the disklabel to userland. */
-		bcopy(&ms->inram, gio->data, sizeof(ms->inram));
+		bsd_disklabel_le_dec(ms->label, gio->data, MAXPARTITIONS);
 		g_io_deliver(bp, 0);
 		return (1);
 	case DIOCBSDBB:
@@ -629,10 +485,10 @@
 	} else if (pp != NULL) {
 		if (indent == NULL)
 			sbuf_printf(sb, " ty %d",
-			    ms->inram.d_partitions[pp->index].p_fstype);
+			    ms->ondisk.d_partitions[pp->index].p_fstype);
 		else
 			sbuf_printf(sb, "%s<type>%d</type>\n", indent,
-			    ms->inram.d_partitions[pp->index].p_fstype);
+			    ms->ondisk.d_partitions[pp->index].p_fstype);
 	}
 }
 
@@ -663,11 +519,10 @@
 	struct g_consumer *cp;
 	int error, i;
 	struct g_bsd_softc *ms;
-	struct disklabel *dl;
 	u_int secsize;
 	struct g_slicer *gsp;
+	u_char hash[16];
 	MD5_CTX md5sum;
-	u_char hash[16];
 
 	g_trace(G_T_TOPOLOGY, "bsd_taste(%s,%s)", mp->name, pp->name);
 	g_topology_assert();
@@ -691,13 +546,6 @@
 		return (NULL);
 
 	/*
-	 * Now that we have attached to and opened our provider, we do
-	 * not need the topology lock until we change the topology again
-	 * next time.
-	 */
-	g_topology_unlock();
-
-	/*
 	 * Fill in the optional details, in our case we have a dumpconf
 	 * routine which the "slice" code should call at the right time
 	 */
@@ -759,10 +607,8 @@
 		 * partition) we calculate an MD5 and ask if other BSD's
 		 * below us love that label.  If they do, we don't.
 		 */
-
-		dl = &ms->inram;
 		MD5Init(&md5sum);
-		MD5Update(&md5sum, (u_char *)dl, sizeof(dl));
+		MD5Update(&md5sum, ms->label, sizeof(ms->label));
 		MD5Final(ms->labelsum, &md5sum);
 
 		error = g_getattr("BSD::labelsum", cp, &hash);
@@ -773,19 +619,19 @@
 		 * Process the found disklabel, and modify our "slice"
 		 * instance to match it, if possible.
 		 */
-		error = g_bsd_modify(gp, dl);	/* Picks up topology lock. */
-		if (!error)
-			g_topology_unlock();
-		break;
+		error = g_bsd_modify(gp, ms->label);
 	} while (0);
 
 	/* Success or failure, we can close our provider now. */
-	g_topology_lock();
 	error = g_access_rel(cp, -1, 0, 0);
 
 	/* If we have configured any providers, return the new geom. */
-	if (gsp->nprovider > 0)
+	if (gsp->nprovider > 0) {
+		g_slice_conf_hot(gp, 0, ms->labeloffset, LABELSIZE,
+		    G_SLICE_HOT_ALLOW, G_SLICE_HOT_DENY, G_SLICE_HOT_CALL);
+		gsp->hot = g_bsd_hotwrite;
 		return (gp);
+	}
 	/*
 	 * ...else push the "self-destruct" button, by spoiling our own
 	 * consumer.  This triggers a call to g_slice_spoiled which will

==== //depot/projects/hammer/sys/geom/geom_bsd_enc.c#3 (text+ko) ====

@@ -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_bsd_enc.c,v 1.2 2003/05/02 19:53:55 phk Exp $
+ * $FreeBSD: src/sys/geom/geom_bsd_enc.c,v 1.3 2003/05/02 22:46:13 phk Exp $
  *
  * Functions to encode and decode struct disklabel and struct partition into
  * a bytestream of little endianess and correct packing.
@@ -44,10 +44,12 @@
 #include <sys/types.h>
 #include <sys/endian.h>
 #include <sys/disklabel.h>
+#include <sys/errno.h>
 #ifdef _KERNEL
 #include <sys/systm.h>
 #else
 #include <string.h>
+#include <stdio.h>
 #endif
 
 void
@@ -61,12 +63,38 @@
 	d->p_cpg = le16dec(ptr + 14);
 }
 
-void
-bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d)
+int
+bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart)
 {
 	int i;
+	u_char *p, *pe;
+	uint16_t sum;
 
 	d->d_magic = le32dec(ptr + 0);
+	if (d->d_magic != DISKMAGIC)
+		return(EINVAL);
+
+	d->d_magic2 = le32dec(ptr + 132);
+	if (d->d_magic2 != DISKMAGIC) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+		return(EINVAL);
+	}
+
+	d->d_npartitions = le16dec(ptr + 138);
+	if (d->d_npartitions > maxpart) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+		return(EINVAL);
+	}
+
+	pe = ptr + 148 + 16 * d->d_npartitions;
+	sum = 0;
+	for (p = ptr; p < pe; p += 2)
+		sum ^= le16dec(p);
+	if (sum != 0) {
+printf("HERE %s %d\n", __FILE__, __LINE__);
+		return(EINVAL);
+	}
+
 	d->d_type = le16dec(ptr + 4);
 	d->d_subtype = le16dec(ptr + 6);
 	bcopy(ptr + 8, d->d_typename, 16);
@@ -97,13 +125,13 @@
 	d->d_spare[2] = le32dec(ptr + 120);
 	d->d_spare[3] = le32dec(ptr + 124);
 	d->d_spare[4] = le32dec(ptr + 128);
-	d->d_magic2 = le32dec(ptr + 132);
 	d->d_checksum = le16dec(ptr + 136);
 	d->d_npartitions = le16dec(ptr + 138);
 	d->d_bbsize = le32dec(ptr + 140);
 	d->d_sbsize = le32dec(ptr + 144);
 	for (i = 0; i < MAXPARTITIONS; i++)
 		bsd_partition_le_dec(ptr + 148 + 16 * i, &d->d_partitions[i]);
+	return(0);
 }
 
 void
@@ -121,6 +149,8 @@
 bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d)
 {
 	int i;
+	u_char *p, *pe;
+	uint16_t sum;
 
 	le32enc(ptr + 0, d->d_magic);
 	le16enc(ptr + 4, d->d_type);
@@ -154,10 +184,15 @@
 	le32enc(ptr + 124, d->d_spare[3]);
 	le32enc(ptr + 128, d->d_spare[4]);
 	le32enc(ptr + 132, d->d_magic2);
-	le16enc(ptr + 136, d->d_checksum);
+	le16enc(ptr + 136, 0);
 	le16enc(ptr + 138, d->d_npartitions);
 	le32enc(ptr + 140, d->d_bbsize);
 	le32enc(ptr + 144, d->d_sbsize);
-	for (i = 0; i < MAXPARTITIONS; i++)
+	for (i = 0; i < d->d_npartitions; i++)
 		bsd_partition_le_enc(ptr + 148 + 16 * i, &d->d_partitions[i]);
+	pe = ptr + 148 + 16 * d->d_npartitions;
+	sum = 0;
+	for (p = ptr; p < pe; p += 2)
+		sum ^= le16dec(p);
+	le16enc(ptr + 136, sum);
 }

==== //depot/projects/hammer/sys/sys/disklabel.h#10 (text+ko) ====

@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)disklabel.h	8.2 (Berkeley) 7/10/94
- * $FreeBSD: src/sys/sys/disklabel.h,v 1.101 2003/04/17 07:39:03 phk Exp $
+ * $FreeBSD: src/sys/sys/disklabel.h,v 1.102 2003/05/02 22:46:13 phk Exp $
  */
 
 #ifndef _SYS_DISKLABEL_H_
@@ -305,7 +305,7 @@
  * bytestring.
  */
 void bsd_partition_le_dec(u_char *ptr, struct partition *d);
-void bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d);
+int bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart);
 void bsd_partition_le_enc(u_char *ptr, struct partition *d);
 void bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d);
 

==== //depot/projects/hammer/usr.bin/xlint/arch/amd64/targparam.h#2 (text+ko) ====

@@ -1,4 +1,4 @@
-/*	$NetBSD: targparam.h,v 1.1 2002/01/18 20:39:22 thorpej Exp $	*/
+/*	$NetBSD: targparam.h,v 1.2 2002/01/30 06:55:00 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1994, 1995 Jochen Pohl



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200305030048.h430mPtd064622>