Bug 31821

Summary: new FAQ: du/df
Product: Documentation Reporter: Michael W Lucas <mwlucas>
Component: Books & ArticlesAssignee: freebsd-doc (Nobody) <doc>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: Latest   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff
none
du-vs-df none

Description Michael W Lucas 2001-11-07 14:10:00 UTC
People have asked several times about the difference between du and
df; specifically, the example cited below keeps happening.

How-To-Repeat: 
read -questions
Comment 1 Dima Dorfman 2001-11-07 15:06:27 UTC
mwlucas@blackhelicopters.org wrote:
> *** en_US.ISO8859-1/books/faq/book.sgml-dist	Mon Nov  5 10:49:36 2001
> --- en_US.ISO8859-1/books/faq/book.sgml	Wed Nov  7 09:05:22 2001
> ***************
> *** 5869,5874 ****
> --- 5869,5921 ----
>         </qandaentry>
>   
>         <qandaentry>
> +         <question id="du-vs-df">
> +           <para>The <command>du</command> and <command>df</command>
> +             commands show different amounts of disk space available?

Is this first sentence really a question (i.e., does the question mark
belong there)?

> +             What's going on?</para>
> +         </question>
> + 
> +         <answer>
> +           <para>You need to understand what <command>du</command> and
> +             <command>df</command> really do.  <command>du</command>
> +             shows how much of the disk is designated <emphasis>used by
> +             files</emphasis>.  <command>df</command> shows how much of
> +             the disk is designated <emphasis>free</emphasis>.  While
> +             they seem to be opposite, that isn't exactly true.</para>

I think the distinction isn't what they do, but how they do it; if one
knows how much space is in use and the size of the disk, one can
compute how much space is free.  On the other hand, how they do it
matters: du traverses the directory tree and counts how much space is
in use by each file.  If a file has no directory entry, it won't be
counted.  On the other hand, df just asks the filesystem how much
space it thinks is in use, and the filesystem doesn't care whether
files have directory entires or not, just as long as they take up
space on the disk.

> + 
> +           <para>When a program has a file open, and you delete the
> +             file, it isn't really deleted until the program releases
> +             the file.  You can see this easily enough with a program
> +             such as <command>more</command>.  If you delete a file
> +             while using <command>more</command> on it,
> +             <command>more</command> doesn't immediately choke and
> +             complain that it cannot view the file.  You cannot access
> +             the file from anywhere except that <command>more</command>
> +             window.

This is a very good example.

> If the file is large enough,

This shouldn't (and doesn't) matter.  People just tend to notice when
they're missing 18M instead of 18K :-).

> +             <command>df</command> will show that it is gone.  The
> +             space the file took up is now designated free.
> +             <command>du</command> will show that it is still there, as
> +             the space the file uses is still technically in use.  Once
> +             you end the <command>more</command> session,
> +             <command>du</command> and <command>df</command> will
> +             agree.</para>

This is backwards.  'du' typically reports less space is in use, not
df (if you wrote this looking at the recent thread on -stable, note
that the originator misnamed the output; what he claimed was from du
was from df, and vice versa).  The reason is that 'rm' removes the
file's directory entry, so 'du' never sees it, but 'df' does.  See
above where I explained why 'df' seems it.

Here's a small example to demonstrate my point.  (Note that I cleaned
up the `script' output a little to make it more readable.)

Script started on Wed Nov  7 14:50:19 2001
root@mirage# mdmfs -s 32m md /mnt
root@mirage# cd /mnt
root@mirage# dd if=/dev/random of=fish bs=1m count=20
20+0 records in
20+0 records out
20971520 bytes transferred in 27.938557 secs (750630 bytes/sec)
root@mirage# cat>open.c
#include <fcntl.h>
#include <unistd.h>

int
main(void)
{
int d = open("fish", O_RDONLY);
pause();
}
^D
root@mirage# make open
cc -O -pipe   open.c  -o open
root@mirage# ./open &
[1] 20447
root@mirage# df
Filesystem          1K-blocks     Used    Avail Capacity  Mounted on
/dev/ad0s1a            254063    68466   165272    29%    /
devfs                       1        1        0   100%    /dev
/dev/ad0s1f           2554468   600470  1749641    26%    /usr
/dev/ad0s1e           1016303   226578   708421    24%    /var
/dev/md0c               32476    20520     9360    69%    /mnt
root@mirage# du
20520	.
root@mirage# rm fish
root@mirage# df
Filesystem          1K-blocks     Used    Avail Capacity  Mounted on
/dev/ad0s1a            254063    68466   165272    29%    /
devfs                       1        1        0   100%    /dev
/dev/ad0s1f           2554468   600470  1749641    26%    /usr
/dev/ad0s1e           1016303   226578   708421    24%    /var
/dev/md0c               32476    20520     9360    69%    /mnt
root@mirage# du
16	.
root@mirage# killall open
[1]  + Terminated                    ./open
root@mirage# sync
root@mirage# df
Filesystem          1K-blocks     Used    Avail Capacity  Mounted on
/dev/ad0s1a            254063    68466   165272    29%    /
devfs                       1        1        0   100%    /dev
/dev/ad0s1f           2554468   600470  1749641    26%    /usr
/dev/ad0s1e           1016303   226578   708421    24%    /var
/dev/md0c               32476       16    29864     0%    /mnt
root@mirage# du
16	.
root@mirage# exit

Script done on Wed Nov  7 14:52:01 2001

Notes:

 - The `open' program just opens the file and keeps it open until it's
   killed.  I didn't use `more' as you did in your example because I
   wouldn't be able to show when I started and killed it (it needs a
   tty).

 - The `sync' command isn't instantaneous; about 10 seconds passed
   between the sync and the subsequent df which shows the space is free.
   This is because of softupdates.
Comment 2 Michael W Lucas 2001-11-07 16:10:34 UTC
On Wed, Nov 07, 2001 at 03:06:27PM +0000, Dima Dorfman wrote:
> This is backwards.  'du' typically reports less space is in use, not
> df (if you wrote this looking at the recent thread on -stable, note
> that the originator misnamed the output; what he claimed was from du
> was from df, and vice versa).

Aha!  That confused me, but I'm not going to argue with actual output.

You've gone to a lot of trouble to prove me wrong, but I'm a tech
writer.  I assume that I will be proven wrong.  :)

Here's another patch, addressing your points.

==ml

-- 
Michael Lucas
mwlucas@blackhelicopters.org
http://www.blackhelicopters.org/~mwlucas/
Big Scary Daemons: http://www.oreillynet.com/pub/q/Big_Scary_Daemons
Comment 3 dd freebsd_committer freebsd_triage 2001-11-07 16:28:48 UTC
State Changed
From-To: open->closed

Patch applied, thanks.
Comment 4 clefevre 2001-11-08 01:14:57 UTC
mwlucas@blackhelicopters.org wrote:
[snip]
> +           <para>When a program has a file open, and you delete the
> +             file, it isn't really deleted until the program releases
> +             the file.  You can see this easily enough with a program
> +             such as <command>more</command>.  If you delete a file
> +             while using <command>more</command> on it,
> +             <command>more</command> doesn't immediately choke and
> +             complain that it cannot view the file.  You cannot access
> +             the file from anywhere except that <command>more</command>
> +             window.  If the file is large enough,
> +             <command>df</command> will show that it is gone.  The
                         ^^ du
> +             space the file took up is now designated free.
> +             <command>du</command> will show that it is still there, as
                         ^^ df
> +             the space the file uses is still technically in use.  Once
> +             you end the <command>more</command> session,
> +             <command>du</command> and <command>df</command> will
> +             agree.</para>
> + 
> +           <para>Note that softupdates can delay the freeing of disk
> +             space; you might need to wait up to 30 seconds for the
> +             change to be visible!</para>
> + 
> +           <para>This situation is common on web servers.  Many people
> +             set up a FreeBSD web server and forget to rotate the log
> +             files.  The access log fills up <filename>/var</filename>.
> +             The new administrator deletes the file, but the system
> +             still complains that the partition is full.  Stopping and
> +             restarting the web server program would free the file,
> +             allowing the system to release the disk space.  To prevent
> +             this from happening, set up &man.newsyslog.8;.</para>
                                    ^
                never delete such file, but empty it by copying /dev/null
                to it (cp /dev/null logfile) or
> +         </answer>
> +       </qandaentry>

Cyrille.
-- 
Cyrille Lefevre                 mailto:clefevre@citeweb.net
Comment 5 wouter 2001-11-08 01:44:24 UTC
[...] but empty it by copying /dev/null to it (cp /dev/null logfile) [...]

Wouldn't it be easier just HUP syslogd?