Вопрос или проблема
Благодаря некоторым хорошим вопросам и ответам здесь и этой странице, я теперь понимаю ссылки. Я вижу, что жесткие ссылки ссылаются на один и тот же индекс узла (inode) под другим именем, а копии являются различными “узлами” с разными именами. В дополнение к этому, мягкие ссылки имеют оригинальное имя файла и путь как их индекс узла, так что если файл перемещен, ссылка «ломается».
Итак, я протестировал то, что я узнал с помощью файла (“saluton_mondo.cpp” ниже), создал жесткую и мягкую ссылки и копию.
jmcf125@VMUbuntu:~$ ls -lh soft hard copy s*.cpp
-rw-rw-r-- 1 jmcf125 jmcf125 205 Авг 27 16:10 copy
-rw-rw-r-- 2 jmcf125 jmcf125 205 Авг 25 13:34 hard
-rw-rw-r-- 2 jmcf125 jmcf125 205 Авг 25 13:34 saluton_mondo.cpp
lrwxrwxrwx 1 jmcf125 jmcf125 17 Авг 27 16:09 soft -> saluton_mondo.cpp
Мне показалось странным, что жесткая ссылка, тем не менее, имеет такой же размер как оригинал и, логически, как копия. Если жесткая ссылка и оригинал используют один и тот же индекс узла, который содержит данные, и различаются только именем файла, разве жесткая ссылка не должна занимать лишь место своего имени, а не 205 байт? Или это размер оригинального файла, который возвращает ls -lh
? Но как тогда я могу узнать, сколько места занимает имя файла? Здесь говорится, что жесткие ссылки не имеют размера. Имя их файла хранится вместе с оригинальным именем файла? Где хранится имя жестких ссылок?
Файл представляет собой индекс узла с метаданными, среди которых список указателей на место, где находятся данные.
Чтобы получить доступ к файлу, вам необходимо связать его с каталогом (подумайте о каталогах как о телефонных книжках, а не о папках), то есть добавить одну или несколько записей в один или несколько каталогов, чтобы ассоциировать имя с этим файлом.
Все эти ссылки, все эти имена файлов указывают на один и тот же файл. Нет такого, который был бы оригиналом, а остальные – ссылками. Все они являются точками доступа к одному и тому же файлу (одинаковый индекс узла) в дереве каталогов. Когда вы получаете размер файла (lstat
системный вызов), вы извлекаете информацию (то самые метаданные, о которых говорилось выше), хранящиеся в индексе узла, не имеет значения, какое имя файла, какую ссылку вы используете для обращения к этому файлу.
В отличие от этого, символические ссылки (symlinks) – это другой файл (другой индекс узла), содержимое которого является путем к целевому файлу. Как и любой другой файл, эти символические ссылки должны быть связаны с каталогом (должны иметь имя), чтобы вы могли получить к ним доступ. Вы также можете иметь несколько ссылок на символическую ссылку, другими словами, символические ссылки могут иметь несколько имен (в одном или нескольких каталогах).
$ touch a
$ ln a b
$ ln -s a c
$ ln c d
$ ls -li [a-d]
10486707 -rw-r--r-- 2 stephane stephane 0 Авг 27 17:05 a
10486707 -rw-r--r-- 2 stephane stephane 0 Авг 27 17:05 b
10502404 lrwxrwxrwx 2 stephane stephane 1 Авг 27 17:05 c -> a
10502404 lrwxrwxrwx 2 stephane stephane 1 Авг 27 17:05 d -> a
Выше номер файла 10486707 является обычным файлом. Две записи в текущем каталоге (одна с именем a
, другая с именем b
) ссылаются на него. Поскольку количество ссылок равно 2, мы знаем, что нет другого имени этого файла в текущем каталоге или любом другом каталоге. Номер файла 10502404 – это другой файл, на этот раз типа символическая ссылка, связанная дважды с текущим каталогом. Его содержимое (цель) – относительный путь “a”.
Обратите внимание, что если 10502404 была связана с другим каталогом, а не с текущим, она обычно указывала бы на другой файл в зависимости от того, как она была доступена.
$ mkdir 1 2
$ echo foo > 1/a
$ echo bar > 2/a
$ ln -s a 1/b
$ ln 1/b 2/b
$ ls -lia 1 2
1:
total 92
10608644 drwxr-xr-x 2 stephane stephane 4096 Авг 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Авг 27 17:26 ../
10504186 -rw-r--r-- 1 stephane stephane 4 Авг 27 17:24 a
10539259 lrwxrwxrwx 2 stephane stephane 1 Авг 27 17:26 b -> a
2:
total 92
10608674 drwxr-xr-x 2 stephane stephane 4096 Авг 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Авг 27 17:26 ../
10539044 -rw-r--r-- 1 stephane stephane 4 Авг 27 17:24 a
10539259 lrwxrwxrwx 2 stephane stephane 1 Авг 27 17:26 b -> a
$ cat 1/b
foo
$ cat 2/b
bar
Файлы не имеют имен, связанных с ними, кроме как в каталогах, которые их связывают. Место, занимаемое их именами, это записи в этих каталогах, оно учитывается в размере файла / использовании диска каталогов.
Вы заметите, что системный вызов для удаления файла – это unlink
. То есть вы не удаляете файлы, вы удаляете их из каталогов, в которых они упоминаются. Как только файл был удален из последнего каталога, в котором была запись на данный файл, этот файл считается уничтоженным (при условии, что никакой процесс не открыл его).
Жесткая ссылка, по сути, является оригинальным файлом. Поэтому размер, который вы видите, соответствует размеру связанного файла. Это мягкие ссылки, которые занимают лишь место своих имен (в каком-то смысле).
Что касается файловой системы, жесткая ссылка и оригинал – это одно и то же, они указывают на один и тот же индекс узла, поэтому сообщается один и тот же размер.
Ответ или решение
Хард ссылки, или жесткие ссылки, создают дополнительное имя для уже существующего файла на файловой системе, связывая новое имя с тем же индексным номером (inode), который использует оригинальный файл. Поэтому, когда вы запрашиваете размер файла (например, с помощью команды ls -lh
), операционная система возвращает размер файла, связанного с его inode, а не размер самого имени файла.
Поскольку хард ссылка фактически является другим именем для того же самого файла, размер, который вы видите в выводе ls
, представляет собой размер файла, к которому указывает данная хард ссылка. Это объясняет, почему размер хард ссылки совпадает с размером оригинального файла. Хард ссылки не занимают дополнительного пространства на диске — они ссылались на одни и те же данные, поэтому в этом смысле считается, что у них нет собственного размера. Если вы создадите несколько хард ссылок на один и тот же файл, каждая из них будет отображать один и тот же размер, так как они все указывают на один и тот же индексный номер.
Напротив, символические ссылки (или софт ссылки) — это отдельные файлы, которые содержат путь к оригинальному файлу в качестве своего содержимого. Эти ссылки занимают место в файловой системе, равное размеру пути, который они хранят, что делает их размером больше, чем просто имя.
Имейте ввиду, что размер, который хард ссылка "показывает", — это просто представление размера оригинального файла, с которым она связана. На уровне файловой системы сама по себе хард ссылка не занимает места, кроме как для хранения имени файла в соответствующей директории. Пространство, занимаемое именем файла или самой ссылкой, не учитывается в размере файла, поскольку это представлено в метаданных директории, которая связывает имя с индексным номером.
Чтобы ответить на ваш вопрос о том, где хранятся имена хард ссылок: имена файлов хранятся в директориях. Каждая директория в файловой системе содержит записи (в виде таблиц), которые связывают имена файлов с их индексными номерами. Таким образом, когда вы обращаетесь к файлу, система проверяет директорию, чтобы найти соответствующее имя и получить его индексный номер, после чего может получить основные данные, связанные с этим файлом.
В заключение, хард ссылки, по сути, являются просто другим именем для уже существующего файла, и поэтому, когда вы проверяете размер, он всегда показывает размер самого файла, к которому ссылаются.