On Unix, typically, a file is some entry in a table of files. There are different sorts of files: regular files, devices, symbolic links, doors, pipes, sockets, directories...
The inode number (which you can see in the output of
ls -i) is the index in that table.
Now, you don't access files by inode but by path. A path is a chain of directory entries. You'll notice we're not talking of folder but of directory here. Because it is what a directory is (think of a phone directory).
A directory is a special kind of file that gives names to a number of inodes. A directory entry is a mapping from a name to an inode.
A given file (an inode) can have more than one name in one directory (just like there can be more than one name at a phone number), and can also have names (entries) in more than one directory. Those are called links, also known as hard links to distinguish from soft links (a slang term for symbolic link, which is a special type of file which is a pointer to a path).
A file (inode) keeps track of the number of links (of entries in any directory) that it has, so that when the number reaches 0 (when it is being unlinked from the last directory it was referenced in), it is deallocated.
That's that number (the number of links) that is displayed in the
ls -l output.
When a non-directory file is created the first time (with the
mknod for some types of files) system calls), it is done by providing a path to the new file (like
"/a/b"). What happens then is a new file and inode is allocated and a new entry is added to the directory associated with the
"a" name in the
"/" root directory. That's the initial link so the link count is one.
More links can be added later on with the
link() system call (the
ln command). And links can be removed with the
unlink() system call (the
You'll notice that the files of type directory generally have a number of links greater or equal to 2.
Now, when you create a directory, you're calling the
mkdir() system call. Something like
mkdir("/a/b"). What it does then is allocate a new file of type directory. In that new directory, it automatically creates two entries:
"." (dot for directory). Which is a link to itself. So the link count is now 1.
".." (for directory's directory). Which is a link to
"/a". So the link count of
"/a" is incremented by one
Then that new directory is linked to
"/a" (an entry is added in
"/a" for it), so its link count is now 2. If a
"/a/b/c" directory is created, because of the
".." entry in
"/a/b/c", the link count of
"/a/b" will become 3.
Most Unices restrict creating further links to a directory because they can cause problematic loops. When they do allow a
link() on a directory, generally only the superuser can do it.
Some filesystems like
btrfs depart from that traditional directory structure. You'll notice that link counts on directories in
btrfs file systems are always one even though those directories do contain a
"." entry with the same inode number as themselves in them.
The fact that the link count is traditionally 2 plus the number of subdirs has its use. For instance, in:
find . -name '*.c' -print
. does not contain subdirs but contains millions of files. By checking the link count of
find can know that there is no subdir. So all
find has to do is read the content of the directory and report the entries that end in
.c (like a
grep '\.c$' on a few megabyte file, no big deal). Otherwise,
find would have to check the type of every single file to see if there are directories to descend into in there (resulting in as many
lstat() system calls). Of course, this kind of optimisation doesn't work on
btrfs (though in modern versions of Linux, the type of files is also stored in the directory entry for some filesystems (including
btrfs) and returned by the
getdents(2) system call used to retrieve the list of entries in a directory, so
lstat is still not necessary).