WelcomeWelcome | FAQFAQ | DownloadsDownloads | WikiWiki

Author Topic: How much space does a symlink consume?  (Read 81 times)

Offline Rich

  • Administrator
  • Hero Member
  • *****
  • Posts: 11694
How much space does a symlink consume?
« on: December 13, 2024, 12:24:15 AM »
How much space does a symlink consume?

That is a question that has come up on occasion, but has never really
received precise answer. Only  "not much"  or  "a few hundred bytes".

I will attempt to provide some insight on symlink behavior, inode use, and
storage block use..

We'll start with /tmp which is in the RAM based rootfs.
Get a count of inodes in use:
Code: [Select]
tc@E310:/tmp$ busybox df -i /tmp
Filesystem              Inodes      Used Available Use% Mounted on
rootfs                 1026040     47284    978756   5% /

Create a directory containing 4 symlinks:
Code: [Select]
tc@E310:/tmp$ mkdir symlinks
tc@E310:/tmp$ cd symlinks/
tc@E310:/tmp/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/NOTICE .
tc@E310:/tmp/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/tce.installed/libreoffice .
tc@E310:/tmp/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/uno .
tc@E310:/tmp/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/xid-fullscreen-on-all-monitors .

Get another count of inodes in use:
Code: [Select]
tc@E310:/tmp/symlinks$ busybox df -i /tmp
Filesystem              Inodes      Used Available Use% Mounted on
rootfs                 1026040     47289    978751   5% /

Every directory entry consumes an inode. Creating 1 directory plus 4 links gives us:
Code: [Select]
tc@E310:/tmp/symlinks$ calc 47289-47284
5
Just as expected, 1 inode for each created entry.

Running stat on the directory and the symlinks:
Code: [Select]
tc@E310:/tmp/symlinks$ stat -c "Inode=%i Blocksize=%B Blocks=%b Len=%s Name=%N" ../symlinks
Inode=10075218 Blocksize=512 Blocks=0 Len=120 Name='../symlinks'
tc@E310:/tmp/symlinks$ stat -c "Inode=%i Blocksize=%B Blocks=%b Len=%s Name=%N" ../symlinks/*
Inode=10074587 Blocksize=512 Blocks=0 Len=56 Name='../symlinks/NOTICE' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/NOTICE'
Inode=10075229 Blocksize=512 Blocks=0 Len=59 Name='../symlinks/libreoffice' -> '/tmp/tcloop/libreoffice/usr/local/tce.installed/libreoffice'
Inode=10074588 Blocksize=512 Blocks=0 Len=61 Name='../symlinks/uno' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/uno'
Inode=10075230 Blocksize=512 Blocks=0 Len=88 Name='../symlinks/xid-fullscreen-on-all-monitors' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/xid-fullscreen-on-all-monitors'
The directory and the symlinks each used 1 inode and no additional storage.

Now lets try that again with a persistent EXT4 partition.
Get a count of inodes in use:
Code: [Select]
tc@E310:/mnt/sdb2$ busybox df -i /mnt/sdb2
Filesystem              Inodes      Used Available Use% Mounted on
/dev/sdb2               602656        10    602646   0% /mnt/sdb2

Create a directory containing 4 symlinks:
Code: [Select]
tc@E310:/mnt/sdb2$ mkdir symlinks
tc@E310:/mnt/sdb2$ cd symlinks/
tc@E310:/mnt/sdb2/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/NOTICE .
tc@E310:/mnt/sdb2/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/tce.installed/libreoffice .
tc@E310:/mnt/sdb2/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/uno .
tc@E310:/mnt/sdb2/symlinks$ ln -s /tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/xid-fullscreen-on-all-monitors .

Get another count of inodes in use:
Code: [Select]
tc@E310:/mnt/sdb2/symlinks$ busybox df -i /mnt/sdb2
Filesystem              Inodes      Used Available Use% Mounted on
/dev/sdb2               602656        15    602641   0% /mnt/sdb2
So the inode count increased from 10 to 15, or 5, just like last time.

Running stat on the directory and the symlinks:
Code: [Select]
tc@E310:/mnt/sdb2/symlinks$ stat -c "Inode=%i Blocksize=%B Blocks=%b Len=%s Name=%N" ../symlinks
Inode=130305 Blocksize=512 Blocks=8 Len=4096 Name='../symlinks'
tc@E310:/mnt/sdb2/symlinks$ stat -c "Inode=%i Blocksize=%B Blocks=%b Len=%s Name=%N" ../symlinks/*
Inode=130306 Blocksize=512 Blocks=0 Len=56 Name='../symlinks/NOTICE' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/NOTICE'
Inode=130307 Blocksize=512 Blocks=0 Len=59 Name='../symlinks/libreoffice' -> '/tmp/tcloop/libreoffice/usr/local/tce.installed/libreoffice'
Inode=130308 Blocksize=512 Blocks=8 Len=61 Name='../symlinks/uno' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/uno'
Inode=130309 Blocksize=512 Blocks=8 Len=88 Name='../symlinks/xid-fullscreen-on-all-monitors' -> '/tmp/tcloop/libreoffice/usr/local/lib/libreoffice/program/xid-fullscreen-on-all-monitors'
The behavior is a little different here.

Creating the directory uses an additional 4k block of storage. possibly
used to store directory entries.

The first 2 symlinks only use 1 inode each.

The second 2 symlinks each use 1 inode plus a 4k block of storage. This
is due to the length of the paths they point to, 61 and 88 characters
respectively. This is explained by:
Quote
4.2. The Contents of inode.i_block

Depending on the type of file an inode describes, the 60 bytes of storage
in inode.i_block can be used in different ways. In general, regular files
and directories will use it for file block indexing information, and special
files will use it for special purposes.

4.2.1. Symbolic Links

The target of a symbolic link will be stored in this field if the target
string is less than 60 bytes long. Otherwise, either extents or block maps
will be used to allocate data blocks to store the link target.

Found here:
https://docs.kernel.org/filesystems/ext4/dynamic.html#the-contents-of-inode-i-block

Why the RAM based filesystem appears to be so much more space efficient, I don't know.