From owner-freebsd-bugs@freebsd.org Wed Feb 10 21:25:49 2016 Return-Path: Delivered-To: freebsd-bugs@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 8F5FAAA4616 for ; Wed, 10 Feb 2016 21:25:49 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from kenobi.freebsd.org (kenobi.freebsd.org [IPv6:2001:1900:2254:206a::16:76]) (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 823A420E for ; Wed, 10 Feb 2016 21:25:49 +0000 (UTC) (envelope-from bugzilla-noreply@freebsd.org) Received: from bugs.freebsd.org ([127.0.1.118]) by kenobi.freebsd.org (8.15.2/8.15.2) with ESMTP id u1ALPnnd077371 for ; Wed, 10 Feb 2016 21:25:49 GMT (envelope-from bugzilla-noreply@freebsd.org) From: bugzilla-noreply@freebsd.org To: freebsd-bugs@FreeBSD.org Subject: [Bug 207092] dd conv=sparse is broken since r265593 Date: Wed, 10 Feb 2016 21:25:49 +0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: Base System X-Bugzilla-Component: bin X-Bugzilla-Version: 10.2-STABLE X-Bugzilla-Keywords: X-Bugzilla-Severity: Affects Many People X-Bugzilla-Who: sobomax@FreeBSD.org X-Bugzilla-Status: New X-Bugzilla-Resolution: X-Bugzilla-Priority: --- X-Bugzilla-Assigned-To: freebsd-bugs@FreeBSD.org X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version rep_platform op_sys bug_status bug_severity priority component assigned_to reporter Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: https://bugs.freebsd.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Feb 2016 21:25:49 -0000 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.=