Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 21 May 2014 07:50:01 GMT
From:      dfilter@FreeBSD.ORG (dfilter service)
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/189174: commit references a PR
Message-ID:  <201405210750.s4L7o17C023744@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <sys/filio.h>
  #include <sys/time.h>
  
 +#include <assert.h>
  #include <ctype.h>
  #include <err.h>
  #include <errno.h>
 @@ -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"
 



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