Стандарт SUSv3 требует, чтобы реализация допускала по меньшей мере _POSIX_SYMLOOP_MAX разыменований для каждого компонента символической ссылки имени пути. Указанное значение _POSIX_SYMLOOP_MAX равно 8. Однако до версии ядра 2.6.18 Linux допускала не более пяти разыменований при следовании по цепочке символических ссылок. Начиная с указанной версии, Linux реализует минимальное число разыменований (8), указанное в стандарте SUSv3. Linux допускает также для всего имени пути общее число разыменований, равное 40. Эти пределы необходимы, чтобы избежать очень длинных цепочек из символических и циклических ссылок, вызывающих переполнение стека ядра при их анализе.

Ряд файловых систем UNIX осуществляют оптимизацию, не упомянутую в основном тексте и не показанную на рис. 18.2. Когда общая длина строки, образующей содержимое символической ссылки, достаточно мала для того, чтобы уместиться в той части индексного дескриптора, которая обычно используется для указателей на данные, строка ссылки хранится там. Это позволяет избежать выделения блока на диске, а также ускоряет доступ к информации символической ссылки, поскольку она извлекается вместе с индексным дескриптором файла. Так, например, файловые системы ext2, ext3 и ext4 применяют данный метод для встраивания коротких символических строк в пределах 60 байт, которые обычно применяются для указателей на блоки данных. На практике такая оптимизация может оказаться весьма эффективной. Среди 20 700 символических ссылок в одной системе, исследованной автором, 97 % имели размер 60 байт и менее.

Интерпретация символической ссылки системными вызовами

Многие системные вызовы разыменовывают символические ссылки (следуют по ним) и таким образом работают с файлом, на который указывает ссылка. Отдельные вызовы не разыменовывают, а оперируют непосредственно ссылкой. При рассмотрении каждого системного вызова мы описываем его поведение по отношению к символическим ссылкам. Эти сведения подытожены также в табл. 18.1.

Таблица 18.1. Интерпретация символических ссылок различными функциями

Функция

Следует ли по ссылкам?

Примечания

access()

*

acct()

*

bind()

*

Сокеты домена UNIX имеют имена путей

chdir()

*

chmod()

*

chown()

*

chroot()

*

creat()

exec()

*

getxattr()

lchown()

lgetxattr()

link()

См. раздел 18.3

listxattr()

*

llistxattr()

lremovexattr()

lsetxattr()

lstat()

lutimes()

open()

*

Если не указан флаг O_NOFOLLOW или O_EXCL | O_CREAT

opendir()

*

pathconf()

*

pivot_root()

*

quotactl()

*

readlink()

removexattr()

*

rename()

Ссылки не отслеживаются ни в одном из аргументов

rmdir()

Завершается с ошибкой ENOTDIR, если аргумент является символической ссылкой

setxattr()

*

stat()

*

statfs(), statvfs()

*

swapon(), swapoff()

*

truncate()

*

unlink()

uselib()

*

utime(), utimes()

*

В ряде случаев, когда необходимо обеспечить одинаковое функционирование как для файла, с которым соотносится символическая ссылка, так и для нее самой, применяют взаимоисключающие системные вызовы: один из них разыменовывает ссылку, а второй — нет, причем этот вызов снабжен префиксом в виде буквы l; например: stat() и lstat().

Обычно выполняется следующее: символические ссылки, являющиеся частью имени пути, представляющей каталоги (то есть все компоненты, которые предшествуют завершающему слешу), всегда разыменовываются. Так, в имени пути /somedir/somesubdir/file компоненты somedir и somesubdir всегда будут разыменованы, если являются символическими ссылками, а разыменование компонента file будет зависеть от того, какому системному вызову было передано имя пути.

В разделе 18.11 мы описываем набор системных вызовов, добавленных в версии Linux 2.6.16. Они расширяют функциональность ряда интерфейсов, приведенных в табл. 18.1. Для некоторых из этих системных вызовов можно управлять вариантами обработки символических ссылок с помощью аргумента flags.

Права доступа к файлу и принадлежность символических ссылок

Перейти на страницу:

Похожие книги