From: Nick Holloway (alfie@dcs.warwick.ac.uk)
Date: 04/28/93


From: alfie@dcs.warwick.ac.uk (Nick Holloway)
Subject: Unremoveable directories...
Date: Wed, 28 Apr 1993 12:34:53 GMT

I had a problem occur again that I would like to track down. The problem
is that it seems to be possible to get a directory into a state where
the kernel thinks that it is still in use, but isn't.

I was playing around with configuring Perl, and was killing it when it
went haywire (my fault for moving utilities around). I decided it was
time to pack it in, and decided to 'rm -fr' the Perl source tree for now.

However, the temporary directory 'UU' couldn't be removed due to it
being busy (EBUSY). This is expected if it is the cwd of another
process but that wasn't the case. There were few processes running,
and none were in this directory. When this has happened before, I have
painstakingly looked at the open fd's, cwd's in the /proc directory --
but found nothing.

It looks like a process has exited without the count being decremented on
the relevant inode. This is with Linux 0.99.7, and the actual directory
was in the ext2fs from that kernel (0.2e?). I plan to upgrade to Linux
0.99.9 and ext2fs 0.3 when I get a half hour spare, but can anybody tell
me how I can try and diagnose the problem if I can provoke it again.

However, the behaviour of rmdir(2) may want to be changed. I have been
used to the SunOS behaviour, and it seems rational. Firstly, you may
find it a pain that you cannot remove your own directory just because
someone has cd'ed into it. Secondly, the situation is more like that
of open files. When a file is unlinked, if a process still has the
inode open, the inode (and the blocks) remain used. If a directory is
removed, then if the inode is in use (count > 0), then it remains --
it is just not possible to access the "." and ".." entries. (Try this:
"mkdir /tmp/alfie; cd /tmp/alfie; rmdir /tmp/alfie; /bin/pwd").

In fact, the SunOS manual page tells me what I had guessed as the method
of operation (and more succinctly).

       If the directory's link count becomes zero, and no process
       has the directory open, the space occupied by the direc-
       tory is freed and the directory is no longer accessible.
       If one or more processes have the directory open when the
       last link is removed, the `.' and `..'. entries, if pre-
       sent, are removed before rmdir() returns and no new
       entries may be created in the directory, but the directory
       is not removed until all references to the directory have
       been closed.

I can't lay my hands on a POSIX draft at the moment, so I don't know
what it says about the behaviour of rmdir(2).

Having a quick look at the kernel source, it seems that the current
behaviour was in the Minix fs, and all other fs's have taken it up.

If a particular fs were changed, then I guess that the relevant fsck would
have to be able to deal with empty unlinked directories existing, and just
remove them (no point in adding '.' and '..' just to stick in lost+found).