[Midnightbsd-cvs] src [9967] trunk/sys/geom: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat May 26 11:19:26 EDT 2018


Revision: 9967
          http://svnweb.midnightbsd.org/src/?rev=9967
Author:   laffer1
Date:     2018-05-26 11:19:25 -0400 (Sat, 26 May 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/sys/geom/stripe/g_stripe.c
    trunk/sys/geom/stripe/g_stripe.h
    trunk/sys/geom/uncompress/g_uncompress.c

Modified: trunk/sys/geom/stripe/g_stripe.c
===================================================================
--- trunk/sys/geom/stripe/g_stripe.c	2018-05-26 15:18:24 UTC (rev 9966)
+++ trunk/sys/geom/stripe/g_stripe.c	2018-05-26 15:19:25 UTC (rev 9967)
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/geom/stripe/g_stripe.c,v 1.32 2007/06/04 18:25:06 dwmalone Exp $");
+__FBSDID("$FreeBSD: stable/10/sys/geom/stripe/g_stripe.c 306765 2016-10-06 15:36:13Z mav $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -175,10 +175,9 @@
 	}
 
 	if (sc->sc_provider != NULL) {
-		sc->sc_provider->flags |= G_PF_WITHER;
 		G_STRIPE_DEBUG(0, "Device %s deactivated.",
 		    sc->sc_provider->name);
-		g_orphan_provider(sc->sc_provider, ENXIO);
+		g_wither_provider(sc->sc_provider, ENXIO);
 		sc->sc_provider = NULL;
 	}
 
@@ -285,9 +284,6 @@
 
 	pbp = bp->bio_parent;
 	sc = pbp->bio_to->geom->softc;
-	if (pbp->bio_error == 0)
-		pbp->bio_error = bp->bio_error;
-	pbp->bio_completed += bp->bio_completed;
 	if (bp->bio_cmd == BIO_READ && bp->bio_caller1 != NULL) {
 		g_stripe_copy(sc, bp->bio_data, bp->bio_caller1, bp->bio_offset,
 		    bp->bio_length, 1);
@@ -294,13 +290,19 @@
 		bp->bio_data = bp->bio_caller1;
 		bp->bio_caller1 = NULL;
 	}
-	g_destroy_bio(bp);
+	mtx_lock(&sc->sc_lock);
+	if (pbp->bio_error == 0)
+		pbp->bio_error = bp->bio_error;
+	pbp->bio_completed += bp->bio_completed;
 	pbp->bio_inbed++;
 	if (pbp->bio_children == pbp->bio_inbed) {
+		mtx_unlock(&sc->sc_lock);
 		if (pbp->bio_driver1 != NULL)
 			uma_zfree(g_stripe_zone, pbp->bio_driver1);
 		g_io_deliver(pbp, pbp->bio_error);
-	}
+	} else
+		mtx_unlock(&sc->sc_lock);
+	g_destroy_bio(bp);
 }
 
 static int
@@ -443,7 +445,6 @@
 
 	sc = bp->bio_to->geom->softc;
 
-	addr = bp->bio_data;
 	stripesize = sc->sc_stripesize;
 
 	cbp = g_clone_bio(bp);
@@ -455,17 +456,26 @@
 	/*
 	 * Fill in the component buf structure.
 	 */
-	cbp->bio_done = g_std_done;
+	if (bp->bio_length == length)
+		cbp->bio_done = g_std_done;	/* Optimized lockless case. */
+	else
+		cbp->bio_done = g_stripe_done;
 	cbp->bio_offset = offset;
-	cbp->bio_data = addr;
 	cbp->bio_length = length;
+	if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+		bp->bio_ma_n = round_page(bp->bio_ma_offset +
+		    bp->bio_length) / PAGE_SIZE;
+		addr = NULL;
+	} else
+		addr = bp->bio_data;
 	cbp->bio_caller2 = sc->sc_disks[no];
 
 	/* offset -= offset % stripesize; */
 	offset -= offset & (stripesize - 1);
-	addr += length;
+	if (bp->bio_cmd != BIO_DELETE)
+		addr += length;
 	length = bp->bio_length - length;
-	for (no++; length > 0; no++, length -= stripesize, addr += stripesize) {
+	for (no++; length > 0; no++, length -= stripesize) {
 		if (no > sc->sc_ndisks - 1) {
 			no = 0;
 			offset += stripesize;
@@ -480,16 +490,26 @@
 		/*
 		 * Fill in the component buf structure.
 		 */
-		cbp->bio_done = g_std_done;
+		cbp->bio_done = g_stripe_done;
 		cbp->bio_offset = offset;
-		cbp->bio_data = addr;
 		/*
 		 * MIN() is in case when
 		 * (bp->bio_length % sc->sc_stripesize) != 0.
 		 */
 		cbp->bio_length = MIN(stripesize, length);
+		if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+			cbp->bio_ma_offset += (uintptr_t)addr;
+			cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+			cbp->bio_ma_offset %= PAGE_SIZE;
+			cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+			    cbp->bio_length) / PAGE_SIZE;
+		} else
+			cbp->bio_data = addr;
 
 		cbp->bio_caller2 = sc->sc_disks[no];
+
+		if (bp->bio_cmd != BIO_DELETE)
+			addr += stripesize;
 	}
 	/*
 	 * Fire off all allocated requests!
@@ -537,15 +557,15 @@
 			return;
 		}
 		bioq_insert_tail(&queue, cbp);
-		cbp->bio_done = g_std_done;
-		cbp->bio_caller1 = sc->sc_disks[no];
+		cbp->bio_done = g_stripe_done;
+		cbp->bio_caller2 = sc->sc_disks[no];
 		cbp->bio_to = sc->sc_disks[no]->provider;
 	}
 	for (cbp = bioq_first(&queue); cbp != NULL; cbp = bioq_first(&queue)) {
 		bioq_remove(&queue, cbp);
 		G_STRIPE_LOGREQ(cbp, "Sending request.");
-		cp = cbp->bio_caller1;
-		cbp->bio_caller1 = NULL;
+		cp = cbp->bio_caller2;
+		cbp->bio_caller2 = NULL;
 		g_io_request(cbp, cp);
 	}
 }
@@ -614,9 +634,15 @@
 	 * 3. Request size is bigger than stripesize * ndisks. If it isn't,
 	 *    there will be no need to send more than one I/O request to
 	 *    a provider, so there is nothing to optmize.
+	 * and
+	 * 4. Request is not unmapped.
+	 * and
+	 * 5. It is not a BIO_DELETE.
 	 */
 	if (g_stripe_fast && bp->bio_length <= MAXPHYS &&
-	    bp->bio_length >= stripesize * sc->sc_ndisks) {
+	    bp->bio_length >= stripesize * sc->sc_ndisks &&
+	    (bp->bio_flags & BIO_UNMAPPED) == 0 &&
+	    bp->bio_cmd != BIO_DELETE) {
 		fast = 1;
 	}
 	error = 0;
@@ -643,6 +669,7 @@
 static void
 g_stripe_check_and_run(struct g_stripe_softc *sc)
 {
+	struct g_provider *dp;
 	off_t mediasize, ms;
 	u_int no, sectorsize = 0;
 
@@ -652,6 +679,9 @@
 
 	sc->sc_provider = g_new_providerf(sc->sc_geom, "stripe/%s",
 	    sc->sc_name);
+	sc->sc_provider->flags |= G_PF_DIRECT_SEND | G_PF_DIRECT_RECEIVE;
+	if (g_stripe_fast == 0)
+		sc->sc_provider->flags |= G_PF_ACCEPT_UNMAPPED;
 	/*
 	 * Find the smallest disk.
 	 */
@@ -661,14 +691,21 @@
 	mediasize -= mediasize % sc->sc_stripesize;
 	sectorsize = sc->sc_disks[0]->provider->sectorsize;
 	for (no = 1; no < sc->sc_ndisks; no++) {
-		ms = sc->sc_disks[no]->provider->mediasize;
+		dp = sc->sc_disks[no]->provider;
+		ms = dp->mediasize;
 		if (sc->sc_type == G_STRIPE_TYPE_AUTOMATIC)
-			ms -= sc->sc_disks[no]->provider->sectorsize;
+			ms -= dp->sectorsize;
 		ms -= ms % sc->sc_stripesize;
 		if (ms < mediasize)
 			mediasize = ms;
-		sectorsize = lcm(sectorsize,
-		    sc->sc_disks[no]->provider->sectorsize);
+		sectorsize = lcm(sectorsize, dp->sectorsize);
+
+		/* A provider underneath us doesn't support unmapped */
+		if ((dp->flags & G_PF_ACCEPT_UNMAPPED) == 0) {
+			G_STRIPE_DEBUG(1, "Cancelling unmapped "
+			    "because of %s.", dp->name);
+			sc->sc_provider->flags &= ~G_PF_ACCEPT_UNMAPPED;
+		}
 	}
 	sc->sc_provider->sectorsize = sectorsize;
 	sc->sc_provider->mediasize = mediasize * sc->sc_ndisks;
@@ -730,6 +767,7 @@
 	fcp = LIST_FIRST(&gp->consumer);
 
 	cp = g_new_consumer(gp);
+	cp->flags |= G_CF_DIRECT_SEND | G_CF_DIRECT_RECEIVE;
 	cp->private = NULL;
 	cp->index = no;
 	error = g_attach(cp, pp);
@@ -831,6 +869,7 @@
 	for (no = 0; no < sc->sc_ndisks; no++)
 		sc->sc_disks[no] = NULL;
 	sc->sc_type = type;
+	mtx_init(&sc->sc_lock, "gstripe lock", NULL, MTX_DEF);
 
 	gp->softc = sc;
 	sc->sc_geom = gp;
@@ -879,6 +918,7 @@
 	KASSERT(sc->sc_provider == NULL, ("Provider still exists? (device=%s)",
 	    gp->name));
 	free(sc->sc_disks, M_STRIPE);
+	mtx_destroy(&sc->sc_lock);
 	free(sc, M_STRIPE);
 	G_STRIPE_DEBUG(0, "Device %s destroyed.", gp->name);
 	g_wither_geom(gp, ENXIO);

Modified: trunk/sys/geom/stripe/g_stripe.h
===================================================================
--- trunk/sys/geom/stripe/g_stripe.h	2018-05-26 15:18:24 UTC (rev 9966)
+++ trunk/sys/geom/stripe/g_stripe.h	2018-05-26 15:19:25 UTC (rev 9967)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/geom/stripe/g_stripe.h,v 1.9 2006/02/01 12:06:01 pjd Exp $
+ * $FreeBSD: stable/10/sys/geom/stripe/g_stripe.h 260385 2014-01-07 01:32:23Z scottl $
  */
 
 #ifndef	_G_STRIPE_H_
@@ -77,6 +77,7 @@
 	uint16_t	 sc_ndisks;
 	uint32_t	 sc_stripesize;
 	uint32_t	 sc_stripebits;
+	struct mtx	 sc_lock;
 };
 #define	sc_name	sc_geom->name
 #endif	/* _KERNEL */

Modified: trunk/sys/geom/uncompress/g_uncompress.c
===================================================================
--- trunk/sys/geom/uncompress/g_uncompress.c	2018-05-26 15:18:24 UTC (rev 9966)
+++ trunk/sys/geom/uncompress/g_uncompress.c	2018-05-26 15:19:25 UTC (rev 9967)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2010-2012 Aleksandr Rybalko
  * Copyright (c) 2004 Max Khon
@@ -34,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__MBSDID("$MidnightBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/geom/uncompress/g_uncompress.c 289958 2015-10-25 22:38:17Z ngie $");
 
 #include <sys/param.h>
 #include <sys/bio.h>
@@ -111,12 +112,12 @@
 {
 
 	if (gp != NULL) {
-		printf("%s: %d requests, %d cached\n",
-		    gp->name, sc->req_total, sc->req_cached);
+		DPRINTF(("%s: %d requests, %d cached\n",
+		    gp->name, sc->req_total, sc->req_cached));
 	}
 	if (sc->offsets != NULL) {
 		free(sc->offsets, M_GEOM_UNCOMPRESS);
-		sc->offsets = 0;
+		sc->offsets = NULL;
 	}
 
 	switch (sc->type) {
@@ -150,6 +151,7 @@
 	void *ptr;
 
 	ptr = malloc(type * size, M_GEOM_UNCOMPRESS, M_NOWAIT);
+
 	return (ptr);
 }
 
@@ -169,7 +171,7 @@
 	struct g_geom *gp;
 	struct bio *bp2;
 	uint32_t start_blk, i;
-	off_t pos, upos;
+	off_t iolen, pos, upos;
 	size_t bsize;
 	int err;
 
@@ -210,24 +212,27 @@
 	 */
 	start_blk = bp2->bio_offset / sc->blksz;
 	bsize = pp2->sectorsize;
+	iolen = bp->bio_completed;
 	pos = sc->offsets[start_blk] % bsize;
 	upos = 0;
 
-	DPRINTF(("%s: done: bio_length %lld bio_completed %lld start_blk %d, "
-		"pos %lld, upos %lld (%lld, %d, %d)\n",
-	    gp->name, bp->bio_length, bp->bio_completed, start_blk, pos, upos,
-	    bp2->bio_offset, sc->blksz, bsize));
+	DPRINTF(("%s: done: bio_length %jd bio_completed %jd start_blk %d, "
+	    "pos %jd, upos %jd (%jd, %d, %zu)\n",
+	    gp->name, (intmax_t)bp->bio_length, (intmax_t)bp->bio_completed,
+	    start_blk, (intmax_t)pos, (intmax_t)upos,
+	    (intmax_t)bp2->bio_offset, sc->blksz, bsize));
 
 	for (i = start_blk; upos < bp2->bio_length; i++) {
-		off_t len, dlen, ulen, uoff;
+		off_t len, ulen, uoff;
 
 		uoff = i == start_blk ? bp2->bio_offset % sc->blksz : 0;
 		ulen = MIN(sc->blksz - uoff, bp2->bio_length - upos);
-		dlen = len = sc->offsets[i + 1] - sc->offsets[i];
+		len = sc->offsets[i + 1] - sc->offsets[i];
 
-		DPRINTF(("%s: done: inflate block %d, start %lld, end %lld "
-			"len %lld\n",
-		    gp->name, i, sc->offsets[i], sc->offsets[i + 1], len));
+		DPRINTF((
+		    "%s: done: inflate block %d, start %ju, end %ju len %jd\n",
+		    gp->name, i, (uintmax_t)sc->offsets[i],
+		    (uintmax_t)sc->offsets[i + 1], (intmax_t)len));
 
 		if (len == 0) {
 			/* All zero block: no cache update */
@@ -236,12 +241,17 @@
 			bp2->bio_completed += ulen;
 			continue;
 		}
-
+		if (len > iolen) {
+			DPRINTF(("%s: done: early termination: len (%jd) > "
+			    "iolen (%jd)\n",
+			    gp->name, (intmax_t)len, (intmax_t)iolen));
+			break;
+		}
 		mtx_lock(&sc->last_mtx);
 
 #ifdef GEOM_UNCOMPRESS_DEBUG
 		if (g_debugflags & 32)
-			hexdump(bp->bio_data + pos, dlen, 0, 0);
+			hexdump(bp->bio_data + pos, len, 0, 0);
 #endif
 
 		switch (sc->type) {
@@ -249,7 +259,7 @@
 			sc->b->in = bp->bio_data + pos;
 			sc->b->out = sc->last_buf;
 			sc->b->in_pos = sc->b->out_pos = 0;
-			sc->b->in_size = dlen;
+			sc->b->in_size = len;
 			sc->b->out_size = (size_t)-1;
 
 			err = (xz_dec_run(sc->s, sc->b) != XZ_STREAM_END) ?
@@ -258,13 +268,13 @@
 			break;
 		case GEOM_UZIP:
 			sc->zs->next_in = bp->bio_data + pos;
-			sc->zs->avail_in = dlen;
+			sc->zs->avail_in = len;
 			sc->zs->next_out = sc->last_buf;
 			sc->zs->avail_out = sc->blksz;
 
 			err = (inflate(sc->zs, Z_FINISH) != Z_STREAM_END) ?
 			    1 : 0;
-			if ((err) && (inflateReset(sc->zs) != Z_OK))
+			if ((err) || (inflateReset(sc->zs) != Z_OK))
 				printf("%s: UZIP decoder reset failed\n",
 				     gp->name);
 			break;
@@ -290,6 +300,7 @@
 		mtx_unlock(&sc->last_mtx);
 
 		pos += len;
+		iolen -= len;
 		upos += ulen;
 		bp2->bio_completed += ulen;
 	}
@@ -298,8 +309,9 @@
 	/*
 	 * Finish processing the request.
 	 */
-	DPRINTF(("%s: done: (%d, %lld, %ld)\n",
-	    gp->name, bp2->bio_error, bp2->bio_completed, bp2->bio_resid));
+	DPRINTF(("%s: done: (%d, %jd, %ld)\n",
+	    gp->name, bp2->bio_error, (intmax_t)bp2->bio_completed,
+	    bp2->bio_resid));
 	free(bp->bio_data, M_GEOM_UNCOMPRESS);
 	g_destroy_bio(bp);
 	g_io_deliver(bp2, bp2->bio_error);
@@ -316,12 +328,12 @@
 	uint32_t start_blk, end_blk;
 	size_t bsize;
 
-
 	pp = bp->bio_to;
 	gp = pp->geom;
-	DPRINTF(("%s: start (%s) to %s off=%lld len=%lld\n", gp->name,
-		(bp->bio_cmd==BIO_READ) ? "BIO_READ" : "BIO_WRITE*",
-		pp->name, bp->bio_offset, bp->bio_length));
+	DPRINTF(("%s: start (%d:%s) to %s off=%jd len=%jd\n",
+	    gp->name, bp->bio_cmd,
+	    (bp->bio_cmd == BIO_READ) ? "BIO_READ" : "NOTSUPPORTED",
+	    pp->name, (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length));
 
 	if (bp->bio_cmd != BIO_READ) {
 		g_io_deliver(bp, EOPNOTSUPP);
@@ -334,10 +346,8 @@
 
 	start_blk = bp->bio_offset / sc->blksz;
 	end_blk   = howmany(bp->bio_offset + bp->bio_length, sc->blksz);
-	KASSERT(start_blk < sc->nblocks,
-		("start_blk out of range"));
-	KASSERT(end_blk <= sc->nblocks,
-		("end_blk out of range"));
+	KASSERT(start_blk < sc->nblocks, ("start_blk out of range"));
+	KASSERT(end_blk <= sc->nblocks, ("end_blk out of range"));
 
 	sc->req_total++;
 	if (start_blk + 1 == end_blk) {
@@ -353,9 +363,9 @@
 			sc->req_cached++;
 			mtx_unlock(&sc->last_mtx);
 
-			DPRINTF(("%s: start: cached 0 + %lld, "
-			    "%lld + 0 + %lld\n",
-			    gp->name, bp->bio_length, uoff, bp->bio_length));
+			DPRINTF(("%s: start: cached 0 + %jd, %jd + 0 + %jd\n",
+			    gp->name, (intmax_t)bp->bio_length, (intmax_t)uoff,
+			    (intmax_t)bp->bio_length));
 			bp->bio_completed = bp->bio_length;
 			g_io_deliver(bp, 0);
 			return;
@@ -368,26 +378,31 @@
 		g_io_deliver(bp, ENOMEM);
 		return;
 	}
-	DPRINTF(("%s: start (%d..%d), %s: %d + %llu, %s: %d + %llu\n",
+	DPRINTF(("%s: start (%d..%d), %s: %d + %jd, %s: %d + %jd\n",
 	    gp->name, start_blk, end_blk,
-	    pp->name, pp->sectorsize, pp->mediasize,
-	    pp2->name, pp2->sectorsize, pp2->mediasize));
-
+	    pp->name, pp->sectorsize, (intmax_t)pp->mediasize,
+	    pp2->name, pp2->sectorsize, (intmax_t)pp2->mediasize));
 	bsize = pp2->sectorsize;
-
 	bp2->bio_done = g_uncompress_done;
-	bp2->bio_offset = rounddown(sc->offsets[start_blk],bsize);
-	bp2->bio_length = roundup(sc->offsets[end_blk],bsize) -
-	    bp2->bio_offset;
-	bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
+	bp2->bio_offset = rounddown(sc->offsets[start_blk], bsize);
+	while (1) {
+		bp2->bio_length = roundup(sc->offsets[end_blk], bsize) -
+		    bp2->bio_offset;
+		if (bp2->bio_length < MAXPHYS)
+			break;
 
-	DPRINTF(("%s: start %lld + %lld -> %lld + %lld -> %lld + %lld\n",
+		end_blk--;
+		DPRINTF((
+		    "%s: bio_length (%jd) > MAXPHYS: lowering end_blk to %u\n",
+		    gp->name, (intmax_t)bp2->bio_length, end_blk));
+	}
+	DPRINTF(("%s: start %jd + %jd -> %ju + %ju -> %jd + %jd\n",
 	    gp->name,
-	    bp->bio_offset, bp->bio_length,
-	    sc->offsets[start_blk],
-	    sc->offsets[end_blk] - sc->offsets[start_blk],
-	    bp2->bio_offset, bp2->bio_length));
-
+	    (intmax_t)bp->bio_offset, (intmax_t)bp->bio_length,
+	    (uintmax_t)sc->offsets[start_blk],
+	    (uintmax_t)sc->offsets[end_blk] - sc->offsets[start_blk],
+	    (intmax_t)bp2->bio_offset, (intmax_t)bp2->bio_length));
+	bp2->bio_data = malloc(bp2->bio_length, M_GEOM_UNCOMPRESS, M_NOWAIT);
 	if (bp2->bio_data == NULL) {
 		g_destroy_bio(bp2);
 		g_io_deliver(bp, ENOMEM);
@@ -403,8 +418,7 @@
 {
 	struct g_geom *gp;
 
-	g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp,
-		cp->provider->name);
+	g_trace(G_T_TOPOLOGY, "%s(%p/%s)", __func__, cp, cp->provider->name);
 	g_topology_assert();
 
 	gp = cp->geom;
@@ -451,7 +465,8 @@
 	struct g_provider *pp2;
 	struct g_consumer *cp;
 	struct g_geom *gp;
-	uint32_t i, total_offsets, offsets_read, type;
+	uint64_t *offsets;
+	uint32_t i, r, total, total_offsets, type;
 	uint8_t *buf;
 	int error;
 
@@ -484,17 +499,15 @@
 	 * Read cloop header, look for CLOOP magic, perform
 	 * other validity checks.
 	 */
-	DPRINTF(("%s: media sectorsize %u, mediasize %lld\n",
-	    gp->name, pp->sectorsize, pp->mediasize));
-
-	i = roundup(sizeof(struct cloop_header), pp->sectorsize);
-	buf = g_read_data(cp, 0, i, NULL);
+	DPRINTF(("%s: media sectorsize %u, mediasize %jd\n",
+	    gp->name, pp->sectorsize, (intmax_t)pp->mediasize));
+	total = roundup(sizeof(struct cloop_header), pp->sectorsize);
+	buf = g_read_data(cp, 0, total, NULL);
 	if (buf == NULL)
 		goto err;
-
 	header = (struct cloop_header *) buf;
 	if (strncmp(header->magic, CLOOP_MAGIC_START,
-		    sizeof(CLOOP_MAGIC_START) - 1) != 0) {
+	    sizeof(CLOOP_MAGIC_START) - 1) != 0) {
 		DPRINTF(("%s: no CLOOP magic\n", gp->name));
 		goto err;
 	}
@@ -506,7 +519,7 @@
 			DPRINTF(("%s: image version too old\n", gp->name));
 			goto err;
 		}
-		printf("%s: GEOM_ULZMA image found\n", gp->name);
+		DPRINTF(("%s: GEOM_ULZMA image found\n", gp->name));
 		break;
 	case 'V':
 		type = GEOM_UZIP;
@@ -514,7 +527,7 @@
 			DPRINTF(("%s: image version too old\n", gp->name));
 			goto err;
 		}
-		printf("%s: GEOM_UZIP image found\n", gp->name);
+		DPRINTF(("%s: GEOM_UZIP image found\n", gp->name));
 		break;
 	default:
 		DPRINTF(("%s: unsupported image type\n", gp->name));
@@ -546,25 +559,30 @@
 		    gp->name, sc->nblocks);
 		goto err;
 	}
-	sc->offsets = malloc(
-	    total_offsets * sizeof(uint64_t), M_GEOM_UNCOMPRESS, M_WAITOK);
-	offsets_read = MIN(total_offsets,
-	    (pp->sectorsize - sizeof(*header)) / sizeof(uint64_t));
-	for (i = 0; i < offsets_read; i++)
-		sc->offsets[i] = be64toh(((uint64_t *) (header + 1))[i]);
-	DPRINTF(("%s: %u offsets in the first sector\n",
-	    gp->name, offsets_read));
+	g_free(buf);
 
-	free(buf, M_GEOM);
-	i = roundup((sizeof(struct cloop_header) +
-		total_offsets * sizeof(uint64_t)),pp->sectorsize);
-	buf = g_read_data(cp, 0, i, NULL);
-	if (buf == NULL)
-		goto err;
-	for (i = 0; i <= total_offsets; i++) {
-		sc->offsets[i] = be64toh(((uint64_t *)
-		    (buf+sizeof(struct cloop_header)))[i]);
+	sc->offsets = malloc(total_offsets * sizeof(uint64_t),
+	    M_GEOM_UNCOMPRESS, M_WAITOK | M_ZERO);
+	total = roundup((sizeof(struct cloop_header) +
+	    total_offsets * sizeof(uint64_t)), pp->sectorsize);
+#define	RSZ	((total - r) > MAXPHYS ? MAXPHYS: (total - r))
+	for (r = 0, i = 0; r < total; r += MAXPHYS) {
+		buf = g_read_data(cp, r, RSZ, &error);
+		if (buf == NULL) {
+			free(sc->offsets, M_GEOM_UNCOMPRESS);
+			goto err;
+		}
+		offsets = (uint64_t *)buf;
+		if (r == 0)
+			offsets +=
+			    sizeof(struct cloop_header) / sizeof(uint64_t);
+		for (; i < total_offsets && offsets < (uint64_t *)(buf + RSZ);
+		    i++, offsets++)
+			sc->offsets[i] = be64toh(*offsets);
+		g_free(buf);
 	}
+#undef RSZ
+	buf = NULL;
 	DPRINTF(("%s: done reading offsets\n", gp->name));
 	mtx_init(&sc->last_mtx, "geom_uncompress cache", NULL, MTX_DEF);
 	sc->last_blk = -1;
@@ -594,21 +612,18 @@
 	pp2 = g_new_providerf(gp, "%s", gp->name);
 	pp2->sectorsize = 512;
 	pp2->mediasize = (off_t)sc->nblocks * sc->blksz;
-	pp2->flags = pp->flags & G_PF_CANDELETE;
 	if (pp->stripesize > 0) {
 		pp2->stripesize = pp->stripesize;
 		pp2->stripeoffset = pp->stripeoffset;
 	}
 	g_error_provider(pp2, 0);
-	free(buf, M_GEOM);
 	g_access(cp, -1, 0, 0);
 
-	DPRINTF(("%s: taste ok (%d, %lld), (%d, %d), %x\n",
+	DPRINTF(("%s: taste ok (%d, %jd), (%d, %d), %x\n",
 	    gp->name,
-	    pp2->sectorsize, pp2->mediasize,
+	    pp2->sectorsize, (intmax_t)pp2->mediasize,
 	    pp2->stripeoffset, pp2->stripesize, pp2->flags));
-	printf("%s: %u x %u blocks\n",
-	    gp->name, sc->nblocks, sc->blksz);
+	DPRINTF(("%s: %u x %u blocks\n", gp->name, sc->nblocks, sc->blksz));
 	return (gp);
 
 err:
@@ -615,7 +630,7 @@
 	g_topology_lock();
 	g_access(cp, -1, 0, 0);
 	if (buf != NULL)
-		free(buf, M_GEOM);
+		g_free(buf);
 	if (gp->softc != NULL) {
 		g_uncompress_softc_free(gp->softc, NULL);
 		gp->softc = NULL;
@@ -623,6 +638,7 @@
 	g_detach(cp);
 	g_destroy_consumer(cp);
 	g_destroy_geom(gp);
+
 	return (NULL);
 }
 
@@ -636,7 +652,7 @@
 	g_topology_assert();
 
 	if (gp->softc == NULL) {
-		printf("%s(%s): gp->softc == NULL\n", __func__, gp->name);
+		DPRINTF(("%s(%s): gp->softc == NULL\n", __func__, gp->name));
 		return (ENXIO);
 	}
 
@@ -649,6 +665,7 @@
 	g_uncompress_softc_free(gp->softc, gp);
 	gp->softc = NULL;
 	g_wither_geom(gp, ENXIO);
+
 	return (0);
 }
 
@@ -665,4 +682,4 @@
 };
 
 DECLARE_GEOM_CLASS(g_uncompress_class, g_uncompress);
-
+MODULE_DEPEND(g_uncompress, zlib, 1, 1, 1);



More information about the Midnightbsd-cvs mailing list