Search code examples
linuxfilesystemsinodehardlink

Size of directory .(DOT) does not decrease?


I am studying the linux file system. I had an experiment to explore how linux saves the hard links.

I made 1000 hard links for a file in the same directory. The size of .(DOT) increased to 28672; I remove 500 hard links, the size of .(DOT) did not decrease. (I used "stat ." to check the size.) Why doesn't the size decrease?

This is my experiment: I have a folder named test, which has only one small file testfile and a script, the status was like this:

York:~/test$ ll -li
total 84
7995940 drwxr-xr-x 2 York domain_users  4096 Jul 17 19:20 ./
7995939 drwxr-xr-x 3 York domain_users 69632 Jul 17 19:20 ../
7996494 -rwxrwxrwx 1 York domain_users    94 Jul 17 19:14 copy.sh*
8026281 -rw-r--r-- 1 York domain_users     7 Jul 17 19:17 testfile

York:~/test$ stat .
  File: `.'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fc03h/64515d    Inode: 7995940     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (2060469376/York)   Gid: (2060452353/domain_users)
Access: 2015-07-17 19:20:06.288345960 +0200
Modify: 2015-07-17 19:20:05.420340318 +0200
Change: 2015-07-17 19:20:05.420340318 +0200
 Birth: -

Then I ran the script:

for i in `seq 200000 200999`;
do
  ln testfile "$i"
done 

After that, I got the following result:

York:~/test$ stat .
  File: `.'
  Size: 28672       Blocks: 64         IO Block: 4096   directory
Device: fc03h/64515d    Inode: 7995940     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (2060469376/York)   Gid: (2060452353/domain_users)
Access: 2015-07-17 19:21:25.364862751 +0200
Modify: 2015-07-17 19:21:11.064768884 +0200
Change: 2015-07-17 19:21:11.064768884 +0200
 Birth: -

And I could see that the inode counter is 1001, which was what I expected:

York:~/test$ ll -li testfile 
8026281 -rw-r--r-- 1001 York domain_users 7 Jul 17 19:17 testfile

I used "rm" to remove 500 hard links, I saw:

York:~/test$ ll -li testfile 
8026281 -rw-r--r-- 501 York domain_users 7 Jul 17 19:17 testfile

But the size of the directory did not decrease:

York:~/test$ stat .
  File: `.'
  Size: 28672       Blocks: 64         IO Block: 4096   directory
Device: fc03h/64515d    Inode: 7995940     Links: 2
Access: (0755/drwxr-xr-x)  Uid: (2060469376/York)   Gid: (2060452353/domain_users)
Access: 2015-07-17 19:24:35.138125221 +0200
Modify: 2015-07-17 19:24:35.142125246 +0200
Change: 2015-07-17 19:24:35.142125246 +0200
 Birth: -

My understanding about the directory in file system is like this: For each directory, an inode is allocated for attributions like folder name etc, and also a block of data is used to keep entries for files and directories in that folder. Because each hard link needs one entry, 1000 hard links need more space than a block of data, another data blocks are needed. So the size of the directory .(DOT) increases. Vise versa, if I remove 500 hard links, the size should decrease.

But the experiment showed that the size did not decrease. Where am I wrong?

Thank you in advance!

Best Wishes, York


Solution

  • What you're seeing is correct. Many Linux filesystems never shrink the size of a directory inode; they just blank out the entries for deleted files, allowing them to be reused if more files are added to the directory later. The only way to return the directory to its original size may be to delete it and create a new one with the same name.