Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Feb 2016 21:25:49 +0000
From:      bugzilla-noreply@freebsd.org
To:        freebsd-bugs@FreeBSD.org
Subject:   [Bug 207092] dd conv=sparse is broken since r265593
Message-ID:  <bug-207092-8@https.bugs.freebsd.org/bugzilla/>

next in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D207092

            Bug ID: 207092
           Summary: dd conv=3Dsparse is broken since r265593
           Product: Base System
           Version: 10.2-STABLE
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Many People
          Priority: ---
         Component: bin
          Assignee: freebsd-bugs@FreeBSD.org
          Reporter: sobomax@FreeBSD.org

The dd(1) sparse conversion is seriously broken after this change. The last
block is never written at least for the case of output being regular file:

$ dd if=3D/dev/zero of=3D/tmp/foo.bar bs=3D1m count=3D10
10+0 records in
10+0 records out
10485760 bytes transferred in 0.003244 secs (3232431656 bytes/sec)
$ ktrace dd if=3D/tmp/foo.bar of=3D/tmp/foo.bar1 bs=3D1m conv=3Dsparse
10+0 records in
10+0 records out
$ ls -l /tmp/foo.bar /tmp/foo.bar1
-rw-r--r--  1 sobomax  wheel  10485760 Feb  9 23:59 /tmp/foo.bar
-rw-r--r--  1 sobomax  wheel         0 Feb  9 23:59 /tmp/foo.bar1
$ uname -a
FreeBSD abc.sippysoft.com 10.3-PRERELEASE FreeBSD 10.3-PRERELEASE #1
80de3e2(master)-dirty: Tue Feb  2 12:19:57 PST 2016=20=20=20=20
sobomax@abc.sippysoft.com:/usr/obj/usr/home/sobomax/projects/freebsd103/sys=
/VAN01
 amd64

ktrace ends with:

  3150 dd       RET   read 1048576/0x100000
  3150 dd       CALL  read(0x3,0x801009000,0x100000)
  3150 dd       GIO   fd 3 read 0 bytes
       ""
  3150 dd       RET   read 0
  3150 dd       CALL  lseek(0x4,0x900000,SEEK_CUR)
  3150 dd       RET   lseek 9437184/0x900000
  3150 dd       CALL  close(0x4)
  3150 dd       RET   close 0
  3150 dd       CALL  write(0x2,0x7fffffffe2c0,0x21)
  3150 dd       GIO   fd 2 wrote 33 bytes
       "10+0 records in
        10+0 records out
       "
  3150 dd       RET   write 33/0x21
  3150 dd       CALL  write(0x2,0x7fffffffe2c0,0x43)
  3150 dd       GIO   fd 2 wrote 67 bytes
       "10485760 bytes transferred in 0.008217 secs (1276090675 bytes/sec)
       "
  3150 dd       RET   write 67/0x43
  3150 dd       CALL  sigprocmask(SIG_BLOCK,0x800822a38,0x7fffffffe780)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  sigprocmask(SIG_SETMASK,0x800822a4c,0)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  sigprocmask(SIG_BLOCK,0x800822a38,0x7fffffffe310)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  sigprocmask(SIG_SETMASK,0x800822a4c,0)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  sigprocmask(SIG_BLOCK,0x800822a38,0x7fffffffe310)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  sigprocmask(SIG_SETMASK,0x800822a4c,0)
  3150 dd       RET   sigprocmask 0
  3150 dd       CALL  exit(0)


Looking at the code in question I don't see how could it have worked. Look =
at
the following piece of code in your diff for example:

+                                       if (force && cnt =3D=3D 0) {
+                                               pending -=3D last_sp;
+                                               assert(outp =3D=3D out.db);
+                                               memset(outp, 0, cnt);
+                                       }

When the branch is taken, cnt is 0, so at the very least memset(x, y, 0) is
NOP.  Later on, write(2) is conditional on cnt !=3D 0, so that it's never t=
aken.
As a result, lseek is the last operation the file sees.

Also, for what it's worth, you can use ftruncate(2) instead of write() for
regular sparse files to ensure correct size. That would write just as much =
data
as needed to the end. I've made a quick and dirty patch, that seems to be
working better than current code at least:

http://sobomax.sippysoft.com/dd.diff

--=20
You are receiving this mail because:
You are the assignee for the bug.=



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