Why Directory Sizes Differ in ‘ls -l’ Output on XFS File System

dufilesystemslinuxlsxfs

I can't understand why ls -l shows folder size less than block size.

For example:

[user@01 NEW]$ ls -l
total 4
drwxr-xr-x  5 root root   78 Apr 22 00:43 controllers
drwxr-xr-x 14 root root 4096 Apr 22 00:44 schemas
drwxr-xr-x  2 root root   38 Apr 22 00:44 spinner

"controllers" is a directory, and block size is 4096 bytes, so why size is 78 bytes?

[user@01 NEW]$ find controllers/ -type f | wc -l
73

Many files are inside. And du -hs shows that size of this folder is 840 K.

Another strange thing is that ls -s shows that for this two directories allocated 0 blocks:

[user@01 NEW]# ls -ls
total 4
0 drwxr-xr-x  5 root root   78 Apr 22 00:43 controllers
4 drwxr-xr-x 14 root root 4096 Apr 22 00:44 schemas
0 drwxr-xr-x  2 root root   38 Apr 22 00:44 skins

xfs_info:

 xfs_info /
meta-data=/dev/disk/by-uuid/5d87d678-e4cc-445f-b770-4e4c0357faaa isize=256    agcount=4, agsize=393088 blks
         =                       sectsz=512   attr=2
data     =                       bsize=4096   blocks=1572352, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

In ext4 folders size is normal (i.e., equal to block size).

Best Answer

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

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
Related Question