Linux Kernel (Ядро линукса) (часть 2)


Стандартный анализ пути

Когда флаг lookup parent сброшен, функция iink_path_waik выполняет следующие действия:
1. Инициализирует локальную переменную lookup fiags значением nd->fiags.
2. Пропускает все косые черты , предшествующие первому элементу пути.
3. Если оставшаяся часть пути пуста, возвращает ноль. В структуре nameidata поля dentry и mnt указывают на объекты, относящиеся к последнему обработанному элементу оригинального пути.
4. Если значение в поле depth дескриптора nd положительно, функция устанавливает флаг lookup follow в локальной переменной lookup fiags
5. Выполняет цикл, в котором путь, переданный в параметре паше, разбивается на элементы (косые черты интерпретируются как разделители имен файлов).
6. Для каждого выделенного элемента эта функция извлекает адрес объекта "индексный дескриптор” последнего обнаруженного элемента из nd->
dentry->d_inode. На первом проходе цикла индексный дескриптор относится к каталогу, с которого должен начаться анализ пути.
7. Убеждается, что у последнего найденного элемента, хранящегося в индексном дескрипторе, разрешено выполнение (в Unix можно просмотреть записи каталога только в том случае, если он помечен как исполняемый). Если индексный дескриптор имеет собственный метод permission, функция выполняет его; в противном случае она вызывает функцию exec_permission_iite, которая проверяет права доступа, хранящиеся в поле i mode объекта индексный дескриптор”, и привилегии текущего процесса. В обоих случаях, если последний выделенный элемент не разрешает выполнение, функция link path waiko прерывает цикл и возвращает сообщение об ошибке.
8. Рассматривает следующий найденный элемент пути. По имени элемента функция вычисляет 32-битовое хеш-значение, которое будет использовано при просмотре хеш-таблицы кэша элементов каталога.
9. Если за косой чертой, завершающей имя анализируемого элемента пути, непосредственно следует какое-то количество косых черт, игнорирует их все.
10. Если анализируемый элемент является последним в исходном пути, переходит к шагу 6.
11. Если в качестве элемента пути указана одиночная точка (”.”), функция переходит к следующему элементу. Точка указывает на текущий каталог и не имеет никакого эффекта внутри пути.
12. Если в качестве элемента пути указаны две точки (”.”), функция пытается перейти в родительский каталог:
• если последний обработанный каталог в пути является корневым каталогом процесса (nd->dentry равно current->fs->root, a nd->mnt равно current->fs->rootmnt), то переход вверх по дереву каталогов не разрешен. Функция вызывает foiiow mount о для последнего проанализированного элемента пути и переходит к следующему элементу;
• если последний обработанный каталог в пути является корневым каталогом фаЙЛОВОЙ системы nd->mnt (nd->dentry paBHO nd->mnt->mnt_root), а файловая система nd->mnt не смонтирована поверх другой файловой системы (nd->mnt равно nd->mnt->mnt_parent), то файловая система nd->mnt обычно3 является корневой системой пространства имен. В таком случае переход вверх по дереву невозможен, и функция вызывает
foiiow mount () для последнего проанализированного элемента пути и переходит к следующему элементу;
• если последний обработанный каталог в пути является корневым каталогом файловой системы nd->mnt, и она смонтирована поверх другой файловой системы, требуется переключение файловых систем. Обсуждаемая фуНКЦИЯ записывает В nd->dentry значение В nd->mnt->mnt_ mountpoint, а в nd->mnt значение nd->rnnt->mnt_parent, после чего переходит к шагу 20 (вспомним, что на одной точке монтирования может быть смонтировано несколько файловых систем);
• если последний обработанный каталог в пути не является корневым каталогом смонтированной файловой системы, то функция должна просто подняться в родительский каталог. Она записывает в nd->dentry значение nd->dentry->d_parent, вызывает foiiow_mount для родитель- ского каталога и переходит к следующему элементу.
Функция foiiow mount Проверяет, является ЛИ nd->dentry точкой монтирования какой-нибудь файловой системы (nd->dentry->d_mounted больше нуля). В таком случае она вызывает lookup mnt для поиска корневого каталога смонтированной файловой системы в кэше элементов каталога и обновляет nd->dentry и nd->mnt адресами объектов, соответствующих смонтированной файловой системе; затем она повторяет всю операцию (на одной точке монтирования может быть смонтировано несколько файловых систем). В сущности, ВЫЗОВ функции foiiow mount при переходе вверх к родительскому каталогу необходим, потому что процесс мог начать анализ пути с каталога, входящего в файловую систему, скрытую другой, смонтированной на родительском каталоге.
13. Имя элемента— не и не В этом случае функция должна искать его в кэше элементов каталога. Если файловая система предоставляет собственный метод d hash элемента каталога, функция вызывает его для изменения хеш-значения, вычисленного ранее на шаге 8.
14. Устанавливает флаг lookup continue в поле nd->fiags, чтобы обозначить присутствие следующего элемента, подлежащего анализу.
15. Вызывает функцию do iookupO, чтобы вычислить объект элемент каталога”, связанный с данным родительским каталогом (nd->dentry) и именем файла (обрабатываемым элементом пути). Вызванная функция вначале вызывает d iookup для поиска объекта элемент каталога”, принадлежащего элементу пути, в кэше элементов каталога. Если такого объекта нет, функция do iookup вызывает reai iookup . Последняя считывает каталог с диска, вызывая метод lookup индексного дескриптора, создает новый объект элемент каталога” и заносит его в кэш элемен
тов каталога. Затем она создает новый объект индексный дескриптор” и вставляет его в кэш индексных дескрипторов.
В некоторых случаях эта функция может сразу найти требуемый индексный дескриптор в кэше индексных дескрипторов. Это бывает, когда элемент является последним в пути и не ссылается на каталог, у соответствующего файла есть несколько жестких ссылок, и наконец, к файлу недавно обращались по жесткой ссылке, отличной от той, что используется в данном пути.
В конце данного шага поля dent г у и mnt локальной переменной next будут, соответственно, указывать на объект элемент каталога” и объект, представляющий смонтированную файловую систему, соответствующие элементу пути, обрабатываемому в этом цикле.
16. Вызывает функцию foiiow mountо, чтобы проверить, ссылается ли только что обработанный элемент пути (next.dentry) на каталог, являющийся ТОЧКОЙ монтирования какой-нибудь файловой системы (next.dentry-> d_mounted больше нуля). Функция follow_mount обновляет next.dentry И next.mnt так, что они указывают на объект элемент каталога” и объект, представляющий самую верхнюю” файловую систему, смонтированную на каталоге, соответствующем данному элементу пути
17. Проверяет, ссылается ли только что обработанный элемент пути на символьную ссылку (next. dentry->d_inode имеет собственный метод foiiow iink). Мы обсудим этот случай далее в разд. "Анализ символьных ссылок".
18. Проверяет, ссылается ли только что обработанный элемент пути на каталог (next. dentry->d_inode имеет собственный метод lookup). Если это не так, функция возвращает код ошибки -enotdir, потому что данный элемент находится где-то в середине оригинального пути.
19. Заносит в nd->dentry значение next.dentry, а в nd->mnt— значение next.mnt, после чего переходит к следующему элементу пути.
20. Итак, обработаны все элементы оригинального пути, кроме последнего. Функция сбрасывает флаг lookup continue в переменной nd->f lags.
21. Если путь заканчивается косой чертой, функция устанавливает флаги
LOOKUP_FOLLOW И LOOKUP_DIRECTORY В ЛОКаЛЬНОЙ Переменной lookup_flags,
чтобы заставить последующие функции интерпретировать последний элемент как имя каталога.
22. Проверяет значение флага lookup parent в переменной lookup fiags. В дальнейшем мы будем предполагать, что флаг сброшен в ноль.
23. Если в качестве последнего элемента пути указана одиночная точка (.), функция заканчивает выполнение и возвращает ноль (нет ошибок). В структуре nameidata, на КОТОруЮ указывает nd, ПОЛЯ dentry И mnt ССЫ- лаются на объекты, относящиеся к предпоследнему элементу пути (любой элемент внутри пути не имеет никакого эффекта).
24. Если в качестве последнего элемента пути указаны две точки ("."), функция пытается перейти в родительский каталог:
• если последний обработанный каталог в пути является корневым каталогом процесса (nd->dentry равно current->fs->root, a nd->mnt равно current->fs->rootmnt), функция вызывает foiiow_mount () для предпоследнего элемента пути и заканчивает выполнение, возвращая ноль (нет ошибки). Поля dentry и mnt ссылаются на объекты, относящиеся к предпоследнему элементу пути, т. е. на корневой каталог процесса;
• если последний обработанный каталог в пути является корневым каталогом файловой системы nd->mnt (nd->dentry равно nd->mnt-> mnt root), и файловая система nd->mnt не смонтирована поверх другой файловой системы (nd->mnt равно nd->mnt->mnt_parent), то переход вверх по дереву невозможен, и функция вызывает foiiow mount о для предпоследнего элемента пути и заканчивает выполнение, возвращая ноль (нет ошибки);
• если последний обработанный каталог в пути является корневым каталогом файловой системы nd->mnt, и она смонтирована поверх другой файловой системы, функция записывает в nd->dentry значение nd->mnt->mnt_mountpoint, а В nd->mnt значение nd->mnt->mnt_parent, ПО- сле чего возобновляет выполнение шага 24;
• если последний обработанный каталог в пути не является корневым каталогом смонтированной файловой системы, то функция записывает В nd->dentry значение nd->dentry->d_parent, вызывает follow_mount() для родительского каталога и заканчивает выполнение, возвращая ноль (нет ошибки). Поля nd->dentry и nd->mnt ссылаются на объекты, относящиеся к элементу, который предшествует предпоследнему элементу пути.
25. Имя элемента— не и не В этом случае функция должна искать его в кэше элементов каталога. Если файловая система реализует собственный метод d hash элемента каталога, функция вызывает его для изменения хеш-значения, вычисленного ранее на шаге 8.
26. Вызывает функцию do iookup , чтобы вычислить объект элемент каталога”, связанный с данным родительским каталогом и именем файла В конце данного шага локальная переменная next содержит ука
затели на объект элемент каталога” и дескриптор смонтированной файловой системы, относящиеся к последнему элементу пути.
27. Вызывает функцию foiiow mountо, чтобы проверить, является ли последний элемент пути точкой монтирования какой-нибудь файловой системы, и, если это так, обновить локальную переменную next, записав в нее адреса объекта элемент каталога” и объекта, представляющего смонтированную файловую систему, которые относятся к корневому каталогу самой верхней” смонтированной файловой системы.
28. Проверяет, установлен ли флаг lookup follow в переменной lookup fiags, И есть ЛИ у объекта индексный дескриптор” next.dentry->d_inode собственный метод foiiow iink. Если это так, значит, элемент является символьной ссылкой, которую следует интерпретировать, как описано в разд. "Анализ символьных ссылок".
29. Элемент не является символьной ссылкой, или данную символьную ссылку не нужно интерпретировать. Тогда функция записывает в поля
nd->mnt И nd->dentry значения, хранящиеся В next.mnt И next.dentгу соответственно. Последний объект элемент каталога” является результатом всей операции анализа.
30. Проверяет nd->dentry->d_inode на равенство null. Это имеет место, когда нет индексного дескриптора, связанного с объектом элемент каталога”, как правило, из-за того, что путь ссылается на несуществующий файл. В таком случае функция возвращает код ошибки -enoent.
31. Индексный дескриптор, связанный с последним элементом пути, существует. Если флаг lookup_directory установлен в переменной iookup_fiags, функция проверяет, есть ли у индексного дескриптора собственный метод (то есть является ли этот элемент пути каталогом). Если нет, то функция возвращает код ошибки -enotdir.
32. Возвращает ноль (нет ошибок). Значения полей nd->dentry и nd->mnt соответствуют последнему элементу пути.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...