Why directories size are different in ls -l output on XFS file system?

Solution 1:

The size is 78 bytes because the directory is almost empty. With "directory" I mean the immediate descendant content of that folder, i.e., if you have

.../controllers/
                Class1/Whatever
                      /Resources...
                Class2/Whatever
                      /Resources...

then "controllers" only has three entries (.., Class1 and Class2. I do not know exactly whether or how .. is actually stored).

Even if, on disk, the directory will occupy one whole block, therefore 4K (but see below...), the directory logical size remains 78 bytes, and in many ways it is treated as a file (the XFS white papers refers to it as a directory file). If you create a new object immediately under controllers, I expect that size to increment.

https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/ch07s03s02s02.html

Also, very small directories can be stored inside inodes, thereby occupying zero actual blocks:

Very small files

Most symbolic links and directory files are small files. XFS allows these files to be stored in inodes for increased performance. XFS also uses delayed writes to wait to gather the entire small file in the buffer cache before writing to disk...

To recap, as far as I understand, you can have

  • small directory files stored within inodes ("shortform directories"), occupying zero blocks, and organized as Array.
  • reasonable directory files stored in physical files occupying a block ("block directories")
  • large directory files stored in physical files, occupying an integer multiple of a block, and organized as B-Trees for extra speed.

Testing

The space available inside a XFS inode for a directory file seems to be around 156-157 bytes on my Linux system. When exceeded, a 4K block is used, but releasing space also releases the block, storing back the info into the inode.

mkdir temp

drwxr-xr-x   2 root   root               6 2013-04-22 08:59 temp

touch temp/x; ls -la temp

drwxr-xr-x   2 root   root              14 2013-04-22 09:00 temp

mv temp/x temp/{ 100 x's }

drwxr-xr-x   2 root   root             113 2013-04-22 09:01 temp

{ 130 x's }

drwxr-xr-x   2 root   root             143 2013-04-22 09:02 temp

{ 140 x's }    
drwxr-xr-x   2 root   root             153 2013-04-22 09:02 temp

{ 146 x's }
drwxr-xr-x   2 root   root            4096 2013-04-22 09:03 temp

{ 142 x's }
drwxr-xr-x   2 root   root             155 2013-04-22 09:03 temp