Subject: Re: Defragmenting a NetBSD drive
To: Simon Burge <simonb@netbsd.org>
From: Brian C. Grayson <bgrayson@orac.ece.utexas.edu>
List: netbsd-ports
Date: 09/15/1999 00:30:43
On Wed, Sep 15, 1999 at 11:22:05AM +1000, Simon Burge wrote:
> Hubert Feyrer wrote:
> 
>> In article <199909022338.TAA00666@pzero.sandelman.ottawa.on.ca> you wrote:
>>>   The file system doesn't need it. It was designed to work for long periods.
>>>   About the only thing that may be needed is that directories that get used
>>> a lot, e.g. /var/spool/mqueue, etc. may need to be deleted and rebuilt to
>>> make them smaller, but that can be done with a shell script.
>> 
>> Wasn't this problem solved with the truncate(2) system call?
> 
> Not according the the man-page:
> 
> 	[EISDIR]      The named file is a directory.
> 
> If indeed it has been fixed, the doco needs updating :)

  To make a long story short, if one creates N files in a
directory, and then deletes N-1 of them, there is no guarantee
that the directory entry for the remaining file is in the first
block of the directory.  In fact, if it was the last file
created, it will be in the last block of the directory.  So
calling truncate(2) on a directory (if it were allowed) would
likely cause FS corruption i.e. orphaned files that can no
longer be reached through the namespace. 

  To see this for yourself:
> mkdir /tmp/corr
> cd /tmp/corr
# Make some files with really long names, to force the directory
# to take up at least two 512-byte blocks.
> touch `printf "%100s\n" a b c d e f g h | tr ' ' '_'`
> rm *[a-g]
> ls -la	# See that . is 1024 bytes.
> od -c .	# See that the only valid entry, for ___....___h,
 		# is at offset 0x350 or so, that is, in the _second_
		# 512-byte block, not the first.

  It seems possible (to me) to add re-crunching support to either
the kernel, or a tool that works on unmounted filesystems.  If
it's worth the effort....

  Brian