views:

575

answers:

5

I recently ran out of disk space on a drive on a FreeBSD server. I truncated the file that was causing problems but I'm not seeing the change reflected when running df. When I run du -d0 on the partition it shows the correct value. Is there any way to force this information to be updated? What is causing the output here to be different?

A: 

Does df --sync work?

mercutio
A: 

@mercutio Doesn't seem to work on FreeBSD.

pix0r
+2  A: 

This probably centres on how you truncated the file. du and df report different things as this post on unix.com explains. Just because space is not used does not necessarily mean that it's free...

Stephen Darlington
A: 

@Stephen you were right. What happened was I truncated the file, but there were still file handles open pointing to it so somehow the system was not realizing the size had changed. In this case it was an Apache logfile. Once Apache was restarted, the df output was consistent with du output.

pix0r
It is possible that what you were witnessing was a time lag due to the 'softupdates' flag in the filesystem. When softupdates are in effect, there can be a time delay between an action that results in file metadata changes and when those changes are actually committed to disk.
nsayer
+1  A: 

In BSD a directory entry is simply one of many references to the underlying file data (called an inode). When a file is deleted with the rm(1) command only the reference count is decreased. If the reference count is still positive, (e.g. the file has other directory entries due to symlinks) then the underlying file data is not removed.

Newer BSD users often don't realize that a program that has a file open is also holding a reference. The prevents the underlying file data from going away while the process is using it. When the process closes the file if the reference count falls to zero the file space is marked as available. This scheme is used to avoid the Microsoft Windows type issues where it won't let you delete a file because some unspecified program still has it open.

An easy way to observe this is to do the following

cp /bin/cat /tmp/cat-test
/tmp/cat-test &
rm /tmp/cat-test

Until the background process is terminated the file space used by /tmp/cat-test will remain allocated and unavailable as reported by df(1) but the du(1) command will not be able to account for it as it no longer has a filename.

Note that if the system should crash without the process closing the file then the file data will still be present but unreferenced, an fsck(8) run will be needed to recover the filesystem space.

Processes holding files open is one reason why the newsyslog(8) command sends signals to syslogd or other logging programs to inform them they should close and re-open their log files after it has rotated them.

Softupdates can also effect filesystem freespace as the actual inode space recovery can be deferred; the sync(8) command can be used to encourage this to happen sooner.

Dave C