4

From http://en.wikipedia.org/wiki/Symbolic_link#Storage_of_symbolic_links

Early implementations of symbolic links stored the symbolic link information as data in regular files. The file contained the textual reference to the link’s target, and an indicator[clarification needed] denoting it as a symbolic link.

This method was slow and an inefficient use of disk-space on small systems. An improvement, called fast symlinks, allowed storage of the target path within the data structures used for storing file information on disk (inodes). This space normally stores a list of disk block addresses allocated to a file. Thus, symlinks with short target paths are accessed quickly. Systems with fast symlinks often fall back to using the original method if the target path exceeds the available inode space. The original style is retroactively termed a slow symlink. It is also used for disk compatibility with other or older versions of operating systems.

  1. Does "allowed storage of the target path within the data structures used for storing file information on disk (inodes)" mean that a fast symlink stores the path of the linked file inside the inode of the fast symlink

    Does a fast symlink, as a file itself, actually only have an inode and has no file content?

    Does a slow symlink, as a file itself, have an inode and some file content which is the target path?

  2. What does "if the target path exceeds the available inode space" mean?

    Is it correct that if a symlink to a file is a fast symlink, if and only if the symlink and the file are on the same file system?

  3. Is there any command that can check if a symlink is a fast or slow one?

  4. When a symlink has file content, what is the command to show the content of the symlink? (So that if a fast symlink doesn't have file content and a slow one has, we can verfiy that.)

5

Does "allowed storage of the target path within the data structures used for storing file information on disk (inodes)" mean that a fast symlink stores the path of the linked file inside the inode of the fast symlink

Yes

Does a fast symlink, as a file itself, actually only have an inode and has no file content?

Depends what you mean by "has file content". No symlinks have file content in the sense that you cannot open() them and read() from them. But in the meaning implied by the text you quoted, "The file contained the textual reference to the link’s target". So, yes, that textual reference can be considered the file's "content".

This content is the same regardless of whether the symlink is a fast symlink or a slow symlink. How and where the filesystem choses to store that information in its on-disk data structures is an implementation detail and does not affect this.

Does a slow symlink, as a file itself, have an inode and some file content which is the target path?

From that same point of view, yes!

What does "if the target path exceeds the available inode space" mean?

Depends on the filesystem and the kind of data structures it used to store inodes and how much spare space is in those data structures and whether they are variable-sized or fixed size. The maximum length of the target path of a symlink before it has to fall back to being stored as a slow symlink is an filesystem implementation detail.

By the way, nothing prevents a particular filesystem from using the same trick to store the contents of a short regular file to save space and disk access.

Is there any command that can check if a symlink is a fast or slow one?

At best, filesystem debugging or dumping tools. And it will be completely dependent on the type of filesystem you are interested in (xfs, ext*, btrfs, etc...)

When a symlink has file content, what is the command to show the content of the symlink? (So that if a fast symlink doesn't have file content and a slow one has, we can verfiy that.)

You can obtain the target path (contents) of a symlink with readlink, but ls -l will work too.

  • By "file content" of a symlink, I mean, viewing a symlink as a file itself, it has its own inode, and the inode will point to some data block. That content of that data block is the "file content" of the symlink. Just like the inode of any ordinary file will point to the content of the file – Tim Jul 31 '14 at 2:31
  • 2
    Except the inode may or may not point to "some data block". It may embed the content directly inside itself if the content is short enough. Or not. Or we may be talking about filesystem types like jffs2 or tmpfs that have no concept of "data block" in the first place because the filesystem structure is not block-based. All of this is implementation details, completely up to the whim of each filesystem implementor, and makes no difference as long as the interface presented to the kernel follows POSIX. – Celada Jul 31 '14 at 2:35
  • 3
    For filesystems like ext[234], you can do lstat() and check if stat.st_blocks is 0. For short targets (< 60 bytes), it will be 0, denoting a fast symlink. For longer targets, it will be nonzero (typically 4). ls -s will show the st_blocks field. – Mark Plotnick Aug 1 '14 at 18:10
3

From the linked inode wiki page:

A file system relies on data structures about the files, beside the file content. The former is called metadata—data that describes data. Each file is associated with an inode, which is identified by an integer number, often referred to as an i-number or inode number.

Inodes store information about files and directories (folders), such as file ownership, access mode (read, write, execute permissions), and file type. On many types of file system implementations, the maximum number of inodes is fixed at file system creation, limiting the maximum number of files the file system can hold. A typical allocation heuristic for inodes in a file system is one percent of total size.

The inode number indexes a table of inodes in a known location on the device; from the inode number, the file system driver portion of the kernel can access the contents of the inode, including the location of the file allowing access to the file. A file's inode number can be found using the ls -i command. The ls -i command prints the i-node number in the first column of the report.

As noted above, ls -i can give you the inode number - which is likely where the link is. ls -l will provide you a path to the link's target. The latter will require a stat() syscall, but, because a file's directory listing - its dentry - will contain its inode number and filename, the ls -i form likely will not. At least, filesystem depending, it will likely not require a stat() for any file object other than the containing directory.

You can modify the way ls reports on links with the following options, as specified by POSIX:

-F - Do not follow symbolic links named as operands unless the -H or -L options are specified. Write a slash ( '/' ) immediately after each pathname that is a directory, an asterisk ( '*' ) after each that is executable, a vertical bar ( '|' ) after each that is a FIFO, and an at sign ( '@' ) after each that is a symbolic link. For other file types, other symbols may be written.

-H - If a symbolic link referencing a file of type directory is specified on the command line, ls shall evaluate the file information and file type to be those of the file referenced by the link, and not the link itself; however, ls shall write the name of the link itself and not the file referenced by the link.

-L - Evaluate the file information and file type for all symbolic links (whether named on the command line or encountered in a file hierarchy) to be those of the file referenced by the link, and not the link itself; however, ls shall write the name of the link itself and not the file referenced by the link. When -L is used with -l, write the contents of symbolic links in the long format (see the STDOUT section).

And how can the link be a fast one? From the same linked wiki page:

Inlining

It can make sense to store very small files in the inode itself to save both space (no data block needed) and look-up time (no further disk access needed). This file system feature is called inlining. The strict separation of inode and file data thus can no longer be assumed when using modern file systems.

If the data of a file fits in the space allocated for pointers to the data, this space can conveniently be used. E.g. ext2 stores the data of symlinks (typically file names) in this way, if the data is no more than 60 bytes ("fast symbolic links").

Ext4 has a file system option called inline_data that, when enabled during file system creation, allows ext4 to perform inlining. As an inode's size is limited, this only works for very small files.

It is the above method that I believe the other excellent answer here refers to as the same trick...

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.