В началоLinux не для идиотов → Файловая система
Gentoo-doc HOME Пред.: System V shared memoryВ началоУровень выше: Linux не для идиотовСлед.: Статически и динамически собранные программы

6. Файловая система

6.1. Виртуальная файловая система

VFS и драйверы файловых систем являются одной из важнейших составляющих ядра. Для того, чтобы получить доступ к файлам, хранящимся на каком-либо устройстве хранения данных, необходимо, чтобы в ядро был загружен драйвер соответствующей файловой системы, и файловая система была смонтирована. Драйвера всех файловых систем поддерживают набор стандартных функций: открыть файл по имени, записать данные в файл, прочитать данные из файла, закрыть файл, удалить файл и т.д.

Уточним, что драйвера файловых систем не занимаются кэшированием, этим занимается VFS.

При первоначальной загрузке драйвер файловой системы регистрирует в VFS имя файловой системы и те функции, которые предназначены для выполнения стандартных файловых операций. Впоследствии при обращении к файлу на какой-либо файловой системе VFS будет переадресовывать обращение на соответствующую функцию, если таковая была зарегистрирована драйвером. Посмотреть список обслуживаемых ядром файловых систем можно в файле /proc/filesystems:

$ cat /proc/filesystems
nodev   sysfs
nodev   rootfs
nodev   bdev
nodev   proc
nodev   sockfs
nodev   usbfs
nodev   usbdevfs
nodev   futexfs
nodev   tmpfs
nodev   pipefs
nodev   eventpollfs
nodev   devpts
ext2
nodev   ramfs
nodev   hugetlbfs
iso9660
nodev   devfs
nodev   mqueue
ext3
nodev   rpc_pipefs
nodev   nfsd
nodev   smbfs

Операция монтирования предназначена для того, чтобы сделать доступной файловую систему, расположенную на каком-либо блочном устройстве. Суть операции монтирования заключается в том, что ядро ассоциирует некоторый каталог (называемый точкой монтирования) с блочным устройством и драйвером файловой системы. Для этого оно передает ссылку на блочное устройство драйверу файловой системы, и в случае, если драйвер успешно проидентифицировал эту файловую систему, ядро заносит в специальную таблицу монтирования информацию о том, что все файлы и каталоги, чей полный путь начинается с указанной точки монтирования, обслуживаются соответствующим драйвером файловой системы и расположены на указанном блочном устройстве.

Некоторые файловые системы не нуждаются в блочном устройстве, поскольку хранят свои данные исключительно в памяти, например файловая система procfs, через файлы которой можно получить доступ к различным системным параметрам и таблицам.

Очень часто при монтировании файловой системы системный администратор имеет возможность задать опции монтирования. Опции монтирования – это специальные параметры, которые влияют на работу драйвера файловой системы, когда он работает с файловой системой на соответствующем блочном устройстве – например, с помощью опций монтирования можно управлять режимом кэширования данных, преобразованиями имен файлов и данных, включать и отключать поддержку ACL и т.д.

Посмотреть таблицу примонтированных файловых систем можно через файл /proc/mounts:

$ cat /proc/mounts
rootfs / rootfs rw 0 0
/dev/root / ext3 rw 0 0
none /dev devfs rw 0 0
/proc /proc proc rw,nodiratime 0 0
/sys /sys sysfs rw 0 0
none /dev/pts devpts rw 0 0
usbdevfs /proc/bus/usb usbdevfs rw 0 0
/dev/chimera/var /var ext3 rw 0 0
/dev/chimera/temp /tmp ext3 rw 0 0
/dev/chimera/usr /usr ext3 rw 0 0
/dev/chimera/home /home ext3 rw 0 0
/dev/chimera/opt /opt ext3 rw 0 0
none /dev/shm tmpfs rw 0 0

Виртуальная файловая система Linux различает несколько типов файлов: каталоги, обычные файлы, именованные каналы, символьные ссылки, сокеты и специальные файлы. Каждая из этих разновидностей обрабатывается своим собственным образом:

  1. Обычные файлы могут быть прочитаны, записаны, удалены или отображены в память.

  2. Каталог можно представить как список имен файлов, и для этого списка определены операции добавления элемента в список, удаление элемента из списка, переименование элемента списка.

  3. Именованные каналы являются просто буферами – в него можно записать некоторый объем данных, и прочесть их в том же порядке, в каком они были записаны.

  4. Сокеты являются вариантом именованных каналов, но если у именованного канала буфер только один, то есть нельзя определить какой процесс записал данные в канал, то у сокетов может быть несколько клиентов, один из которых осуществляет управление сокетом и может обмениваться данными с любым из остальных клиентов, а те в свою очередь могут обмениваться данными с диспетчером канала – то есть сокет поддерживает множество независимых буферов, по одному на каждую пару сервер+клиент

  5. Специальные файлы предназначены для того, чтобы осуществлять прямой доступ к устройствам. Подробнее о специальных файлах будет говориться в главе Секреты /dev

  6. Символьные ссылки являются “ярлыками”, которые могут содержать имя другого файла – и тогда операции чтения, записи и открытия/закрытия файла автоматически переадресовываются к файлу, на который указывает символьная ссылка, но в отличие от “ярлыков” Windows (shortcuts), символьные ссылки (symbolic links) не требуют специальных функций при работе – все программы (кроме тех, которые специально предназначены для работы с ними) видят их как обычные файлы, и также их открывают, читают и записывают данные и т.д.

В некоторых файловых системах, которые изначально проектировались для UNIX-подобных систем, есть возможность создавать кроме символьных ссылок еще и жесткие ссылки. Фактически, жесткая ссылка – это второе имя для файла. Жесткие ссылки возможно создавать только в пределах одной файловой системы.

Из-за того, что в VFS присутствует понятие кэширования, перед отключением системы необходимо делать обязательный сброс изменений на диск. Сброс кэша на диск осуществляется в момент размонтирования файловой системы. Кроме того, с помощью команды sync можно в любой момент принудительно сбросить на диск все закэшированные изменения в файловой системе (например, системные администраторы часто делают sync перед загрузкой нового драйвера). Размонтировать файловую систему можно только тогда, когда ни один процесс не удерживает в открытом состоянии файлов с этой файловой системы, а также не находится ни один процесс не имеет рабочим каталогом каталога с размонтируемой файловой системы. При невыполнении этого условия размонтировать файловую систему не удастся:

$ umount /home/ftp/pub/linux/fedora/cd1
umount: /home/ftp/pub/linux/fedora/cd1: device is busy
umount: /home/ftp/pub/linux/fedora/cd1: device is busy

Некоторые файловые системы поддерживают специальные опции, позволяющие принудительно синхронизировать файловую систему при каждой операции чтения или записи. Обычно опции, влияющие на синхронизацию файловой системы, содержат в своем названии слово sync, например приведенная ниже команда инструктирует операционную систему примонтировать некоторый раздел в режиме принудительной синхронизации:

$ mount -t ext3 -o sync,dirsync /dev/hda9 /home

Следует учесть, что принудительная синхронизация – это удар по производительности операций записи для файловой системы, смонтированной в таком режиме, поэтому использовать такой его следует осторожно.

6.2. Права доступа

Кроме стандартных наборов прав доступа к файлам некоторые файловые системы Linux поддерживают т.н. POSIX ACL – списки контроля доступа POSIX. Эта возможность позволяет гибко управлять доступом к файлу, не ограничиваясь “классическим” набором ugo/rwx. Для того, чтобы использовать на файловой системе POSIX ACL, необходимо смонтировать файловую систему с опцией acl:

$ mount -t ext3 -o acl /dev/inferno/opt /opt

Возможно также настроить соответствующий параметр для файловой системы, чтобы она поддерживала POSIX ACL по умолчанию:

$ tune2fs -o acl /dev/inferno/opt

После установки соответствующей опции можно приступать к работе с POSIX ACL. Для работы с ними существует две базовых утилиты: getfacl для получения списка дополнительных атрибутов доступа, и setfacl для установки расширенных атрибутов контроля доступа. Если в выводе команды ls вы видите символ “+” рядом со списком стандартных прав доступа, это означает, что для файла также установлены расширенные атрибуты контроля доступа:

$ ls -l /home/dalth/.bash_???????
-rw-r-----+ 1 dalth dalth 20034 Окт 11 22:48 /home/dalth/.bash_history
-rw-r--r--  1 dalth dalth   191 Авг 23 21:51 /home/dalth/.bash_profile

Для просмотра значений расширенных атрибутов можно воспользоваться утилитой getfacl. Жирным шрифтом выделен дополнительный атрибут контроля доступа, позволяющий пользователю kiki получить доступ на чтение к файлу .bash_history:

$ getfacl .bash_history
# file: .bash_history
# owner: dalth
# group: dalth
user::rw-
user:kiki:r--
group::---
mask::r--
other::---

Добавим пользователю oracle права на чтение и запись файла .bash_history с помощью команды setfacl, и затем отберем дополнительные права на доступ к указанному файлу у пользователя kiki:

$ setfacl -m u:oracle:rw .bash_history
$ setfacl -x u:kiki .bash_history
$ getfacl .bash_history
# file: .bash_history
# owner: dalth
# group: dalth
user::rw-
user:oracle:rw-
group::---
mask::rw-
other::---

Последним шагом сбросим все расширенные атрибуты с файла с файла .bash_history:

$ setfacl -b .bash_history
$ ls -l .bash_history
$ getfacl .bash_history
-rw-------  1 dalth dalth 20034 Окт 11 22:48 .bash_history

Расширенные атрибуты позволяют гибко контролировать доступ к файловых объектам, обходя стратегию ugo/rwx пришедшую из “классического UNIX”. Права доступ на файловые объекты могут быть выданы не только пользователю, но и группе.

К сожалению, далеко не все утилиты и файловые системы поддерживают ACL, поэтому при резервном копировании или восстановлении файлов необходимо проверять корректность установки расширенных атрибутов и правильность их переноса.

6.3. Журналируемые файловые системы

Для обеспечения сохранности данных и обеспечения целостности файловых систем при неожиданных сбоях были разработаны журналируемые файловые системы. Как правило, у этих файловых систем существует специальная область данных, называемая журналом. Все изменения, которые необходимо произвести с файловой системой, сначала записываются в журнал, и уже из журнала попадают в основную часть файловой системы.

В большинстве случаев журналируются только метаданные файловых систем (служебная информация, обеспечивающая целостность структуры файловой системы – например, изменения в каталогах или служебных таблицах размещения файлов). Некоторые файловые системы позволяют журналировать не только метаданные, но и данные файлов – такой шаг позволяет повысить надежность, но уменьшает скорость записи данных на файловую систему, поскольку каждый блок данных записывается на диск дважды – сначала в журнал, и затем из журнала в основную область файловой системы.

В большинстве случаев, журналируемые файловые системы способны решить проблемы с надежностью при неожиданных сбоях без тех потерь производительности, к которым может привести использование опции sync при монтировании.

В частности, к журналируемым файловым системам, например, относятся EXT3, ReiserFS, XFS, JFS и некоторые другие.

6.4. Отображаемые в память файлы

Объединение кэширования файлов и разделяемой памяти позволяет реализовать такое действие, как отображение файла в память. Для простоты можно представить, что файл загружается в кэш, и страницы кэша отображаются в адресное пространство процесса, и в результате любое изменение в том фрагменте адресного пространства, которое занято отображением файла, автоматически попадает в закэшированные данные файла. Когда файл закрывается, закэшированные изменения сбрасываются на диск, изменяя сам файл. Кроме того, в свободное время ядро также постепенно сбрасывает изменившиеся кэшированные данные на диск.

Files mapped in memory

На самом деле, механизм отображения файлов в память куда “хитрее” – при обращении по записи к странице, которая является отображением некоторого файла, ядро перехватывает обращение, производит запись в файл (в подавляющем большинстве случаев эта операция попадает в кэш). При обращении по чтению к такой странице ядро опять же перехватывает обращение и производит чтение из файла – в большинстве случаев это чтение производится из кэша. Для наших же целей проще будет считать, что страницы кэша отображены в память процесса.

Такая методика часто используется для загрузки разделяемых библиотек, когда выполняемый код библиотек и исполняемого кода программы хранится в кэше и через отображение файла в память становится виден в адресном пространстве процесса:

$ cat /proc/1/maps
08048000-08050000 r-xp 00000000 03:01 75813      /sbin/init
08050000-08051000 rw-p 00008000 03:01 75813      /sbin/init
08051000-08072000 rw-p 08051000 00:00 0 
40015000-40016000 rw-p 40015000 00:00 0 
4c8ee000-4c903000 r-xp 00000000 03:01 92869      /lib/ld-2.3.3.so
4c903000-4c904000 r--p 00014000 03:01 92869      /lib/ld-2.3.3.so
4c904000-4c905000 rw-p 00015000 03:01 92869      /lib/ld-2.3.3.so
4c907000-4ca1c000 r-xp 00000000 03:01 92857      /lib/tls/libc-2.3.3.so
4ca1c000-4ca1e000 r--p 00115000 03:01 92857      /lib/tls/libc-2.3.3.so
4ca1e000-4ca20000 rw-p 00117000 03:01 92857      /lib/tls/libc-2.3.3.so
4ca20000-4ca22000 rw-p 4ca20000 00:00 0 
4d201000-4d20f000 r-xp 00000000 03:01 92965      /lib/libselinux.so.1
4d20f000-4d211000 rw-p 0000d000 03:01 92965      /lib/libselinux.so.1
bfffd000-c0000000 rw-p bfffd000 00:00 0
ffffe000-fffff000 ---p 00000000 00:00 0

На самом деле, драйверы любого устройства и любой файловой системы могут по-своему реализовывать операцию mmap, но большинство драйверов файловых систем полагаются в этом на VFS.

6.5. Специальные файловые системы

Некоторые типы файловых систем являются специальными и предназначаются для выполнения или реализации специфических задач операционной системы. К таким файловым системам относятся файловые системы procfs и sysfs, предоставляющие доступ к различным параметрам системы и системным объектам, “живущим” в ядре.

Файловая система sysfs в основном предоставляет доступ к объектам ядра и отображает взаимосвязи между ними. Файловая система procfs предоставляет доступ к различным параметрам ядра и драйверов и к пользовательским процессам, позволяя тем самым реализовать такие команды как ps или sysctl. Большинство файлов в sysfs двоичные, в procfs – текстовые.

Драйверы файловых системы ramfs, tmpfs и shmfs очень похожи, и после монтирования файловой системы такого типа на ней можно создавать файлы, хранящиеся в памяти и отличаются в основном небольшими особенностями работы (например, страницы, используемые ramfs под данные файлов, не вытесняются в swap-файл в отличие от shmfs и tmpfs). В ядре 2.6 shmfs была заменена на tmpfs.

6.6. Сетевые файловые системы

Сетевые файловые системы предназначены для получения доступа к файловым системам других компьютеров с использованием сетевых протоколов.

Наиболее часто используются сетевые файловые системы NCPFS (для доступа к серверам Novell NetWare), SMBFS (для доступа к серверам Windows) и NFS (для доступа к файловым системам других UNIX-систем).

Как правило, процедура монтирования сетевых файловых систем схожа с процедурой монтирования обычных файловых систем на блочных устройствах с тем отличием, что вместо блочного устройства указывается адрес сервера, чья файловая система монтируется, и имя монтируемого ресурса. Для примера рассмотрим процедуры монтирования ресурсов, доступных по SMB и по NFS:

$ mount -t smbfs -o username=usr,workgroup=tst //server/share_name /mnt/smb_target
Password: ********
$ mount -t nfs -o timeout=4 server:/export/home /mnt/nfs_target

В данном примере опция -t команды mount указывает тип файловой системы, опция -o позволяет задать дополнительные параметры для монтирования – для SMB мы задаем, например, имя пользователя, с правами которого производится подключение к серверу и имя рабочей группы или домена, для NFS мы указываем таймаут, по истечении которого операция ввода/вывода считается неудавшейся. Вместо блочного устройства мы указываем адрес сервера, ресурс которого хотим использовать, и имя ресурса на сервере. Последним параметром идет точка монтирования.

6.7. Создание файловых систем

Для создания файловых систем в Linux используется команда mkfs:

$ mkfs -t ext3 /dev/hda6

На самом деле, mkfs является просто “оберткой” к реальным программам создания файловых систем, которые обычно именуются как mkfs.<имя_ФС>, например mksf.ext2 или mkfs.reiserfs.

В большинстве случаев программы группы mkfs просто инициализируют специальную область раздела, называемую суперблоком файловой системы. Суперблок содержит ссылки на все значимые элементы файловой системы (например,ссылку на оглавление корневого каталога, ссылку список свободных блоков, ссылку на список файлов и т.д.)

Наличие суперблока (который практически всегда содержит в своем теле некоторое характерное значение) позволяет производить монтирование файловых систем без указания их типа. К сожалению, некоторые файловые системы вследствие своей архитектуры не содержат суперблока (в частности, FAT и большинство ее разновидностей) и для блочных устройств, содержащих такие файловые системы, автоматическое определение типа файловой системы затруднено.

Пред.: System V shared memoryВ началоУровень выше: Linux не для идиотовСлед.: Статически и динамически собранные программы
В началоLinux не для идиотов → Файловая система