chris@umcp-cs.UUCP (Chris Torek) (07/25/86)
In article <2517@umcp-cs.UUCP> I wrote: >... it may help to think of a `bizarre bazzar' Eep! That should be `bizarre bazaar'. Thanks to Jim Shankland, rtech!jas, for spotting this. Now, to make this message otherwise productive, I shall follow a suggestion from Doug Hosking, convex!hosking, and explain a bit. I have added net.unix since this has nothing to do with a 4BSD bug. >Ai! You do NOT want to `unlink' a directory. Use `rmdir'! Why not? I will have to explain a bit about the file system structure. (Incidentally, the mkdir and rmdir system calls are specific to 4.2BSD and derivatives. Other systems must use careful fork/exec sequences to run the mkdir and rmdir programs.) Every file in the Unix file system---and a directory is just a file, albeit a rather special one---is represented by one `inode' and one or more names (directory entries). In a sense, the inode *is* the file; each name is a `link' to this inode. An ordinary file may have anywhere from one to several thousand links (the exact limit is system-dependent), but a directory never has any fewer than two. Every directory has at least two names. Suppose you start in /usr/tmp and do a `mkdir x'. What are the two links to x? They are `/usr/tmp/x' (a directory entry in /usr/tmp) and `/usr/tmp/x/.' (a directory entry in /usr/tmp/x). This might seem rather odd at first: how can a directory name itself? It is not hard: you first create `/usr/tmp/x', a completely empty diretory, then link `/usr/tmp/x/.' to `/usr/tmp/x'. All `link' does is take its first name and turn it into an inode (the file itself), then make the second name point to that inode. You need also link `/usr/tmp' to `/usr/tmp/x/..' to make a properly formed directory. `mkdir' (the program and the system call) does all this properly; and there is no other way for anyone except the super-user to create a directory. Here is where the trouble creeps in. All `unlink' does is take the name it is given, convert it to an inode, and remove the name. If the name was the last link to that inode, the file itself is destroyed as well; if not, it is left intact and may still be accessed by its other name(s). So what happens if you unlink a directory? Well, if it is completely empty, it goes away and everything is fine. However, if it still has `.' and `..' in it, things are not so good. The `.' link to the directory itself still exists, so the file that is the directory is not deleted. The name `/usr/tmp/x' *is* deleted, and that leaves us with a pretty problem: how can we get rid of that last `.' and `..'? The answer is that we cannot. That directory will stick around forever. Worse, it has in it another name for, or link to, /usr/tmp, which means that that too cannot be deleted. Of course, fsck (which does not use the regular file system mechanisms) can clean this up, but this does essentially require a system shutdown. For this reason, again, only the super-user may unlink a directory. Ordinary processes must use rmdir (the program or the system call). -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu