Раздел ext2. Файловые системы ext2, ext3, XFS, ReiserFS, NTFS. Индексные дескрипторы файлов

Файловая система (англ. file system) - порядок, определяющий способ организации, хранения и именования данных на носителях информации ИТ – оборудования (использующего для многократной записи и хранения информации портативные флеш-карты памяти в портативных электронных устройствах: цифровых фотоаппаратах, мобильных телефонах и т. д) и компьютерной техники. Она определяет формат содержимого и физического хранения информации, которую принято группировать в виде файлов. Конкретная файловая система определяет размер имени файла (папки), максимальный возможный размер файла и раздела, набор атрибутов файла. Некоторые файловые системы предоставляют сервисные возможности, например, разграничение доступа или шифрование файлов.

Задачи файловой системы

Основные функции любой файловой системы нацелены на решение следующих задач:

именование файлов;

программный интерфейс работы с файлами для приложений;

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

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

Файловая система - это основная структура, используемая компьютером для упорядочения информации на жестком диске. При установке нового жесткого диска его необходимо разбить на разделы и отформатировать под определенную файловую систему, после чего на нем можно хранить данные и программы. В Windows существует три возможных варианта файловой системы: NTFS , FAT32 и редко используемая устаревшая система FAT (также известная как FAT16).

NTFS является предпочтительной файловой системой для этой версии Windows. Она имеет множество преимуществ перед более ранней системой FAT32; ниже перечислены некоторые из них.

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

Файловая система FAT32 и редко применяемая система FAT использовались в предыдущих версиях Windows, в том числе в Windows 95, Windows 98 и Windows Millenium Edition. Файловая система FAT32 не обеспечивает уровня безопасности, предоставляемого NTFS, поэтому если на компьютере имеется раздел или том, отформатированный под FAT32, файлы на этом разделе видны любому пользователю, имеющему доступ к компьютеру. Файловая система FAT32 также имеет ограничения по размеру файлов. В этой версии Windows невозможно создать раздел FAT32 размером более 32Гб. Кроме того, раздел FAT32 не может содержать файл размером более 4Гб.

Основной причиной использования системы FAT32 может служить то, что на компьютере можно будет запустить как Windows 95, Windows 98 или Windows Millenium Edition, так и эту версию Windows (конфигурация с несколькими операционными системами). Для создания такой конфигурации необходимо установить предыдущую версию операционной системы на раздел, отформатированный под FAT32 или FAT, сделав его основным (основной раздел может содержать операционную систему). Другие разделы, доступ к которым осуществляется из предыдущих версий Windows, также должны быть отформатированы под FAT32. Более ранние версии Windows могут обращаться только к сетевым NTFS-разделам или томам. NTFS-разделы на локальном компьютере будут недоступны.

FAT – плюсы:

Для эффективной работы требуется немного оперативной памяти.
Быстрая работа с малыми и средними каталогами.
Диск совершает в среднем меньшее количество движений головок (в сравнении с NTFS).
Эффективная работа на медленных дисках.

FAT – минусы:

Катастрофическая потеря быстродействия с увеличением фрагментации, особенно для больших дисков (только FAT32).
Сложности с произвольным доступом к большим (скажем, 10% и более от размера диска) файлам.
Очень медленная работа с каталогами, содержащими большое количество файлов.

NTFS – плюсы:

Фрагментация файлов не имеет практически никаких последствий для самой файловой системы – работа фрагментированной системы ухудшается только с точки зрения доступа к самим данным файлов.
Сложность структуры каталогов и число файлов в одном каталоге также не чинит особых препятствий быстродействию.
Быстрый доступ к произвольному фрагменту файла (например, редактирование больших.wav файлов).
Очень быстрый доступ к маленьким файлам (несколько сотен байт) – весь файл находится в том же месте, где и системные данные (запись MFT).

NTFS – минусы:

Существенные требования к памяти системы (64 Мбайт – абсолютный минимум, лучше – больше).
Медленные диски и контроллеры без Bus Mastering сильно снижают быстродействие NTFS.
Работа с каталогами средних размеров затруднена тем, что они почти всегда фрагментированы.
Диск, долго работающий в заполненном на 80% – 90% состоянии, будет показывать крайне низкое быстродействие.

В качестве «родных» для Linux (то есть тех, на которые он может быть установлен и с которых способен стартовать) рассматриваются следующие файловые системы: ext2fs, ext3fs, ext4fs, ReiserFS, XFS, JFS. Именно они обычно и предлагаются на выбор при установке подавляющего большинства дистрибутивов. Конечно, существуют и способы установки Linux на файловые системы FAT/VFAT/FAT32, но это - только для тех медам и мсье, которые понимают толк в извращениях, и о них я говорить не буду.

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

Так вот, под мелкими файлами понимаются файлы размером меньше логического блока файловой системы, который в Linux в большинстве случаев равен четырем килобайтам, хотя и может задаваться при форматировании в некоторых пределах (зависящих от конкретной FS). Таких мелких файлов в любой Unix-подобной ОС - бессчетное количество. Типичным примером являются файлы, составляющие дерево портов FreeBSD, портежей Gentoo и тому подобных портообразных систем.
В большинстве файловых систем для таких мини файлов существует как свой inode (информационный узел, содержащий мета информацию о файле), так и блок данных, что приводит как к расходу дискового пространства, так и снижению быстродействия файловых операций. В частности, именно в этом причина катастрофической задумчивости файловой системы FreeBSD (как старой, UFS, так и новой, UFS2) при работе с собственной же системой портов.

В файловой системе ReiserFS в таких случаях отдельные блоки под данные не выделяются - она умудряется запихать данные файла непосредственно в область его же inode. За счет этого и дисковое пространство экономится, и быстродействие возрастает - буквально в несколько раз по сравнению со всеми прочими FS.
Такое обращение с мелкими файлами ReiserFS послужило причиной возникновения легенды о ее ненадежности. Действительно, при крахе файловой системы (то есть разрушении служебных областей) данные, размещенные совместно со своими inodes, вместе с ними же и пропадают - причем безвозвратно. Тогда как в тех файловых системах, где inodes и блоки данных всегда разобщены пространственно, последние теоретически можно восстановить. Так, для ext2/ext3 даже существуют средства, позволяющие это сделать.

Однако, как и всякая легенда, эта лишь производит впечатление достоверности. Во-первых, безвозвратная потеря данных относится лишь к очень маленьким файлам. Среди пользовательских таковых практически не бывает, а все прочие же легко восстанавливаются из дистрибутива.
Во-вторых, говоря о возможности восстановления данных из блоков, утративших привязку к своим inodes, я не случайно употребил слово «теоретическая». Потому что на практике это занятие чрезвычайно трудоемкое, не дающее гарантированного результата. Каждый, кому приходилось этим заниматься, согласится, что предаться ему можно только от полной безысходности. И это относится ко всем файловым системам Linux. Так что этим аспектом при выборе файловой системы можно пренебречь.

По суммарному быстродействию ReiserFS однозначно быстрее всех остальных журналируемых FS, а по некоторым показателям превосходит и ext2. С результатами сравнения скорости выполнения некоторых распространенных файловых файловых операций можно ознакомиться здесь.
А вот с совместимостью у ReiserFS дело обстоит несколько хуже. Доступ к ней из ОС семейства Windows, насколько мне известно, невозможен. В некоторых операционных системах семейства BSD (DragonFlyBSD, FreeBSD) реализована поддержка этой файловой системы, но в режиме только для чтения. Даже вероятность того, что произвольный Linux LiveCD прошлых лет не имеет поддержку ReiserFS, не нулевая.

И тут впору вспомнить об ext3fs. Преимущество ее вовсе не в большей надежности - это такая же легенда, как и неустойчивость ReiserFS. О случаях краха ext3fs я слышал не меньше, чем об аналогичных происшествиях с ReiserFS. Самому мне не удавалось порушить ни ту, ни другую. Разве что с ext2 получалось - но и то очень давно, во времена ядра 2.2 (или даже еще 2.0).

Нет, главное преимущество ext3fs в ее совместимости - она с гарантией будет прочитана любой Linux-системой. Например, при восстановлении с какого-нибудь древнего подручного LiveCD - ситуация, практически не столь уж невероятная, мне приходилось в нее попадать. Опять же, большинство BSD-систем легко понимают ext3fs (хотя и без журналирования). Для Windows также имеются, насколько я знаю, всякого рода драйверы и plug-ins к распространенным файловым менеджерам (типа Total Commander), обеспечивающие доступ к разделам с ext2fs/ext3fs.

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

Впрочем, если требование быстродействия ставится на первое место, то тут вне конкуренции оказывается ext2fs - правда, в этом случае придется смириться с отсутствием журналирования вообще. И, следовательно, с длительными проверками файловой системы при любом некорректном завершении работы - а при объемах современных дисков это может затянуться ой как надолго…

Относительно XFS можно сказать следующее. В плане совместимости к ней относится все то же самое, что написано для ReiserFS - более того, до некоторого времени она не поддерживалась стандартным ядром Linux. С точки зрения быстродействия она XFS она также не блещет, выступая суммарно примерно на одном уровне с ext3fs. А на операции удаления файлов вообще демонстрирует удручающую медлительность.
По моим наблюдениям, использование XFS оправдывает себя при работе не просто с большими, а с очень большими файлами - каковыми являются фактически только образы DVD и видеофайлы.

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

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

Если предусматривается отдельный раздел под каталог /boot (а это рекомендуется при использовании загрузчика GRUB его разработчиками) - для него никакая другая файловая система, кроме ext2fs, не оправданна, какое-либо журналирование тут смысла не имеет. Наконец, если создается отдельный раздел под всякого рода мультимедийные материалы - тут можно подумать и о XFS.

Если же подойти к объяснению более методично

ext - на начальном этапе развития Linux была доминирующей система ext2 (расширенная файловая система, версия 2). С 2002 года ей на смену пришла система ext3, которая во многом совместима с ext2, но к тому же поддерживает функции журналирования, а при работе с версией ядра 2.6 и выше - и ACL. Максимальный размер файла составляет 2 Тбайт, максимальный размер файловой системы - 8 Тбайт. В конце 2008 года было официально заявлено о выпуске версии ext4, которая обладает обратной совместимостью с ext3, но многие функции внедрены более эффективно, чем ранее. Кроме того, максимальный размер файловой системы равен 1 Эбайт (1 048 576 Тбайт), и можно рассчитывать, что на какое-то время такого объема хватит. О reiser - система получила название от имени своего основателя - Ганса Рай-зера (Hans Reiser) и была первой системой с функциями журналирования, обращавшейся за данными к ядру Linux. Версия З.п в SUSE даже считалась стандартной в течение некоторого времени. Основные преимущества reiser в сравнении с ext3 - более высокая скорость работы и эффективность размещения при работе с мелкими файлами (а в файловой системе, как правило, большинство файлов мелкие). Со временем, правда, разработка reisefers приостановилась. Уже давно было заявлено о выходе версии 4, которая все еще не готова, а поддержка версии 3 прекратилась. О xfs - первоначально файловая система xfs разрабатывалась для рабочих станций фирмы SGI, функционировавших в операционной системе IRIX. Xfs особенно хороша для работы с крупными файлами, в частности идеально подходит для работы с потоковым видео. Система поддерживает квотирование и расширенные атрибуты (ACL).
jfs

jfs - a66peBHaTypaJFS расшифровывается «Журналируемая файловая система». Первоначально она была разработана для IBM, а затем адаптирована для Linux.Jfs никогда не пользовалась в Linux особым признанием и в настоящее время влачит жалкое существование, уступая другим файловым системам.
brtfs

brtfs - если на то будет воля ведущих разработчиков ядра, файловую систему brtfs в Linux ждет блестящее будущее. Эта система была разработана в Oracle с нуля. Она включает функции поддержки модуля отображения устройств (device-mapper) и RAID. Brtfs наиболее сходна с системой ZFS, разработанной компанией Sun. К ее самым интересным функциям относится проверка файловой системы на ходу, а также поддержка SSD (твердотельные диски - это жесткие диски, работающие на основе флеш-памяти). К сожалению, работа над brtfs в обозримом будущем не завершится. В Fedora, уже начиная с версии 11, предусмотрена возможность установки brtfs, но пользоваться ею я рекомендую только разработчикам файловых систем!
Не существует «быстрейшей» или «наилучшей» файловой системы - оценка зависит от того, для чего вы собираетесь использовать систему. Начинающим пользователям Linux, работающим с локальным компьютером, рекомендуется работать с ext3, а администраторам серверов - с ext4. Конечно, с ext4 скорость работы повыше, чем с ext3, но при этом в системе ext4 значительно хуже дело обстоит с надежностью данных - вы вполне можете потерять информацию при внезапном отключении системы.

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

sysv - применяется в ОС SCO, Xenix и Coherent.

ufs - используется в FreeBSD, NetBSD, NextStep и SunOS. Linux может только считывать информацию из таких файловых систем, но не может вносить изменения в данные. Для доступа к сегментам с BSD дополнительно потребуется расширение BSD disklabel. Аналогичное расширение существует и для таблиц разбиения SunOS.

ZFS - это относительно новая система, разработанная Sun для Solaris. Поскольку код ZFS не соответствует лицензии GPL, ее нельзя интегрировать с ядром Linux. По этой причине Linux поддерживает эту файловую систему лишь опосредованно, через FUSE.
Windows, Mac OS X

Следующие файловые системы будут полезны при обмене информацией с MS DOS, Windows, OS/2 и Macintosh.

vfat - используется в Windows 9х/МЕ. Linux может считывать информацию из таких разделов и вносить в нее изменения. Драйверы системы vfat позволяют работать и со старыми файловыми системами MS DOS (8 + 3 символов).

ntfs - система применяется во всех современных версиях Windows: otNT и выше. Linux может считывать и изменять ее файлы.

hfs и hfsplus - эти файловые системы используются в компьютерах Apple. Linux может считывать и изменять ее файлы.

На CD и DVD с данными обычно используются собственные файловые системы.

iso9660 - файловая система для CD-ROM описана в стандарте ISO-9660, допускающем только короткие названия файлов. Длинные названия поддерживаются в различных операционных системах по-разному, с помощью многообразных несовместимых друг с другом расширений. Система Linux способна работать как с расширением Rockridge, обычным в UNIX, так и с расширением Joliet, разработанным Microsoft.

udf - этот формат (универсальный формат диска) появился и развился как наследник ISO 9660.

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

Файловые системы не обязательно должны находиться на локальном диске - они
могут подключаться к компьютеру и через сеть. Ядро Linux поддерживает различные сетевые файловые системы, из которых чаще всего применяются следующие.

smbfs/cifs - помогают подключать сетевые каталоги Windows или Samba к дереву каталогов.

nfs - это важнейшая в UNIX сетевая файловая система.

coda - эта система очень напоминает NFS. В ней имеется множество дополнительных функций, но она не очень распространена.

ncpfs - работает на базе протокола ядра NetWare;oH используется Novell Netware.

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

В Linux существует несколько файловых систем, предназначенных не для сохранения данных на жестком диске (или другом носителе), а только для обмена информацией между ядром и пользовательскими программами.
devpts - эта файловая система обеспечивает доступ к псевдотерминалам (сокращенно - PTY) через /dev/pts/* в соответствии со спецификацией UNIX-98. (Псевдотерминалы эмулируют последовательный интерфейс. В системах UNIX/Linux такие интерфейсы используются эмуляторами терминалов, например xterm. При этом, как правило, применяются такие устройства, как /dev/ ttypn. В спецификации UNIX-98, напротив, определяются новые устройства. Более подробная информация сообщается в текстовом терминале H0WT0.)
proc и sysfs - файловая система proc служит для отображения служебной информации, касающейся управления ядром и процессами. В дополнение к этому файловая система sysfs строит взаимосвязи между ядром и оборудованием. Обе файловые системы подключаются на позициях /proc и /sys.
tmpfs - эта система построена на основе разделяемой памяти в соответствии с System V. Она обычно подключается на позиции /dev/shm и обеспечивает эффективный обмен информацией между двумя программами. В некоторых дистрибутивах (например, Ubuntu) каталоги /var/run и /var/lock также создаются с помощью файловой системы tmpfs. Файлы из этих каталогов применяются некоторыми сетевыми демонами для того, чтобы сохранять идентификационные номера процессов, а также информацию о доступе к файлам. Благодаря tmpfs эти данные теперь отражаются в RAM. Метод гарантирует высокую скорость, а также то, что после отключения компьютера в каталогах / var/run или /var/lock не останется никаких файлов.

usbfs - файловая система usbfs, начиная с версии ядра 2.6 и выше, дает информацию о подключенных USB-устройствах. Обычно она интегрирована в файловую систему proc. О поддержке USB-устройств в Linux.

Прочие файловые системы

auto - на самом деле файловой системы под таким названием не существует. Однако слово auto можно использовать в /etc/fstab или с командой mount для указания файловой системы. В таком случае Linux попытается самостоятельно распознать файловую систему. Этот метод работает с большинством важнейших файловых систем.
autofs, autofs4

autofs, autofs4 - это тоже не файловые системы, а расширения ядра, автоматически выполняющие команду mount для выбранных файловых систем. Если файловая система не используется в течение некоторого времени, то для нее автоматически выполняется команда umount. Этот метод удобен прежде всего в тех случаях, когда из многих NFS-каталогов одновременно активно используются всего несколько.

Для выполнения таких операций при запуске системы сценарий /etc/init.d/ autofs автоматически выполняет программу automount. Она конфигурируется с помощью файла /etc/auto.master. Соответствующие программы автоматически устанавливаются, например, в Red Hat и Fedora. В любом случае autofs активизируется только после конфигурации /etc/auto.master или /etc/auto.misc.
cramfs и squashfs

cramfs и squashfs - файловые системы Cram и Squash предназначены только для чтения. Они используются для того, чтобы «упаковать» как можно больше заархивированных файлов во флеш-память или ПЗУ (постоянное запоминающее устройство).

fuse - FUSE означает «Файловая система в пользовательском пространстве» (Filesystem in Userspace) и позволяет разрабатывать и использовать драйверы файловых систем вне ядра. Следовательно, FUSE всегда применяется с внешним драйвером файловой системы. FUSE работает, в частности, с драйвером NTFS ntfs-3g.

gfs и ocfs - Глобальная файловая система (Global File System) и Кластерная файловая система от Oracle (Oracle Cluster File System) позволяют строить гигантские сетевые файловые системы, к которым могут параллельно обращаться множество компьютеров в один и тот же момент.

jffs и yaffs - Журналируемая файловая система для флеш-носителей (Journaling Flash File System) и Альтернативная файловая система для флеш-носителей (Yet Another Flash File System) специально оптимизированы для работы с твердотельными дисками и флеш-носителями. С помощью специальных алгоритмов они пытаются равномерно использовать все ячейки памяти (технология «выравнивание износа»), чтобы избежать преждевременного отказа системы.
loop

loop - используется для работы с псевдоустройствами. Псевдоустройство (loopback device) - это адаптер, способный обращаться к обычному файлу как к блочному устройству. Благодаря ему в любом файле можно расположить любую файловую систему, а затем подключить ее к дереву каталогов с помощью mount. Отвечающая за это функция ядра - поддержка псевдоустройств - реализуется в модуле loop.

Существуют разнообразные способы применения псевдоустройств. В частности, они могут использоваться при создании дисков в оперативной памяти для начальной инициализации (Initial RAM disk) для GRUB или LILO, при реализации зашифрованных файловых систем или тестировании ISO-образов для CD.

Файловые системы носителей данных

Файловые системы
ISO 9660
Joliet расширение файловой системы ISO 9660.
Rock Ridge (RRIP, IEEE P1282) - расширение файловой системы ISO 9660, разработанное для хранения файловых атрибутов, используемых в операционных системах POSIX
Amiga Rock Ridge Extensions
El Torito
Apple ISO9660 Extensions
HFS, HFS+
Universal Disk Format cпецификация формата файловой системы, независимой от операционной системы для хранения файлов на оптических носителях. UDF является реализацией стандарта ISO/IEC 13346
Mount Rainier

Рассмотрим логическую структуру файловой системы ext2fs. Физически жесткий диск разбит на сектора размером 512 байт. Первый сектор дискового раздела в любой файловой системе считается загрузочной областью. В первичном разделе эта область содержит загрузочную запись - фрагмент кода, который инициирует процесс загрузки операционной системы при запуске. На других разделах эта область не используется. Остальные сектора объединены в логические блоки размером 1, 2 или 4 килобайта. Логический блок есть наименьшая адресуемая порция данных: данные каждого файла занимают целое число блоков. Блоки, в свою очередь, объединяются в группы блоков. Группы блоков и блоки внутри группы нумеруются последовательно, начиная с 1.

Структуры данных, применяемые при работе с файловой системой ext2fs, описаны в заголовочном файле /usr/include/linux/ext2fs .h.

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

информацию о ней. Он имеет размер 1024 байта и располагается по смещению 1024 байта от начала файловой системы. В каждой группе блоков он дублируется, что позволяет быстро восстановить его после сбоев. В суперблоке определяется размер файловой системы, максимальное число файлов в разделе, объем свободного пространства и содержится информация о том, где искать незанятые участки . При запуске ОС суперблок считывается в память и все изменения файловой системы вначале находят отображение в копии суперблока, находящейся в ОП, и записываются на диск только периодически. Это позволяет повысить производительность системы, так как многие пользователи и процессы постоянно обновляют файлы. С другой стороны, при останове системы суперблок обязательно должен быть записан на диск, что не позволяет выключать компьютер простым выключением питания. В противном случае, при следующей загрузке информация, записанная в сунерблоке, окажется не

соответствующей реальному состоянию файловой системы.

После суперблока следует описание (дескриптор) группы блоков. Хранящаяся в нем информация позволяет найти битовые карты блоков и индексных дескрипторов, а также таблицу индексных дескрипторов.

Битовой картой блоков (block bitmap) называется структура, каждый бит которой показывает, отведен ли такой же по счету блок какому-либо файлу. Значение 1 показывает, что блок занят. Эта карта служит для поиска свободных блоков в тех случаях, когда надо выделить место под файл .

Битовая карта индексных дескрипторов выполняет аналогичную функцию по отношению к таблице индексных дескрипторов: показывает, какие именно дескрипторы заняты.

Каждому файлу соответствует один и только один индексный дескриптор (inode, i-узел, информационный узел), который идентифицируется своим порядковым номером - индексом файла. В индексном дескрипторе хранятся метаданные файла. Среди них - все атрибуты файла, кроме его имени, и указатель на данные файла.

Для обычного файла или каталога этот указатель представляет собой массив из 15 адресов блоков. Первые 12 адресов в этом массиве являются прямыми ссылками на номера блоков, в которых хранятся данные файла. Если данные не помещаются в 12 блоков, то включается механизм косвенной адресации. Следующий адрес в этом массиве является косвенной ссылкой, то есть адресом блока, в котором хранится список адресов следующих блоков с данными из этого файла.

Сколько блоков с данными можно так адресовать? Адрес блока занимает 4 байта, блок, как уже сказано, - 1, 2 или 4 килобайта. Значит, путем косвенной адресации можно разместить 256 - 1024 блока.

А если файл еще длиннее? Следующий адрес в массиве-указателе указывает на блок двойной косвенной адресации (double indirect block). Этот блок содержит список адресов блоков, которые, в свою очередь, содержат списки адресов следующих блоков данных.

И, наконец, последний адрес в массиве-указателе задает адрес блока тройной косвенной адресации, то есть блока со списком адресов блоков, которые являются блоками двойной косвенной адресации.

Пока остается непонятным, где находится имя файла, если его нет ни среди данных файла, ни среди его метаданных. В UNIX-подобных системах имя файла есть атрибут не самого файла, а файловой системы, понимаемой как логическая структура каталогов. Имя файла хранится только в каталоге, к которому файл приписан, и больше нигде. Из этого вытекают любопытные следствия.

Во-первых, одному индексному дескриптору может соответствовать любое количество имен, приписанных к разным каталогам, и все они являются настоящими. Количество имен (жестких ссылок) учитывается в индексном дескрипторе. Именно это количество вы можете увидеть по команде Is -1.

Во-вторых, удаление файла означает просто удаление записи о нем из данных каталога и уменьшение на 1 счетчика ссылок.

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

Сам каталог таким же образом приписан к своему родительскому каталогу. Корневой каталог всегда записан в индексный дескриптор с номером 2 (номер 1 отведен для списка адресов дефектных блоков). В каждом каталоге хранится ссылка на него самого и на его родительский каталог - это и есть псевдоподкаталоги «.» и «..».

Таким образом, количество ссылок на каталог равно количеству его подкаталогов плюс два.

Данные каталога представляют собой связный список с записями переменной длины и выглядят примерно так:

Строение каталога в ext2fs

А как же файлы физических устройств? Они могут находиться в тех же каталогах, что и обычные файлы: в каталоге нет никаких данных, говорящих о принадлежности имени файлу на диске или устройству. Разница находится на уровне индексного дескриптора. Если i-узел обычного файла указывает на дисковые блоки, где хранятся его данные, то в i-узле файла устройства содержится указатель на список драйверов устройств в ядре - тот элемент списка, который соответствует старшему номеру устройства:

Разница между обычным файлом и файлом устройства

Свойства файловой системы ext2fs:

Максимальный размер файловой системы - 4 Тбайт.

Максимальный размер файла - 2 Гбайт.

Максимальная длина имени файла - 255 символов.

Минимальный размер блока - 1024 байт.

Количество выделяемых индексных дескрипторов - 1 на 4096 байт раздела.

ВЛАДИМИР МЕШКОВ

Архитектура файловой системы ext2

В статье рассматривается логическая структура ext2 – файловой системы операционной системы Linux.

Основные компоненты файловой системы ext2

Как и в любой файловой системе UNIX, в составе файловой системы ext2 можно выделить следующие составляющие:

  • блоки и группы блоков;
  • информационный узел (information node);
  • суперблок (superblock).

Блоки и группы блоков

Все пространство раздела диска разбивается на блоки фиксированного размера, кратные размеру сектора – 1024, 2048 и 4096 байт. Размер блока указывается при создании файловой системы на разделе жесткого диска. Меньший размер блока позволяет экономить место на жестком диске, но также ограничивает максимальный размер файловой системы. Все блоки имеют порядковые номера. С целью уменьшения фрагментации и количества перемещений головок жесткого диска при чтении больших массивов данных блоки объединяются в группы.

Информационный узел

Базовым понятием файловой системы является информационный узел, information node, или inode. Это специальная структура, которая содержит информацию об атрибутах и физическом расположении файла. Атрибутами файла являются его тип (обычный файл, каталог и т. д.), права доступа к нему, идентификатор владельца, размер, время создания. Информация о физическом расположении представляет собой последовательность абсолютных номеров блоков, содержащих данные файла.

Суперблок

Суперблок – основной элемент файловой системы ext2. Он содержит следующую информацию о файловой системе (список неполный):

  • общее число блоков и inode в файловой системе;
  • число свободных блоков и inode в файловой системе;
  • размер блока файловой системы;
  • количество блоков и inode в группе;
  • размер inode;
  • идентификатор файловой системы;
  • номер первого блока данных.

Другими словами, это номер блока, содержащего суперблок. Этот номер всегда равен 0, если размер блока файловой системы больше 1024 байт, и 1, если размер блока равен 1024 байт.

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

Ранние версии файловой системы ext2 создавали копии суперблока в начале каждой группы блоков. Это приводило к большим потерям дискового пространства, поэтому позже количество резервных копий суперблока было уменьшено, и для их размещения были выделены группы блоков 0, 1, 3, 5 и 7.

Формат группы блоков

Обобщенная структурная схема файловой системы ext2 представлена на рис. 1.

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

Битовая карта занятости блоков обычно расположена в первом блоке группы. Если в группе присутствует резервная копия суперблока, битовая карта располагается во втором блоке группы. Размер битовой карты – один блок. Каждый бит этой карты обозначает состояние блока. Если бит установлен (1), то блок занят, если сброшен (0) – блок свободен. Первому блоку группы соответствует нулевой бит карты, второму блоку – первый бит и т. д.

Inode, находящиеся в пределах одной группы, собраны в таблицу. В битовой карте занятости inode группы каждый бит характеризует состояние элемента в таблице inode группы.

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

Алгоритм чтения файла

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

Как было сказано выше, информация о физическом расположении файла содержится в inode. Эта информация представляет собой последовательность 32-битных номеров блоков, содержащих данные файла (рис. 1). Первые 12 номеров – это прямые ссылки на информационные блоки (direct blocks number). 13-й номер является косвенной ссылкой (indirect blocks number). В нем находится адрес блока, в котором хранятся адреса информационных блоков. 14-й номер – двойная косвенная ссылка (double blocks number), 15-й номер – тройная косвенная ссылка (triple blocks number).

Имя файла в состав inode не входит, установление соответствия между именами файлов и порядковыми номерами inode выполняется через каталоги.

Каталоги

Файлы в UNIX- и POSIX-системах хранятся в древовидной иерархической файловой системе. Корень файловой системы – это корневой каталог, обозначенный символом «/». Каждый промежуточный узел в дереве файловой системы – это каталог. Конечные вершины дерева файловой системы являются либо пустыми каталогами, либо файлами. Абсолютное путевое имя файла состоит из имен всех каталогов, ведущих к указанному файлу, начиная с корневого каталога. Так, путевое имя /home/test.file означает, что файл test.file расположен в каталоге home, который, в свою очередь, находится в корневом каталоге «/».

Каталог, так же как и файл, описывается при помощи inode. Содержимое каталога представляет собой массив записей, каждая из которых содержит информацию о файле, который находится «внутри» текущего каталога.

Запись каталога имеет следующий формат:

  • порядковый номер inode файла;
  • длина записи в байтах;
  • имя файла;
  • длина имени файла.

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

Несколько первых номеров inode зарезервированы файловой системой, их перечень содержится в заголовочном файле:

* Special inode numbers

#define EXT2_BAD_INO 1 /* Bad blocks inode */

#define EXT2_ROOT_IN 2 /* Root inode */

#define EXT2_ACL_IDX_IN 3 /* ACL inode */

#define EXT2_ACL_DATA_INO 4 /* ACL inode */

#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */

#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */

Для записи корневого каталога зарезервирован inode под номером 2 (root inode). Этот inode находится в группе блоков 0 и занимает вторую позицию в таблице inode этой группы. Номер первого незарезервированного inode хранится в суперблоке.

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

Номер группы блоков, в которой расположен inode, вычисляется по формуле:

group = (inode_num - 1) / inodes_per_group

где:

  • group – искомый номер группы блоков;
  • inode_num – порядковый номер inode, определяющего файл;
  • inodes_per_group – число inode в группе (эта информация находится в суперблоке).

Позиция inode в таблице inode группы определяется по формуле:

index = (inode_num - 1) % inodes_per_groupe

где index – позиция inode в таблице.

Рассмотрим пример получения содержимого файла test.file, находящегося в корневом каталоге. Для чтения файла /test.file необходимо:

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

На рис. 2 подробно показаны этапы чтения файла /test.file.

    Этапы 1-6 – чтение корневого каталога:

  1. Из группы блоков 0 считывается таблица дескрипторов групп.
  2. Из таблицы дескрипторов групп извлекается дескриптор группы блоков 0 и из него считывается адрес таблицы inode группы 0.
  3. Из группы блоков 0 считывается таблица inode.
  4. Порядковый номер inode корневого каталога фиксирован и равен 2, поэтому из таблицы inode группы 0 считывается второй элемент, который содержит адрес блока с содержимым корневого каталога. Предположим, что этот блок расположен в группе блоков A.
  5. Из группы блоков A считывается блок, содержащий записи корневого каталога.
  6. Выполняется поиск записи с именем «test.file». Если такая запись найдена, из нее извлекается порядковый номер inode файла «test.file».
  7. Определив номер inode, можно получить доступ к информационным блокам файла (этапы 7-11):

  8. Вычисляется номер группы, в которой находится данный inode, и его позицию в таблице inode группы (предположим, что номер группы равен B, а позиция в таблице – X).
  9. Из таблицы дескрипторов групп извлекаем дескриптор группы блоков B, и из него считывается адрес таблицы inode этой группы блоков.
  10. Из группы блоков B считывается таблица inode.
  11. Из таблицы inode группы блоков B считывается inode, находящийся в позиции X.
  12. Из считанного inode извлекаются адреса блока с содержимым файла /test.file и выполняется чтение информации из блока с указанным адресом.

Программная реализация алгоритма чтения файла

Исходные данные: имеется раздел жесткого диска, на котором создана файловая система ext2. Этому разделу соответствует файл устройства /dev/hda3. В корневом каталоге раздела создан подкаталог home, а в нем находится файл test.file следующего содержания:

В чащах юга жил бы цитрус?

Да, но фальшивый экземпляр!

1234567890-=

Не подумайте плохого, это не бред, а тестовое упражнение из курса подготовки телеграфистов в войсках связи бывшего СССР!

Внимание! Следует учесть один важный момент. Созданный файл не будет сразу записан на диск, а сначала попадет в дисковый буфер. Попытка сразу же получить содержимое файла по вышеприведенному алгоритму ни к чему не приведет, так как информация об этом файле физически на диске отсутствует. Необходимо «заставить» систему записать дисковый буфер на диск. Самый простой способ сделать это – выполнить операцию перезагрузки. Поэтому после того, как файл создан, перезагрузите систему.

Наша задача – используя файл устройства /dev/hda3, осуществить чтение файла /home/test.file методом прямого доступа к его информационным блокам.

Рассмотрим программную реализацию модуля, выполняющего эту операцию.

Заголовочные файлы:

#include

#include

#include

#include

#include

#include

В заголовочном файле определены структурные типы, описывающие основные компоненты файловой системы ext2 – суперблок, дескриптор группы блоков, информационный узел, запись каталога.

Рассмотрим кратко поля, которые входят в каждую из этих структур:

  1. Структура суперблока struct ext2_super_block:
    • __u32 s_inodes_count – общее число inode в файловой системе;
    • __u32 s_blocks_count – общее число блоков в файловой системе;
    • __u32 s_free_blocks_count – количество свободных блоков;
    • __u32 s_free_inodes_count – количество свободных inode;
    • __u32 s_first_data_block – номер первого блока данных (номер блока, в котором находится суперблок);
    • __u32 s_log_block_size – это значение используется для вычисления размера блока. Размер блока определяется по формуле: block size = 1024 << s_log_block_size;
    • __u32 s_blocks_per_group – количество блоков в группе;
    • __u32 s_inodes_per_group – количество inode в группе;
    • __u16 s_magic – идентификатор файловой системы ext2 (сигнатура 0xEF53);
    • __u16 s_inode_size – размер информационного узла (inode);
    • __u32 s_first_ino – номер первого незарезервированного inode.
  2. Структура дескриптора группы блоков struct ext2_group_desc:
    • __u32 bg_block_bitmap – битовая карта занятости блоков группы;
    • __u32 bg_inode_bitmap – битовая карта занятости inode группы;
    • __u32 bg_inode_table – адрес таблицы inode группы.
  3. Структура информационного узла struct ext2_inode:
    • __u16 i_mode – тип файла и права доступа к нему. Тип файла определяют биты 12-15 этого поля:
      • 0xA000 – символическая ссылка;
      • 0x8000 – обычный файл;
      • 0x6000 – файл блочного устройства;
      • 0x4000 – каталог;
      • 0x2000 – файл символьного устройства;
      • 0x1000 – канал FIFO.
    • __u32 i_size – размер в байтах;
    • __u32 i_atime – время последнего доступа к файлу;
    • __u32 i_ctime – время создания файла;
    • __u32 i_mtime – время последней модификации;
    • __u32 i_blocks – количество блоков, занимаемых файлом;
    • __u32 i_block – адреса информационных блоков (включая все косвенные ссылки).
  4. Значение EXT2_N_BLOCKS определено в файле:

    * Constants relative to the data blocks

    #define EXT2_NDIR_BLOCKS 12

    #define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS

    #define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)

    #define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)

    #define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)

  5. Структура записи каталога struct ext2_dir_entry_2:
  6. #define EXT2_NAME_LEN 255

  • __u32 inode – номер inode файла;
  • __u16 rec_len – длина записи каталога;
  • __u8 name_len – длина имени файла;
  • char name имя файла.

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

#define PART_NAME "/dev/hda3"

struct ext2_super_block sb;

/* буфер для хранения таблицы дескрипторов групп */

unsigned char buff_grp;

unsigned char buff; /* информационный буфер */

int indev; /* дескриптор файла устройства */

int BLKSIZE; /* размер блока файловой системы */

Определим несколько функций, которые нам понадобятся для работы:

Функция чтения суперблока:

void read_sb()

Memset(&sb,0,1024);

Смещаемся на 1024 байта от начала раздела и считываем суперблок в структуру struct ext2_super_block sb:

If(lseek(indev,1024,0) < 0) {

Perror("lseek");

Exit(-1);

If(read(indev,(char *)&sb,sizeof(sb)) < 0) {

Perror("read");

Exit(-1);

Проверяем идентификатор файловой системы:

If(sb.s_magic != EXT2_SUPER_MAGIC) {

Printf("Неизвестный тип файловой системы! ");

Exit(-1);

Значение EXT2_SUPER_MAGIC определено в заголовочном файле.

Отображаем информацию о файловой системе, которая находится в суперблоке:

printf(" Superblock info ----------- ");

Printf("Inodes count - %u ",sb.s_inodes_count);

Printf("Blocks count - %u ",sb.s_blocks_count);

Printf("Block size - %u ",1024 << sb.s_log_block_size);

Printf("First inode - %d ",sb.s_first_ino);

Printf("Magic - 0x%X ",sb.s_magic);

Printf("Inode size - %d ",sb.s_inode_size);

Printf("Inodes per group - %u ",sb.s_inodes_per_group);

Printf("Blosks per group - %u ",sb.s_blocks_per_group);

Printf("First data block - %u ",sb.s_first_data_block);

Return;

Функция чтения таблицы дескрипторов групп:

void read_gdt()

Вычисляем размер блока файловой системы:

BLKSIZE = 1024 << sb.s_log_block_size

Таблица дескрипторов групп находится в блоке, который расположен сразу же за первым блоком данных (за суперблоком).

Считываем таблицу:

If(lseek(indev, (sb.s_first_data_block + 1) * BLKSIZE, 0) < 0) {

Perror("lseek");

Exit(-1);

If(read(indev,buff_grp,BLKSIZE) < 0) {

Perror("read");

Exit(-1);

Return;

Функция получения содержимого inode по его номеру:

void get_inode(int inode_num, struct ext2_inode *in)

Входные параметры функции – порядковый номер inode и структура struct ext2_inode.

Struct ext2_group_desc gd;

U64 group, index, pos;

Вычисляем номер группы блоков, в которой находится inode с порядковым номером inode_num:

Group = (inode_num - 1) / sb.s_inodes_per_group;

Из таблицы дескрипторов групп извлекаем дескриптор группы group и копируем его в структуру struct ext2_group_desc gd:

Memset((void *)&gd, 0, sizeof(gd));

Memcpy((void *)&gd, buff_grp + (group * (sizeof(gd))), sizeof(gd));

Вычисляем позицию inode c порядковым номером inode_num в таблице inode группы group и считываем этот inode в структуру struct ext2_inode:

index = (inode_num - 1) % sb.s_inodes_per_group;

Pos = ((__u64)gd.bg_inode_table) * BLKSIZE + (index * sb.s_inode_size);

Pread64(indev, in, sb.s_inode_size, pos);

Return;

Функция чтения блока данных:

void read_iblock(struct ext2_inode *in, int blk_num)

U64 pos;

Входные параметры функции – структура inode и номер блока (имеется в виду номер из последовательности адресных блоков, расположенных в inode).

Вычисляем смещение к информационному блоку на разделе и считываем этот блок в глобальный буфер buff:

Pos = ((__u64)in->i_block) * BLKSIZE;

Pread64(indev, buff, BLKSIZE, pos);

Return;

Функция получения содержимого корневого каталога:

void get_root_dentry()

Struct ext2_inode in;

Порядковый номер inode корневого каталога известен, поэтому получаем содержимое inode корневого каталога и считываем в буфер buff его содержимое:

get_inode(EXT2_ROOT_INO, &in);

Read_iblock(&in, 0);

В буфере buff будет находиться содержимое корневого каталога.

Return;

Функция получения номера inode по имени файла:

int get_i_num(char *name)

Входные параметры функции – имя файла. Возвращаемое значение – порядковый номер inode файла.

Int i = 0, rec_len = 0;

Struct ext2_dir_entry_2 dent;

В буфере buff находится массив записей каталога. Для определения порядкового номера inode файла необходимо найти в этом массиве запись с именем этого файла:

For(; i < 700; i++) {

Memcpy((void *)&dent, (buff + rec_len), sizeof(dent));

If(!memcmp(dent.name, name, dent.name_len)) break;

Rec_len += dent.rec_len;

Return dent.inode;

А теперь распишем главную функцию:

int main()

Переменные и структуры:

struct ext2_inode in;

// абсолютное путевое имя файла

Unsigned char *full_path = "/home/test.file";

Unsigned char buff1;

Static int i = 1;

Int n, i_num, outf, type;

Первым символом в абсолютном путевом имени файла должен быть прямой слэш (/). Проверяем это:

If(full_path != "/") {

Perror("slash");

Exit(-1);

Открываем файл устройства, считываем суперблок и таблицу дескрипторов групп:

Indev = open(PART_NAME,O_RDONLY);

If(indev < 0) {

Perror("open");

Exit(-1);

Read_sb();

Read_gdt();

Получаем содержимое корневого каталога:

get_root_dentry();

Сейчас в буфере buff находятся все записи корневого каталога (если хотите, можете сохранить их в отдельном файле). Теперь, имея записи корневого каталога, мы можем добраться до содержимого файла test.file, используя вышеприведенный алгоритм чтения файла. С этой целью организуем цикл. В теле цикла проведем разбор абсолютного путевого имени файла, выделяя его элементы – подкаталоги (он у нас один, home) и имя искомого файла (test.file). Для каждого элемента определим порядковый номер inode, считаем этот inode и затем получим содержимое нулевого блока (из последовательности адресных блоков, находящихся в inode):

while(1) {

Memset(buff1,0,sizeof(buff1));

For(n = 0 ; n < EXT2_NAME_LEN; n++, i++) {

Buff1[n] = full_path[i];

If((buff1[n] == "/") || (buff1[n] == "?")) {

I++;

Break;

buff1[n] = "?";

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

I_num = get_i_num(buff1);

Get_inode(i_num, &in);

Read_iblock(&in, 0);

Отобразим информацию о файле (имя, порядковый номер inode, размер файла и его тип):

Printf("Inode number - %u ", i_num);

Printf("File name - %s ", buff1);

Printf("File size - %u ",in.i_size);

Тип файла определяют старшие четыре бита поля i_mode структуры struct ext2_inode:

type = ((in.i_mode & 0xF000) >> 12);

Printf("Type - %d ",type);

Switch(type) {

Case(0x04) :

Printf("(каталог) ");

Break;

Case(0x08) :

Printf("(обычный файл) ");

Break;

Case(0x06) :

Printf("(файл блочного устройства) ");

Break;

Case(0x02) :

Printf("(файл символьного устройства) ");

Break;

Default:

Printf("(unknown type) ");

Break;

Проверяем тип файла. Если это обычный файл – прерываем цикл:

If(type & 0x08) {

В буфере buff будет находиться информация, считанная из информационных блоков файла /home/test.file. Запишем эту информацию в файл:

Outf = open("out",O_CREAT|O_RDWR,0600);

Write(outf, buff, sizeof(buff));

Close(outf);

Break;

Выходим:

Close(indev);

Return 0;

На этом рассмотрение логической структуры файловой системы ext2 завершим.

ext2 (также называется как ext2fs ) - Second Extended File System (Вторая Расширенная Файловая Система) представляет собой файловую систему, построенную на ядре Linux. Создателем и разработчиком ext2 является Реми Кард. Файловая система ext2 была построена им взамен старой, предыдущей версии - ext.

По таким показателям как скорость и производительность данная файловая система может служить эталоном. Об этом говорят результаты тестов производительности файловых систем. К примеру, в испытаниях на скорость последовательного чтения и записи, которые проводил технический центр Dell, файловая система ext2 превосходит ext3 , и уступает в скорости чтения лишь более современной ext4 .

Главным недостатком ext2 является то, что она не является журналируемой файловой системой. Однако, этот недостаток был устранен в следующей файловой системе - ext3.

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

История создания ext2

Во времена бурного развития системы Linux, в ней применялась файловая система ОС Minix. Она отличалась довольно высокой стабильностью, но при этом была 16-разрядной. Вследствие этого, в ней существовало жесткое ограничение в 64 Mb на раздел. Кроме того, имелось ограничение и на максимальную длину имени файла, которое составляло 14 символов.

Эти ограничения в совокупности послужили причиной для разработки «расширенной файловой системы» (отсюда и термин «Extended File System» ). На нее возлагалась задача по решению двух ключевых проблем Minix. Новая файловая система была обнародована в апреле 1992 года. Это была Ext, она расширила ограничения на размер файла до 2 гигабайт и установила предельную длину имени файла в 255 символов.

Однако, несмотря на успех новой файловой системы, тем не менее, оставалось еще довольно много нерешенных проблем. К примеру, отсутствовала поддержка раздельного доступа, не было временных меток модификации данных. Необходимость решения данных задач и послужила мотивом для создания следующей версии расширенной файловой системы ext2 («Second Extended File System» ). ext2 была разработана в январе 1993 года, в ней также были реализованы соответствующие стандарту POSIX списки контроля доступа ACL и расширенные атрибуты файлов.

Логическая организация ext2

Граф иерархии каталогов ext2 представлен в виде сети. Это связано с тем, что один файл может входить сразу в несколько каталогов.

Все типы файлов имеют символьные имена. В иерархически организованных файловых системах, как правило, применяется три типа имен: простые, составные и относительные. Так и в ext2. В случае с простым именем, ограничение заключается в том что, его длина не должна превышать 255 символов, кроме того, в имени не должны присутствовать символ NULL и слеш.

Что касается символа NULL, то ограничения связаны с представлением строк в языке Си, в случае с символом слеш, все заключается в том, что он используются как разделительный символ между каталогами.

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

Атрибуты ext2:

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

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

Физическая организация ext2

Структура дискового раздела

В составе ext2 можно выделить следующее:

  • блоки и группы блоков;
  • индексный дескриптор;
  • суперблок.

Все пространство раздела диска разбивается на блоки фиксированного размера, блоки кратны размеру сектора (1024, 2048, 4096 или 8192 байт). Размер блока указывается при создании файловой системы на разделе диска. Всем блокам присвоены порядковые номера. Для уменьшения фрагментации и количества перемещений головок жесткого диска при чтении больших массивов данных блоки объединяются в группы.

Базовым понятием файловой системы является индексный дескриптор (также называют inode - information node ). Это специальная структура, содержащая информацию об атрибутах и физическом расположении файла. Индексные декрипторы объединены в таблицу, содержащуюся в начале каждой группы блоков. Суперблок — основной элемент файловой системы ext2. В нем содержится общая информация о файловой системе. Суперблок расположен в 1024 байтах от начала раздела. Целостность суперблока определяет работоспособность файловой системы. ОС создает несколько резервных копий суперблока - на случай повреждения раздела. В следующем блоке после суперблока располагается глобальная дескрипторная таблица — описание групп блоков в виде массива с общей информацией обо всех группах блоков.

Группа блоков

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

Битовая карта блоков — это система, в которой каждый бит информирует, отведен ли соответствующий ему блок какому-либо файлу. Если бит равен 1, то блок занят. Аналогичную функцию выполняет битовая карта индексных дескрипторов: она показывает, какие именно индексные дескрипторы заняты, а какие нет. Ядро Linux старается равномерно распределить inode каталогов по группам, а inode файлов - переместить в группу с родительским каталогом. Все оставшееся место, фигурирующее в таблице в качестве данных, отводится для хранения файлов.

Система адресации данных

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

ext2 применяет следующую схему адресации блоков файла. Для хранения адреса файла выделено 15 полей, каждое из которых состоит из 4 байт. Если файл умещается в 12 блоков, то номера соответствующих кластеров перечисляются в первых двенадцати полях адреса. Если размер файла превышает 12 блоков, то следующее поле содержит адрес кластера, в котором могут быть расположены номера следующих блоков файла. Так, триннадцатое поле применяется для косвенной адресации.

При максимальном размере блока в 4096 байт кластер, соответствующий 13-му полю, может содержать до 1024 номеров следующих блоков файла. Если размер файла превышает 12+1024 блоков, то используется 14-е поле, в котором находится адрес кластера, содержащего 1024 номеров кластеров, каждый из которых ссылается на 1024 блока файла. Здесь применяется уже двойная косвенная адресация. А если файл включает более 12+1024+1048576 блоков, то применяется последнее 15-е поле для тройной косвенной адресации.

Такая система адресации позволяет при максимальном размере блока в 4096 байт иметь файлы, размером свыше 2 TB.

Как и в любой файловой системе UNIX, в составе ext2 можно выделить следующие составляющие:

− блоки и группы блоков;

− индексный дескриптор;

− суперблок.

Всё пространство раздела диска разбивается на блоки фиксированного размера, кратные размеру сектора: 1024, 2048, 4096 или 8192 байт. Размер блока указывается при создании файловой системы на разделе диска. Меньший размер блока позволяет сэкономить место на жёстком диске, но также ограничивает максимальный размер файловой системы. Все блоки имеют порядковые номера. С целью уменьшения фрагментации и количества перемещений головок жёсткого диска при чтении больших массивов данных блоки объединяются в группы блоков.

Базовым понятием файловой системы является индексный дескриптор, или inode (англ. information node). Это специальная структура, которая содержит информацию об атрибутах и физическом расположении файла. Индексные дескрипторы объединены в таблицу, которая содержится в начале каждой группы блоков.

Рисунок 10 - Обобщенная структурная схема ФС ext2

Суперблок - основной элемент файловой системы ext2. Он содержит общую информацию о файловой системе:

общее число блоков и индексных дескрипторов в файловой системе,

число свободных блоков и индексных дескрипторов в файловой системе,

размер блока файловой системы,

количество блоков и индексных дескрипторов в группе блоков,

размер индексного дескриптора,

идентификатор файловой системы.

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

Все блоки раздела ext2 разбиваются на группы блоков. Для каждой группы создаётся отдельная запись в глобальной дескрипторной таблице, в которой хранятся основные параметры:

номер блока в битовой карте блоков,

номер блока в битовой карте inode,

номер блока в таблице inode,

число свободных блоков в группе,

число индексных дескрипторов, содержащих каталоги.

Битовая карта блоков - это структура, каждый бит которой показывает, отведён ли соответствующий ему блок какому-либо файлу. Если бит равен 1, то блок занят. Аналогичную функцию выполняет битовая карта индексных дескрипторов, которая показывает, какие именно индексные дескрипторы заняты, а какие нет. Ядро Linux, используя число индексных дескрипторов, содержащих каталоги, пытается равномерно распределить inode каталогов по группам, а inode файлов старается по возможности переместить в группу с родительским каталогом. Все оставшееся место, обозначенное в таблице как данные, отводится для хранения файлов.

Файловая система ext2 использует следующую схему адресации блоков файла. Для хранения адреса файла выделено 15 полей, каждое из которых состоит из 4 байт. Если файл умещается в 12 блоков, то номера соответствующих кластеров непосредственно перечисляются в первых двенадцати полях адреса. Если размер файла превышает 12 блоков, то следующее поле содержит адрес кластера, в котором могут быть расположены номера следующих блоков файла. Таким образом, 13-е поле используется для косвенной адресации.

При максимальном размере блока в 4096 байт кластер, соответствующий 13-му полю, может содержать до 1024 номеров следующих блоков файла. Если размер файла превышает 12+1024 блоков, то используется 14-е поле, в котором находится адрес кластера, содержащего 1024 номеров кластеров, каждый из которых ссылается на 1024 блока файла. Здесь применяется уже двойная косвенная адресация. И наконец, если файл включает более 12+1024+1048576 блоков, то используется последнее 15-е поле для тройной косвенной адресации.

Данная система адресации позволяет при максимальном размере блока в 4096 байт иметь файлы, размер которых превышает 2 ТБ.

ext3 или ext3fs - журналируемая файловая система, используемая в операционных системах на ядре Linux. Основана на ФС ext2.

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

Стандартом предусмотрено три режима журналирования:

writeback: в журнал записываются только метаданные файловой системы, то есть информация о её изменении. Не может гарантировать целостности данных, но уже заметно сокращает время проверки по сравнению с ext2;

ordered: то же, что и writeback, но запись данных в файл производится гарантированно до записи информации о изменении этого файла. Немного снижает производительность, также не может гарантировать целостности данных (хотя и увеличивает вероятность их сохранности при дописывании в конец существующего файла);

journal: полное журналирование как метаданных ФС, так и пользовательских данных. Самый медленный, но и самый безопасный режим; может гарантировать целостность данных при хранении журнала на отдельном разделе (а лучше - на отдельном жёстком диске).

Файловая система ext3 может поддерживать файлы размером до 1 ТБ. С Linux-ядром 2.4 объём файловой системы ограничен максимальным размером блочного устройства, что составляет 2 терабайта. В Linux 2.6 (для 32-разрядных процессоров) максимальный размер блочных устройств составляет 16 ТБ, однако ext3 поддерживает только до 4 ТБ.

ext4 - файловая система, основанная на ext3 и совместимая с ней (прямо и обратно). Отличается от ext3 поддержкой extent"ов, групп смежных физических блоков, управляемых как единое целое; повышенной скоростью проверки целостности и рядом других усовершенствований.

Новые возможности ext4 (в сравнении с ext3):

Использование экстентов. В файловой системе ext3 адресация данных выполнялась традиционным образом, поблочно. Такой способ адресации становится менее эффективным с ростом размера файлов. Экстенты позволяют адресовать большое количество (до 128 MB) последовательно идущих блоков одним дескриптором. До 4х указателей на экстенты может размещаться непосредственно в inode, что достаточно для файлов маленького и среднего размера.

48-битные номера блоков. При размере блока 4K это позволяет адресовать до одного экзабайта (2 48 *4KB = 2 50 *1KB = 2 60 B = 1 EB).

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

Отложенное выделение блоков (delayed allocation). Выделение блоков для хранения данных файла происходят непосредственно перед физической записью на диск (например, при вызове sync), а не при вызове write. В результате, операции выделения блоков можно делать не по одной, а группами, что в свою очередь минимизирует фрагментацию и ускоряет процесс выделения блоков. С другой стороны, увеличивает риск потери данных в случае внезапного пропадания питания.

Превышен лимит в 32000 каталогов.

Резервирование inode"ов при создании каталога (directory inodes reservation). При создании каталога резервируется несколько inode"ов. Впоследствии, при создании файлов в этом каталоге сначала используются зарезервированные inode"ы, и если таких не осталось, выполняется обычная процедура.

Размер inode. Размер inode (по умолчанию) увеличен с 128 до 256 байтов. Это дало возможность реализовать те преимущества, которые перечислены ниже.

Временные метки с наносекундной точностью (nanosecond timestamps). Более высокая точность времён, хранящихся в inode. Диапазон хранящихся времён тоже расширен: если раньше верхней границей хранимого времени было 18 января 2038 года, то теперь это 25 апреля 2514 года.

Версия inode. В inode появился номер, который увеличивается при каждом изменении inode файла.

Хранение расширенных атрибутов в inode (EA in inode). Хранение расширенных атрибутов, таких как ACL, атрибутов SELinux и прочих, позволяет повысить производительность. Атрибуты, для которых недостаточно места в inode, хранятся в отдельном блоке размером 4KB.

Контрольное суммирование в журнале (Journal checksumming). Контрольные суммы журнальных транзакций. Позволяют лучше найти и (иногда) исправить ошибки при проверке целостности системы после сбоя.

Предварительное выделение (persistent preallocation). Сейчас для того, чтобы приложению гарантированно занять место в файловой системе, оно заполняет его нулями. В ext4 появилась возможность зарезервировать множество блоков для записи и не тратить на инициализацию лишнее время. Если приложение попробует прочитать данные, оно получит сообщение о том, что они не проинициализированы. Таким образом, несанкционированно прочитать удалённые данные не получится.

Дефрагментация без размонтирования (online Defragmentation).

Неинициализированные блоки (uninitialised groups). Позволяет ускорить проверку файловой системы. Блоки, отмеченные как неиспользуемые, проверяются группами, и детальная проверка производится, только если проверка группы показала, что внутри есть повреждения.

Лекция 12.

Тема: Каталоговые системы

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

Например, в Ms-Dos и Windows каталоги образуют древовидную структуру, а в UNIX – сетевую. В общем случае вычислительная система может иметь несколько дисковых устройств, даже в ПК всегда имеется несколько дисков: гибкий, винчестер, CD-ROM (DVD). Как организовать хранение файлов в этом случае?

Рис. Каталоговые системы

Первое решение состоит в том, что на каждом из устройств размещается автономная файловая система, т.е. файлы, находящиеся на этом устройстве, описываются деревом каталогов, никак не связанным с деревьями каталогов на других устройствах. В таком случае для однозначной идентификации файла пользователь вместе с составным символьным именем файла должен указывать идентификатор логического устройства. Примером такого автономного существования может служить MS-DOS, Windows 95/98/Me/XP.

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

В ОС UNIX монтирование осуществляется следующим образом. Среди всех имеющихся логических дисковых устройств выделяется одно, называемое системным. Пусть имеются две файловые системы, расположенные на разных логических дисках, причем один из дисков является системным (рис. 7.12).

Файловая система, расположенная на системном диске, называется корневой. Для связи иерархий файлов в корневой файловой системе выбирается некоторый существующий каталог, в данном примере – каталог loc. После выполнения монтирования выбранный каталог loc становится корневым каталогом второй файловой системы. Через этот каталог монтируемая файловая система подсоединяется как поддерево к общему дереву.

Рис. Монтирование

Атрибут

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

Атрибут Значение
Тип файла Обычный, каталог, специальный и т. д.
Владелец файла Текущий владелец
Создатель файла Идентификатор пользователя, создавшего файл
Пароль Пароль для получения доступа к файлу
Время Создания, последнего доступа, последнего изменения
Текущий размер файла Количество байт в записи
Максимальный размер Количество байт, до которого можно увеличивать размер файла
Флаг "только чтение" 0 – чтение / запись, 1 – только чтение
Флаг "скрытый" 0 – нормальный, 1 – не показывать в перечне файлов каталога
Флаг "системный" 0 – нормальный, 1 – системный
Флаг "архивный" 0 – заархивирован, 1 – требуется архивация
Флаг ASCII / двоичный 0 – ASCII, 1 – двоичный
Флаг произвольного доступа 0 – только последовательный доступ, 1 – произвольный доступ
Флаг "временный" 0 – нормальный, 1 – удаление после окончания работы процесса
Позиция ключа Смещение до ключа в записи
Длина ключа Количество байт в поле ключа

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

Значения атрибутов файлов могут содержаться в каталогах, как это сделано, например, в MS-DOS (рис. 7.7). Другим вариантом является размещение атрибутов в специальных таблицах, в этом случае в каталогах содержатся ссылки на эти таблицы.

Рис. 7. Атрибуты файлов MS DOS