29

On Linux, when you a create folder, it automatically creates two hard links to the corresponding inode. One which is the folder you asked to create, the other being the . special folder this folder.

Example:

$ mkdir folder
$ ls -li
total 0
124596048 drwxr-xr-x    2 fantattitude  staff    68 18 oct 16:52 folder
$ ls -lai folder
total 0
124596048 drwxr-xr-x  2 fantattitude  staff   68 18 oct 16:52 .
124593716 drwxr-xr-x  3 fantattitude  staff  102 18 oct 16:52 ..

As you can see, both folder and .'s inside folder have the same inode number (shown with -i option).

Is there anyway to delete this special . hardlink?

It's only for experimentation and curiosity. Also I guess the answer could apply to .. special file as well.

I tried to look into rm man but couldn't find any way to do it. When I try to remove . all I get is:

rm: "." and ".." may not be removed

I'm really curious about the whole way these things work so don't refrain from being very verbose on the subject.

EDIT: Maybe I wasn't clear with my post, but I want to understand the underlying mechanism which is responsible for . files and the reasons why they can't be deleted.

I know the POSIX standard disallows a folder with less than 2 hardlinks, but don't really get why. I want to know if it could be possible to do it anyway.

  • 11
    Possible duplicate of Why can't I remove the '.' directory? – Stephen Kitt Oct 18 '16 at 15:13
  • @StephenKitt Please see my edit. – Fantattitude Oct 18 '16 at 15:27
  • 1
    I've retracted my vote, let's see how the voting plays out... – Stephen Kitt Oct 18 '16 at 15:38
  • 2
    Both are needed for relative paths. why would you want to remove these (other than plain curiosity)? – HalosGhost Oct 18 '16 at 16:00
  • @HalosGhost I'm just being very curious haha, exploring the limitations of the system and how and why it was designed this way. – Fantattitude Oct 18 '16 at 16:04
46

It is technically possible to delete ., at least on EXT4 filesystems. If you create a filesystem image in test.img, mount it and create a test folder, then unmount it again, you can edit it using debugfs:

debugfs -w test.img
cd test
unlink .

debugfs doesn't complain and dutifully deletes the . directory entry in the filesystem. The test directory is still usable, with one surprise:

sudo mount test.img /mnt/temp
cd /mnt/temp/test
ls

shows only

..

so . really is gone. Yet cd ., ls ., pwd still behave as usual!

I'd previously done this test using rmdir ., but that deletes the directory's inode (huge thanks to BowlOfRed for pointing this out), which leaves test a dangling directory entry and is the real reason for the problems encountered. In this scenario, the test folder then becomes unusable; after mounting the image, running ls produces

ls: cannot access '/mnt/test': Structure needs cleaning

and the kernel log shows

EXT4-fs error (device loop2): ext4_lookup:1606: inode #2: comm ls: deleted inode referenced: 38913

Running e2fsck in this situation on the image deletes the test directory entirely (the directory inode is gone so there's nothing to restore).

All this shows that . exists as a specific entity in the EXT4 filesystem. I got the impression from the filesystem code in the kernel that it expects . and .. to exist, and warns if they don't (see namei.c), but with the unlink .-based test I didn't see that warning. e2fsck doesn't like the missing . directory entry, and offers to fix it:

$ /sbin/e2fsck -f test.img
e2fsck 1.43.3 (04-Sep-2016)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Missing '.' in directory inode 30721.
Fix<y>?

This re-creates the . directory entry.

  • Very interesting! Thank you! So the . folder is really existing inside the FS and tools expect it to work properly. – Fantattitude Oct 18 '16 at 15:51
  • Really nice of you, I don't know Linux and its FS enough to find this kind of infos myself so I'm very thankful you take time to answer me :) – Fantattitude Oct 18 '16 at 15:54
  • 3
    Can you try changing "rmdir" (which actually removes the inode) to "unlink" (which only removes the directory entry). It appears to leave a mostly-functioning directory (no errors on mount or ls). I haven't seen if other problems arise. – BowlOfRed Oct 18 '16 at 17:43
  • @BowlOfRed thank you very much, that is a very good point — so my rmdir . was actually destroying test and leaving that as a dangling directory entry, which you'd expect to cause issues. I'll check with unlink and update my answer! – Stephen Kitt Oct 18 '16 at 18:21
  • 1
    @GiacomoCatenazzi not directly, permissions and ownership are stored in the inode, not the directory entry. – Stephen Kitt Oct 19 '16 at 7:40
5

There is no way to remove this directory entry. The . entry means "this directory", the .. entry means "this directory's parent directory". They're not actually hard links, that's just how the directory structure gets created / represented.

  • I know about that, I'm just curious if it's possible since they seem to be hardlinks. If they are not why would they add up to the hard link count of the inode? – Fantattitude Oct 18 '16 at 15:06
  • 3
    > They're not actually hard links, that's just how the directory structure gets created / represented. Also, duplicate. unix.stackexchange.com/questions/289385/… – Xalorous Oct 18 '16 at 15:11
  • @Xalorous And so what exactly represents these special files, if they are not hardlinks, what are they? They exist so they must be somewhere, except if they just get shown by ls or other tools automatically which doesn't seem realistic to me. – Fantattitude Oct 18 '16 at 15:18
  • @Fantattitude they are the how the folder represents itself to implement the POSIX requirement that rmdir not be able to remove the PWD. – Xalorous Oct 18 '16 at 15:24
  • 1
    In traditional Unix filesystems they're real hard links. They're synthesized on the fly by the driver for other filesystems. – Barmar Oct 19 '16 at 18:37
2

As described in Lion's Notes on the Unix 6 Source Code early Unix had a disk file where both files and directories were represented on the disk by inode structures. There was a special bit that indicated that the file contents were a directory. Each inode had a link to its owning inode that allowed a file to know what directory it was in. The exception was the '/' directory which owned itself. There was also a link to contents. If an inode had no contents it could be returned to the free list. Since a directory was just a blessed file even an empty directory had to have contents to keep it from being garbage collected. Thus the .. was the inode's link to the parent inode and the . was there to indicate the directory still was usable. rmdir (by calling unlink) could remove the . directory if there were no other contents and the inode would then move to the free list when there were no more references to it.

0

As the 'possible duplicate of' post's answer says, the POSIX standard specifies that if rmdir attempts to remove the current directory, it shall fail.

With anything you build you have to have a foundation. It's hard to define relative paths without a way to say 'here'. So the '.' is defined as 'here'.

Also, you can remove 'dot' and 'dot dot'. Write your own OS that does not define them. Though Unix (and by extension Mac OSX), Linux, and even MS DOS and Windows all use dot and dotdot.

TL;DR - 'dot' is in the definition of the OS.

  • This answer is good mostly for the TL;DR. – Joshua Oct 19 '16 at 16:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.