ФАЙЛОВАЯ СИСТЕМА OS UNIX
Понятие файловой системы
Файловая система - это концептуальное понятие OS UNIX, которое
определяет логическую организацию пространства внешней памяти. Она
может быть образована на любом физическом или виртуальном устройстве
внешней памяти с прямым доступом, например, жестком диске, логическом
разделе жесткого диска, гибком диске, сменном пакете дисков. Разделение
пространства внешней памяти на физические или виртуальные носители
данных в OS UNIX отражается логическим разделением внешней памяти на
файловые системы.
Файловая система OS UNIX обеспечивает разбиение пространства физической
памяти внешнего устройства на поименованные участки данных - файлы,
гарантирует защиту данных от аппаратных сбоев и несакционированного
доступа, поддерживает единый интерфейс обращения к данным, минимизирует
время обращения к данным. Это основные функции файловой системы.
Строение файловой системы имеет двойственную интерпретацию.
Внутренняя организация файловой системы интерпретируется как последовательность
фиксированных по размеру блоков внешней памяти. Внешнее
представление файловой системы имеет иерархическую структуру с поименованными
узлами, которые обозначают либо файлы данных, либо
каталоги файлов, либо
специальные файлы доступа к устройствам. Внутренняя организация
файловой системы скрыта от пользователя и недоступна при использовании
стандартных средств. Внешний интерфейс файловой системой обеспечен
соответсвующими командами и системными вызовами ядра.
Внутренняя структура файловой системы
Упорядоченную последовательность блоков внутреннего представления
файловой системы можно разделить по функциональному признаку на 5
областей, как показано на следующем рисунке.
Рис. Расположение блоков файловой системы
0 |
1 |
2 |
S |
N |
M |
|
|
|
|
|
- Блок начальной загрузки (блок 0)
- содержит программу начальной загрузки
OS UNIX, которая читает в RAM либо непосредственно программу ядра,
либо более сложный вторичный загрузчик.
- Суперблок (блок 1)
- содержит заголовок файловой системы, который включает информацию о ее размерах
и характеристиках.
- Индексный файл (блоки 2-S)
- содержит индексные дескрипторы (описатели) файлов, характеризующие их
основные атрибуты.
- Область данных (блоки S-N)
- содержит последовательность блоков, используемых для хранения и косвенной
адресации данных.
- Область своппинга (блоки N-M)
- используется диспетчером OS UNIX для перемещения (выталкивания) из RAM
образов пассивных процессов, когда нет достаточных ресурсов для их
выполнения. По мере возможности образы вытолкнутых процессов могут быть
загружены (подкачены) обратно из области своппинга в RAM.
Структура суперблока
В терминах системы программирования C устройство суперблока файловой
системы задает структура struct filsys. Ее основные поля имеют
следующий смысл:
s_isize, s_fsize |
- |
адреса 1-го блока областей данных и своппинга, соответственно; |
s_nfree, s_ninode |
- |
счетчики свободных блоков и индексных
дескрипторов файлов, соответственно; |
s_free[], s_inode[] |
- |
списки адресов свободных блоков и индексных
дескрипторов файлов, соответственно; |
s_tfree, s_tinode |
- |
общее число свободных блоков и индексных
дескрипторов файлов, соответственно; |
s_fblock, s_iblock |
- |
флаги запрета доступа к списку свободных блоков
и индексных дескрипторов файлов во время их
модификации, соответственно; |
s_fmod |
- |
флаг модификации суперблока, устанавливается
при изменениях файловой системы; |
s_ronly |
- |
флаг монтирования, устанавливающий наличие или
отсутствие возможности модификации файловой
системы; |
s_state |
- |
состояние файловой системы, нормальное,
активное или поврежденное, соответственно; |
s_time |
- |
время последней модификации файловой системы; |
s_type |
- |
размер блока файловой системы. |
Индексные дескрипторы файлов
Любой файл файловой системы OS UNIX однозначно специфицирован некоторой
структурой данных, называемой индексным дескриптором или описателем
файла. Индексные дескрипторы файлов имеют фиксированный размер (кратный
размеру блока) и сосредоточены в последовательных блоках индексного
файла. Предельное количество индексных дескрипторов в индексном файле
ограничивает число файлов, которые могут быть созданы в блоках области
данных файловой системы. Целесообразно иметь некоторый избыток индексных
дескрипторов, чтобы уменьшить риск недоиспользования области данных
из-за невозможности создавать файлы, когда размер индексного файла будет
исчерпан. Размер индексного файла задается при создании файловой системы
исходя из среднего размера файла и об'ема пространства внешней памяти, в
котором строится файловая система.
Индексные дескрипторы нумеруются в индексном файле, начиная с нуля.
Для системных нужд зарезервированы два индексных дескриптора с номерами
0 и 1. Индексный дескриптор с номером 0 используется для спецификации
дефектных блоков внешней памяти. Индексный дескриптор номер 1 выделен
для корневого каталога файловой системы. Остальные индексные дескрипторы,
с номерами больше 1, специального назначения не имеют и используются для
спецификации каталогов, обычных или специальных файлов файловой системы.
Логическую организацию индексного дескриптора файла в терминах системы
программирования С отражает структура struct dinode. Ее поля содержат
следующую информацию:
di_mode | - |
тип и код защиты файла; |
di_nlink | - |
число альтернативных имен файла,
равное числу ссылок на данный индексный дескриптор из каталогов
файловой системы; |
di_uid, di_gid | - |
идентификаторы владельца и группы владельца файла,
соответственно, устанавливаются по реальным
идентификаторам владельца и группы владельца
процесса, который создает данный файл; |
di_size | - |
размер файла в байтах; |
di_ctime | - |
дата создания файла; |
di_atime, di_mtime | - |
даты последнего обращения и последней модификации
файла, соответственно; |
di_addr[40] | - |
адресация блоков файла в области данных. |
Содержание полей структуры struct dinode для любого существующего файла
можно контролировать командой ls с ключом -l или системными вызовами
stat и fstat.
Для повышения эффективности обработки данных в файловой системе при
открытии любого файла его индексный дескриптор считывается в
таблицу индексных дескрипторов, которая резидентна в RAM. Резидентный
образ индексного дескриптора файла возвращается в индексный файл после
завершения работы с данным файлом во всех процессах.
Чтобы динамически поддерживать соответствие резидентных копий индексных
дескрипторов с их оригиналами в индексном файле, содержание таблицы
индексных дескрипторов файлов периодически копируется в индексный файл
следящим процессом (демоном) update, который запускается при переходе
OS UNIX в многопользовательский режим. Указанная процедура синхронизации
позволяет минимизировать нарушение корректности файловой системы при
аппаратных сбоях, когда возможность приведения в соответствие индексного
файла и модифицированных резидентных копий индексных дескрипторов будет
потеряна. Хотя в OS UNIX предусмотрены административные средства ремонта
файловой системы, но исправление существенных нарушений может привести к
потере данных.
Тип и код защиты файла
Тип и код защиты файла, а также возможность смены группы и владельца
файла при выполнении, устанавливаются полем di_mode структуры
struct dinode индексного дескриптора файла. Битовый
формат этого поля приведен на следующем рисунке.
Рис. Формат поля di_mode
т и п |
|
б и т ы |
|
к о д з а щ и т ы |
ф а й л а |
|
с м е н ы |
|
o w n e r |
|
g r o u p |
|
o t h e r |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- |
d |
c |
p |
|
s |
s |
t |
|
r |
w |
x |
|
r |
w |
x |
|
r |
w |
x |
|
b |
b |
|
Код защиты предназначен для ограничения несанкционированного доступа к
файлу. Он устанавливается 9-ю младшими битами поля di_mode с маской
0777 и позволяет дифференцировать права доступа к данным файла для 3-х
категорий пользователей:
- владелец файла (owner),
- группа владельца файла (group),
- остальные пользователи (other).
Для каждой категории, OS UNIX предоставляет три разновидности прав доступа:
- по чтению,
- по записи,
- по выполнению.
В пределах каждой категории пользователей права доступа задает тройка битов с масками:
- 0700 - для владельца файла,
- 070 - для группы владельца файла,
- 07 - для остальных пользователей.
Старший бит каждой тройки определяет права доступа по чтению (r), средний - по
записи (w), младший - по выполнению (x). Таким образом, права доступа
любых категорий пользователей устанавливают следующие битовые маски:
- 0444 - доступ по чтению,
- 0222 - доступ по записи,
- 0111 - доступ по выполнению.
Произвольный комбинированный код защиты может быть построен
из базисных прав доступа с помощью операции битовой суммы. Требуемый
код защиты устанавливается при создании файла и может быть изменен
владельцем файла или суперпользователем с помощью команды chmod.
Средняя тройка битов поля di_mode с маской 07000 существенна для
выполняемых файлов. Ее составляют бит несговорчивости (t) и биты смены
владельца или группы владельца (s). Бит несговорчивости (или sticky bit)
задается маской 01000 и может быть установлен для файлов реентерабельных
программ или для каталогов. В первом случае, установка этого бита
обеспечивает сохранение образа разделяемого процедурного сегмента после
завершения всех процессов, выполнявших данную реентерабельную программу.
Во втором случае, установка бита несговорчивости для каталога запрещает
непривилигированным пользователям модифицировать или переименовывать
"чужие" файлы в данном каталоге даже при наличии соответствующих прав
доступа. Бит несговорчивости может быть установлен или снят только
суперпользователем с помощью команды chmod.
Пара битов с маской 06000 устанавливает возможность смены владельца и
группы владельца процесса, который выполняет данный файл на владельца
и группу владельца файла. При этом, бит с маской 04000 разрешает смену
владельца, а бит с маской 02000 - смену группы владельца процесса.
Установка этих битов позволяет рядовому пользователю получить
привилигированные полномочия владельца или группы владельца файла на
время его выполнения.
Старшие 4 бита поля di_mode с битовой маской 0170000 определяют тип
файла в соответствии со следующими масками:
Тип файла задается при его создании. Для создания файла любого типа
может быть использован универсальный системный вызов или команда mknod.
На практике это универсальное средство обычно применяется только для
создания специальных файлов. Для создания файлов
иных типов используют специализированные системные вызовы и команды. В частности,
каталог можно создать системным вызовом или
командой mkdir, а именованный программный канал
- системным вызовом или командой mkfifo. Регулярный
файл может быть создан системным вызовом creat или командной строкой:
$ cat < /dev/null > regular-file-name
которая создает обычный файл с именем regular-file-name нулевой длины.
Для существующего файла содержание поля di_mode можно контролировать с
помощью системного вызова stat. Следующий фрагмент C-кода определяет
тип файла с заданным именем anyfile.
#include <sys/types.h> | |
#include <sys/stat.h> | |
|
main() { | |
struct stat statbuf[1]; |
/* буфер индексного дескриптора файла */ |
|
stat("anyfile", statbuf); |
/* заполнить буфер индексного дескриптора */ |
|
/* анализ типа файла */ |
|
printf("anyfile - "); | |
|
switch( statbuf->st_mode & | S_IFMT ) { |
|
case S_IFREG: |
puts("Регулярный файл"); |
| break; |
case S_IFIFO: |
puts("Именованный программный канал"); |
| break; |
case S_IFCHR: |
puts("Байт-ориентированный спец-файл"); |
| break; |
case S_IFBLK: |
puts("Блок-ориентированный спец-файл"); |
| break; |
case S_IFDIR: |
puts("Каталог"); |
| break; |
default: |
puts("Неклассический файл"); |
| break; |
} |
/* switch */ |
|
|
} |
/* main */ |
Маска типа файла S_IFMT и альтернативы выбора S_IFREG, S_IFIFO, S_IFCHR,
S_IFBLK, S_IFDIR определены в заголовочном файле /usr/include/sys/stat.h
с помощью директивы #define. Этот заголовочный файл содержит набор
макроопределений, необходимых для контроля любых полей структуры
индексного дескриптора и битов поля di_mode системным вызовом stat.
Адресация блоков данных
Расположение файла задается списком адресов блоков области данных
файловой системы. Физическое расположение блоков файла может быть
произвольным, но логически они образуют связную цепочку. Непрерывное
расположение расположение блоков любого файла не является обязательным.
Степень разброса блоков файлов (сегментация файловой системы) влияет
только на время доступа к файлам.
Списковую адресацию блоков файла обеспечивает адресное поле di_addr
структуры struct dinode индексного дескриптора.
Адресное поле di_addr имеет длину 40 байт и может хранить 13
трехбайтовых указателей блоков файла. Эти указатели определяют расположение блоков
файла на основе прямой и косвенной адресации.
Первые 10 указателей адресного поля индексного дескриптора используются
для прямой адресации 10-ти начальных блоков файла. Если размер файла
превышает 10 блоков используется 11-й указатель адресного поля di_addr.
Он содержит адрес первичного косвенного блока из 128 четырехбайтовых
указателей, которые позволяют адресовать еще 128 блоков. Следующий
(12-й) указатель адресного поля индексного дескриптора хранит адрес
вторичного косвенного блока, который может содержать 128 указателей
128-ми первичных косвенных блоков. Вторичный косвенный блок позволяет
дополнительно адресовать еще 1282 блоков данных. Для адресации
блоков больших файлов используют 13-й указатель адресного поля di_addr.
Он содержит адрес третичного косвенного блока, который адресует 128
вторичных косвенных блоков. Трехкратная косвенная адресация позволяет
адресовать дополнительно еще 1283 блоков. Следует отметить,
что ковенные блоки, также как блоки данных файлов принадлежат области
данных файловой системы. Рассмотренный метод адресации блоков в файловой
системе OS UNIX иллюстрирует следующая схема.
Рис. Схема адресации блоков данных
Поле di_addr |
|
Блоки данных |
|
Прямая адресация |
|
----------------------------------------------------> |
|
|
|
|
|
|
Однократная косвенная |
------> |
----------------------------------------> |
|
адресация |
------> |
|
|
|
|
|
|
|
|
|
|
------> |
------> |
|
|
------> |
2-х кратная |
|
|
---------------------------> |
|
:::: |
|
косвенная адресация |
|
|
|
|
|
------> |
------> |
|
|
------> |
|
|
|
|
|
|
|
|
|
|
|
------> |
------> |
|
|
------> |
|
|
------> |
|
:::: |
|
|
|
|
|
------> |
------> |
|
|
------> |
3-х кратная |
|
|
---------------> |
::::::::::::::::: |
косвенная |
|
|
|
|
адресация |
------> |
|
------> |
|
|
------> |
|
------> |
:::: |
|
|
|
|
------> |
------> |
|
|
------> |
|
|
Третичный косвенный блок |
Вторичные косвенные блоки |
Первичные косвенные блоки |
|
Рассмотренный метод адресации позволяет задавать местоположение до
10 + 128 + 1282 + 1283
блоков данных. Очевидно, что наиболее быстрый доступ осуществляется к
коротким файлам, длиной до 10-ти блоков. В этом случае доступ к данным
требует 1 обращение к внешней памяти. При использовании блоков косвенности
требуется, соответственно, 2, 3 или 4 обращения к внешней памяти. Существует
мнение, что это не очень дорогая цена за возможность адресации гигобайтных
файлов.