From owner-freebsd-bugs@FreeBSD.ORG Wed May 21 07:50:01 2014 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.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 40ED2B9D for ; Wed, 21 May 2014 07:50:01 +0000 (UTC) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) (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 2EA5727F3 for ; Wed, 21 May 2014 07:50:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.8/8.14.8) with ESMTP id s4L7o1K5023745 for ; Wed, 21 May 2014 07:50:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.8/8.14.8/Submit) id s4L7o17C023744; Wed, 21 May 2014 07:50:01 GMT (envelope-from gnats) Date: Wed, 21 May 2014 07:50:01 GMT Message-Id: <201405210750.s4L7o17C023744@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: dfilter@FreeBSD.ORG (dfilter service) Subject: Re: bin/189174: commit references a PR Reply-To: dfilter@FreeBSD.ORG (dfilter service) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 21 May 2014 07:50:01 -0000 The following reply was made to PR bin/189174; it has been noted by GNATS. From: dfilter@FreeBSD.ORG (dfilter service) To: bug-followup@FreeBSD.org Cc: Subject: Re: bin/189174: commit references a PR Date: Wed, 21 May 2014 07:42:48 +0000 (UTC) Author: thomas Date: Wed May 21 07:42:42 2014 New Revision: 266489 URL: http://svnweb.freebsd.org/changeset/base/266489 Log: MFC rev. 265593: (dd_out): Fix handling of all-zeroes block at end of input with conv=sparse. PR: bin/189174 PR: bin/189284 Reviewed by: kib Modified: stable/9/bin/dd/dd.c Directory Properties: stable/9/ (props changed) stable/9/bin/ (props changed) stable/9/bin/dd/ (props changed) Modified: stable/9/bin/dd/dd.c ============================================================================== --- stable/9/bin/dd/dd.c Wed May 21 07:21:36 2014 (r266488) +++ stable/9/bin/dd/dd.c Wed May 21 07:42:42 2014 (r266489) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -76,6 +77,7 @@ STAT st; /* statistics */ void (*cfunc)(void); /* conversion function */ uintmax_t cpy_cnt; /* # of blocks to copy */ static off_t pending = 0; /* pending seek if sparse */ +static off_t last_sp = 0; /* size of last added sparse block */ u_int ddflags = 0; /* conversion options */ size_t cbsz; /* conversion block size */ uintmax_t files_cnt = 1; /* # of files to copy */ @@ -173,6 +175,8 @@ setup(void) } else if ((in.db = malloc(MAX(in.dbsz, cbsz) + cbsz)) == NULL || (out.db = malloc(out.dbsz + cbsz)) == NULL) err(1, "output buffer"); + + /* dbp is the first free position in each buffer. */ in.dbp = in.db; out.dbp = out.db; @@ -434,8 +438,15 @@ dd_out(int force) * we play games with the buffer size, and it's usually a partial write. */ outp = out.db; + + /* + * If force, first try to write all pending data, else try to write + * just one block. Subsequently always write data one full block at + * a time at most. + */ for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) { - for (cnt = n;; cnt -= nw) { + cnt = n; + do { sparse = 0; if (ddflags & C_SPARSE) { sparse = 1; /* Is buffer sparse? */ @@ -447,18 +458,24 @@ dd_out(int force) } if (sparse && !force) { pending += cnt; + last_sp = cnt; nw = cnt; } else { if (pending != 0) { - if (force) - pending--; + /* If forced to write, and we have no + * data left, we need to write the last + * sparse block explicitly. + */ + if (force && cnt == 0) { + pending -= last_sp; + assert(outp == out.db); + memset(outp, 0, cnt); + } if (lseek(out.fd, pending, SEEK_CUR) == -1) err(2, "%s: seek error creating sparse file", out.name); - if (force) - write(out.fd, outp, 1); - pending = 0; + pending = last_sp = 0; } if (cnt) nw = write(out.fd, outp, cnt); @@ -473,27 +490,29 @@ dd_out(int force) err(1, "%s", out.name); nw = 0; } + outp += nw; st.bytes += nw; - if ((size_t)nw == n) { - if (n != out.dbsz) - ++st.out_part; - else - ++st.out_full; - break; - } - ++st.out_part; - if ((size_t)nw == cnt) - break; - if (out.flags & ISTAPE) - errx(1, "%s: short write on tape device", - out.name); - if (out.flags & ISCHR && !warned) { - warned = 1; - warnx("%s: short write on character device", - out.name); + + if ((size_t)nw == n && n == out.dbsz) + ++st.out_full; + else + ++st.out_part; + + if ((size_t) nw != cnt) { + if (out.flags & ISTAPE) + errx(1, "%s: short write on tape device", + out.name); + if (out.flags & ISCHR && !warned) { + warned = 1; + warnx("%s: short write on character device", + out.name); + } } - } + + cnt -= nw; + } while (cnt != 0); + if ((out.dbcnt -= n) < out.dbsz) break; } _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"