The following reply was made to PR bin/189174; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: bin/189174: commit references a PR
Date: Wed, 21 May 2014 07:21:40 +0000 (UTC)

 Author: thomas
 Date: Wed May 21 07:21:36 2014
 New Revision: 266488
 URL: http://svnweb.freebsd.org/changeset/base/266488
 
 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/10/bin/dd/dd.c
 Directory Properties:
   stable/10/   (props changed)
 
 Modified: stable/10/bin/dd/dd.c
 ==============================================================================
 --- stable/10/bin/dd/dd.c      Wed May 21 06:33:21 2014        (r266487)
 +++ stable/10/bin/dd/dd.c      Wed May 21 07:21:36 2014        (r266488)
 @@ -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-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to