Subject: bug#10282: change in behavior of du with multiple arguments (commit efe53cc)

From: Eric Blake <[email-masked]>
Date: Mon, 12 Dec 2011 15:33:59 -0700

On 12/12/2011 05:50 AM, Kamil Dudka wrote:
> Hi,
> 
> the following upstream commit introduces a major change in behavior of du
> when multiple arguments are specified:
> 
> http://git.savannah.gnu.org/cgit/coreutils.git/commit/?id=efe53cc
> 
> ... and the issue has landed as a bug in our Bugzilla:
> 
> https://bugzilla.redhat.com/747075#c3
> 
> Was such a change in behavior intended?

A change in behavior was intended, but I think we ended up introducing a
bug in its place.

> The info 
> documentation states:
> 
>     The FILE argument order affects which links are counted, and changing the
>     argument order may change the numbers that `du' outputs.

And this is intended.  The end goal is that if a directory appears both
on the command line and as a child of another directory on the command
line, that it gets counted only once.

> 
> However, changing the numbers is one thing and missing lines in the output
> of du is quite another thing.

Yes, that's the bug I think we introduced - we are mistakenly eliding
lines of output, rather than listing those directories with 0 attributed
additional size.

More importantly, POSIX says of -s:

"−s Instead of the default output, report only the total sum for each of
the specified files."

But we fail that:

$ mkdir -p /tmp/a/b
$ cd /tmp/a
$ du -s . b
8	.
$ du -s b .
4	b
4	.

We correctly deduced that only 8 units were occupied (that is, b was not
double-counted in either approach), but we _failed_ to list b in the
first approach.  I think POSIX requires the output to have been:

$ du -s . b
8       .
0       b

as an indication that we did visit b, but that there were no additional
contributions to the disk usage encountered during our visit there.

Meanwhile, without -s, I still think we elided too much data:

$ du . b
4	./b
8	.
$ du b .
4	b
4	.

In the first case, we recursed into ./b, then back out to ., but elided
any notion that we ever directly visited b.  In the second case, we
visited b, then recursed into ./b but had nothing to output, then back
out to '.'.  I think that a saner output would be:

$ du . b
4       ./b
8       .
0       b
$ du b .
4       b
0       ./b
4       .

to make it obvious that we pruned recursion at points where we
encountered duplicates, and that the sum of the first columns shows an
accurate disk usage.

-- 
Eric Blake   [email-masked]    +1-919-301-3266
Libvirt virtualization library http://libvirt.org