From owner-svn-src-all@FreeBSD.ORG Tue Apr 22 18:08:35 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0FBDE3C7; Tue, 22 Apr 2014 18:08:35 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id E43EC17B3; Tue, 22 Apr 2014 18:08:34 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s3MI8YKI057527; Tue, 22 Apr 2014 18:08:34 GMT (envelope-from loos@svn.freebsd.org) Received: (from loos@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s3MI8Y8G057526; Tue, 22 Apr 2014 18:08:34 GMT (envelope-from loos@svn.freebsd.org) Message-Id: <201404221808.s3MI8Y8G057526@svn.freebsd.org> From: Luiz Otavio O Souza Date: Tue, 22 Apr 2014 18:08:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264769 - head/sys/geom/uncompress X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 22 Apr 2014 18:08:35 -0000 Author: loos Date: Tue Apr 22 18:08:34 2014 New Revision: 264769 URL: http://svnweb.freebsd.org/changeset/base/264769 Log: Keep geom_uncompress(4) in line with geom_uzip(4), bring in the r264504 fix. Make sure not to start I/O bigger than MAXPHYS bytes. Quoting r264504: When we detect the condition, we'll reduce the block count and perform a "short" read. In g_uncompress_done() we need to consider the original I/O length and stop early if we're about to deflate a block that we didn't read. By using bio_completed in the cloned BIO and not bio_length to check for this, we automatically and gracefully handle short reads that our providers may be doing on top of the short reads we may initiate ourselves. Reviewed by: marcel Modified: head/sys/geom/uncompress/g_uncompress.c Modified: head/sys/geom/uncompress/g_uncompress.c ============================================================================== --- head/sys/geom/uncompress/g_uncompress.c Tue Apr 22 16:13:56 2014 (r264768) +++ head/sys/geom/uncompress/g_uncompress.c Tue Apr 22 18:08:34 2014 (r264769) @@ -169,7 +169,7 @@ g_uncompress_done(struct bio *bp) 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,6 +210,7 @@ g_uncompress_done(struct bio *bp) */ start_blk = bp2->bio_offset / sc->blksz; bsize = pp2->sectorsize; + iolen = bp->bio_completed; pos = sc->offsets[start_blk] % bsize; upos = 0; @@ -239,6 +240,13 @@ g_uncompress_done(struct bio *bp) 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 @@ -292,6 +300,7 @@ g_uncompress_done(struct bio *bp) mtx_unlock(&sc->last_mtx); pos += len; + iolen -= len; upos += ulen; bp2->bio_completed += ulen; } @@ -380,10 +389,18 @@ g_uncompress_start(struct bio *bp) 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; + + 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, @@ -392,6 +409,7 @@ g_uncompress_start(struct bio *bp) (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);