The filesystem and archives

INPUT · Slides

A second name on the same contents (`ln`)

01 / 08

What a file really is, is not its name

Until now you have thought of a file as "contents with a name on them". It divides up a little more finely than that.

the name (memo.txt)  | points atthe record of the contents (the inode)  | points atthe actual data

The inode in the middle is the lead part. It has a number, and it holds the size, the permissions, the owner and where the data sits.

The name is no more than a tag pointing at an inode.

~ $ ls -li origin.txt      4 -rw-r--r--  1 learner  learner  6  origin.txt      ^   the inode number

ls -i shows the number, and stat -c %i reads it too.

And you may put as many tags as you like on one inode. That is a hard link.

02 / 08

Leave off the -s and it is a hard link

Making one is almost the same as last lesson, except that you leave off the -s.

~ $ ln origin.txt alias.txt~ $ stat -c '%i %h' origin.txt alias.txt4 24 2

Look at the two numbers.

%i  the inode number  -> 4 for both (the same contents!)%h  the number of names -> 2 (two tags)

The second number from the left in ls -l is that same "number of names". The column that has been showing 1 all this time.

-rw-r--r--  2 learner  learner  6  origin.txt            ^         it has two names

What matters is that neither of them is the real one.

origin.txt -+            +-> inode 4 (the contents)alias.txt  -+

The one made first has no seniority. They are two entirely equal names.

03 / 08

Remove a name and the contents stay

Here is where it is the exact opposite of last lesson.

~ $ ln origin.txt alias.txt~ $ rm origin.txt~ $ cat alias.txthello              <- reads quite happily!

A symbolic link would have broken. A hard link does not.

The reason becomes clear once you know what rm really is.

> rm does not "remove the contents"; it peels off one name.

Afterwards it counts the names left and throws the contents away only when that reaches 0.

rm origin.txt   -> names 2 -> 1 (the contents stay)rm alias.txt    -> names 1 -> 0 (now the contents go)

Which is how "I removed the file and the space did not come back" happens. While another name is left, the contents are alive.

Something can be gone from ls and still be there. Knowing this lets you explain a disk that mysteriously will not empty.

04 / 08

The difference from a symbolic link

Put the two side by side. This table is the crux of the chapter.

symbolic link (ln -s)hard link (ln)
what it isa note with the target on ita second name on the same inode
remove the targetit breaks (lost)fine (the contents stay)
another diskcan point therecannot
a directorycan point at onecannot be made
how ls -l looksan l and a ->just like an ordinary file
the link count (%h)does not growgrows

Remember it by how you tell them apart.

a -> appears in ls -l   -> a symbolic linknothing, but the count is 2 -> a hard link

The weakness of a hard link is that it is hard to spot. It looks like an ordinary file.

In exchange it is sturdy. Move it and it does not break, and losing the target does not matter.

05 / 08

Two things it cannot do

A hard link has two clear limits.

1. It cannot cross to another disk

~ $ ln /etc/passwd there.txtln: there.txt: Cross-device link

Refused. An inode number only means anything inside that one disk. Number 4 means "number 4 on this disk", and has nothing to do with number 4 on another.

In this environment your home and /etc are separate disks. There was talk of df before, and it comes next lesson.

2. It cannot be made on a directory

~ $ ln deep deep2ln: deep2: Operation not permitted

This is to stop a loop forming.

if you could make one...deep/inner/deep2 -> points at deep -> inside it a deep2 -> ...

A road with no end. find would go round for ever, and cp -r would never stop. So it is forbidden.

When you want another name for a directory, use a symbolic link.

06 / 08

Find every name on the same contents

Hard links being hard to spot, learn the tool for finding them.

~ $ find . -samefile origin.txt./origin.txt./alias.txt

-samefile says "show me things pointing at the same inode as this". A relative of the find from chapter 3.

A link count of 2 or more means there are other names.

~ $ stat -c %h origin.txt2                    <- there is another tag somewhere~ $ find . -samefile origin.txt(go and find it)

Look at the count, and if there is one, go and find it.

Here is when you need it. When you removed a file and the space did not come back,

1. look at the number of names with stat -c %h2. if it is 2 or more, find the rest with find -samefile3. only when all are gone does the space come back

Not knowing this leaves you puzzling over "I removed it and nothing changed" for ever.

07 / 08

What mv really is

One last interesting thing.

Within one disk, mv does not move any contents.

mv a.txt b.txt

All it does is swap the tag over. The contents (the inode) stay put and only the name changes.

By hand it goes like this.

~ $ ln a.txt b.txt   put on a second tag~ $ rm a.txt         peel the old tag off

The result is the same as mv a.txt b.txt.

Which is why mv finishes instantly for a file of any size, as long as it stays on one disk.

mv within one disk    instant (swapping a tag)mv to another disk    slow (really copying, then removing)

You may have felt that difference. Moving to a USB stick is slow for exactly this reason.

Today's point, that a name and its contents are separate, explains what you see every day.

08 / 08

Now have a go

This is everything for the lesson.

ln original new-name       make a hard linkstat -c %i name            the inode number (the number of the contents)stat -c %h name            the number of names (the link count)ls -li                     the numbers and counts as a listfind . -samefile name      find names on the same contents

A word on how stat -c is written.

stat -c '%i %h' name     both at once (separated by a space)

-c says "give it to me in this shape". %i and %h are the holes, and the values go in.

In the practice you also try the things that cannot be done on purpose: a hard link to a directory, and a hard link to another disk.

Knowing the shape of the refusal makes "why the -s is needed" stick. Now, have a go.