Анатомія файлової системи Linux

Якщо говорити про файлових системах, Linux в порівнянні з іншими операційними системами нагадує швейцарський армійський ніж. Linux підтримує безліч файлових систем, від журналіруемих до кластерних і систем з шифруванням. Linux – це чудова платформа для використання стандартних і екзотичних файлових систем, а також для розробки файлових систем. У цій статті розглядається віртуальна файлова система (VFS) ядра Linux, яка іноді називається віртуальним комутатором файлової системи, а також наводиться огляд деяких основних структур, що зв'язують файлові системи.

Базова архітектура файлової системи


Архітектура файлової системи Linux являє собою цікавий зразок абстрагування складнощів. Єдиний набір функцій API дозволяє підтримувати безліч файлових систем на безлічі пристроїв зберігання. Візьмемо, наприклад, виклик функції read, Яка дозволяє зчитувати певну кількість байт з заданого дескриптора файлу. Функція read нічого не знає про типи файлових систем, чи то ext3 або NFS. Вона також не знає про носія, на якому змонтована файлова система, будь то диск, підключений по інтерфейсу ATA, послідовному інтерфейсу SCSI (SAS) або послідовному інтерфейсу ATA (SATA). І, незважаючи на це, при виклику функції read для відкритого файлу ми отримуємо, як нам і хотілося, дані. У цій статті буде описано, як це досягається, а також будуть розглянуті основні структури рівня файлової системи Linux.


Що таке файлова система?


Я почну з найбільш загального питання – визначення файлової системи. Файлової системою називається деяка організація даних і метаданих на пристрої зберігання. Ви розумієте, що при такому нечіткому визначенні код, його реалізує, буде дуже цікавим. Як я вже згадував, існує безліч типів носіїв і файлових систем. Варто очікувати, що при такому різноманітті інтерфейс файлової системи Linux буде реалізований з використанням багаторівневої архітектури, яка відділяє рівень інтерфейсу користувача від реалізації файлової системи і від драйверів, які керують пристроями зберігання.







 



Файлові системи як протоколи
Альтернативний спосіб полягає в тому, щоб розглядати файлову систему як протокол. Так само, як мережеві протоколи (наприклад, IP) надають сенс потоків даних, що передаються через Інтернет, файлова система надає значення даними на певному носії.
 

Монтування


Процес зв'язування файлової системи з пристроєм в Linux називається монтуванням (mounting). Для підключення файлової системи до існуючої ієрархії файлових систем (корені) використовується команда mount. При монтуванні вказується файлова система, її тип і точка монтування.


Щоб продемонструвати можливості рівня файлової системи Linux (і монтування), створимо файлову систему у файлі, розташованому в існуючій файловій системі. Це можна зробити шляхом створення файлу заданого розміру з допомогою dd (Копіювання файлу з джерела / dev / zero) – іншими словами, Ініціалізіруем файл нулями, як показано в лістингу 1.


Лістинг 1. Створення ініціалізованої файлу





$ dd if=/dev/zero of=file.img bs=1k count=10000
10000+0 records in
10000+0 records out
$

Тепер у нас є файл file.img розміром 10 МБ. Зв'яжемо з файлом блоковий пристрій-заглушку (loop) за допомогою команди losetup (Щоб він виглядав як блоковий пристрій, а не як звичайний файл файлової системи):





$ losetup /dev/loop0 file.img
$

Тепер, маючи файл, який виглядає як блоковий пристрій (представлений / dev/loop0), створимо на цьому пристрої файлову систему за допомогою mke2fs. Ця команда створює нову файлову систему ext2 визначеного нами розміру, як видно з лістингу 2.


Лістинг 2. Створення файлової системи ext2 на пристрої loop





$ mke2fs -c /dev/loop0 10000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 1250, rsv_gdb = 39
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
2512 inodes, 10000 blocks
500 blocks (5.00%) reserved for the super user

$

Тепер файл file.img, представлений блоковим пристроєм (/dev/loop0), Змонтований у точці / mnt/point1 за допомогою команди mount. Зверніть увагу, що зазначений тип файлової системи – ext2. Після монтування ви можете звертатися до точки монтування як до нової файлової системи за допомогою команди ls, Як видно з лістингу 3.


Лістинг 3. Створення точки монтування та монтування файлової системи за допомогою пристрою loop





$ mkdir /mnt/point1
$ mount -t ext2 /dev/loop0 /mnt/point1
$ ls /mnt/point1
lost+found
$

Як показано в лістингу 4, цей процес можна продовжити, створюючи новий файл в новій файлової системі, пов'язуючи його з пристроєм loop і створюючи в ньому ще одну файлову систему.

Лістинг 4. Створення нової файлової системи loop в існуючій





$ dd if=/dev/zero of=/mnt/point1/file.img bs=1k count=1000
1000+0 records in
1000+0 records out
$ losetup /dev/loop1 /mnt/point1/file.img
$ mke2fs -c /dev/loop1 1000
mke2fs 1.35 (28-Feb-2004)
max_blocks 1024000, rsv_groups = 125, rsv_gdb = 3
Filesystem label=

$ mkdir /mnt/point2
$ mount -t ext2 /dev/loop1 /mnt/point2
$ ls /mnt/point2
lost+found
$ ls /mnt/point1
file.img lost+found
$

З цього простого прикладу легко зрозуміти, наскільки великі можливості надає файлова система (і пристрій loop) в Linux. Аналогічним чином за допомогою пристрою loop можна створювати у файлі файлові системи з шифруванням. Це може бути корисно для захисту ваших даних; при необхідності такий файл можна швидко змонтувати за допомогою пристрою loop.

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


Тепер, коли ви побачили створення файлової системи в дії, давайте повернемося до архітектури рівня файлової системи Linux. У цій статті файлова система Linux розглядається з двох точок зору. Перша точка зору – це Високорівнева архітектура. Друга точка зору розглядає рівень файлової системи глибше і ширше, з боку основних структур, що складають його.


Архітектура високого рівня


Хоча більша частина коду файлової системи реалізована в ядрі (за винятком файлових систем простору користувача, про які я розповім нижче), архітектура, показана на малюнку 1, характеризує відносини між основними компонентами файлової системи, як у просторі користувача, так і в ядрі.


Малюнок 1. Архітектурне подання компонентів файлової системи Linux

У просторі користувача розміщуються додатки (у цьому прикладі – користувач файлової системи) і бібліотека GNU C (glibc), які надають інтерфейс для виклику файлової системи (відкриття, читання, запис, закриття). Інтерфейс системних викликів діє як комутатор, спрямовує системні виклики з простору користувача у відповідну точку простору ядра.


VFS є основним інтерфейсом до файлових систем нижнього рівня. Цей компонент експортує набір інтерфейсів і після цього абстрагує їх в окремі файлові системи, образ поведінки яких може бути дуже різним. Для об'єктів файлової системи (вузлів inodes і записів dentries) існують два кешу, про які я скоро розповім. Кожен з них надає пул нещодавно використаних об'єктів файлової системи.


Реалізація кожної файлової системи, наприклад, ext2, JFS і так далі, експортує загальний масив інтерфейсів, який використовується (і очікується) VFS. Буферний кеш буферизує запити між файловими системами і блочними пристроями, якими вони можуть управляти. Наприклад, через буферний кеш проходять запити на читання і запис до драйверів пристроїв. Це дозволяє кешувати запити для більш швидкого доступу (Замість звернення до фізичного пристрою). Буферний кеш управляється набором списків останніх використаних елементів (least recently used, LRU). Зверніть увагу, що командою sync можна скинути буферний кеш на носій (примусово відправити всі незаписані дані на драйвери пристроїв і, надалі, на пристрої зберігання).







 



Що таке блоковий пристрій?
Блоковим називається пристрій, дані на яку і з якого передаються блоками (наприклад, секторами диска), і яке підтримує такі атрибути, як буферизація і прямий доступ (пристрій не вимагає послідовного доступу до блоків під час читання – будь-який блок може бути доступний в будь-який час). До блоковим пристроїв відносяться жорсткі диски, CD-ROM і диски в оперативній пам'яті. Вони є протилежністю символьним пристроїв, відмінність яких полягає в тому, що у них немає носія з фізичної адресацією. До символьним пристроїв відносяться послідовні порти і стрічкові пристрої, в яких дані передаються посимвольно.
 

Це був загальний погляд на компоненти файлової системи і VFS. Давайте тепер розглянемо основні структури, складові цю підсистему.


Основні структури


У Linux всі файлові системи розглядаються з точки зору загального набору об'єктів. До цих об'єктів відносяться системні блоки, вузли inode, записи dentry і файли. Коренем кожної файлової системи є системний блок, який описує і підтримує стан файлової системи. Кожен об'єкт, з яким працює файлова система (файл або директорія) представлений в Linux вузлом inode. Вузол inode зберігає в собі всі метадані для керування об'єктами файлової системи (в тому числі і можливих операціях з ним). Інше безліч структур, яке називають записами dentry, використовується для здійснення перетворення між назвами і вузлами inode, для чого існує кеш директорій, в якому зберігаються останні використані запису. У записах dentry також зберігаються відносини між папками й файлами для обходу файлових систем. І, нарешті, файл VFS представляє собою відкритий файл (містить стан відкритого файлу, в тому числі зсув для запису і т.п.).


Рівень віртуальної файлової системи


VFS діє як кореневої рівень інтерфейсу файлової системи. VFS стежить за всіма підтримуваними і всіма змонтованими на даний момент файловими системами.


Файлові системи в Linux можна динамічно додавати й видаляти за допомогою кількох функцій реєстрації. У ядрі зберігається список підтримуваних файлових систем, який можна переглянути з простору користувача за допомогою файлової системи / proc. У цьому віртуальному файлі також показані пристрої, зв'язані на поточний момент з файловими системами. Для того, щоб додати нову файлову систему в Linux, викликається register_filesystem. Ця команда має один аргумент – посилання на структуру файлової системи (file_system_type), Яка визначає назву файлової системи, набір атрибутів і дві функції системних блоків. Файлова система також може бути незареєстрованою.


Реєстрація нової файлової системи полягає в додаванні цієї системи і відноситься до неї інформації в список file_systems (див. малюнок 2 і linux / include / linux / mount.h). Цей список визначає підтримувані файлові системи. Переглянути його можна, ввівши в командному рядку cat /proc/filesystems.


Малюнок 2. Файлова система, зареєстрована в ядрі

Інший структурою, підтримуваної VFS, є змонтовані файлові системи (див. малюнок 3). Вона надає список змонтованих на даний момент файлових систем (див. linux / include / linux / fs.h). Вона посилається на структуру системного блоку superblock, Про який я розповім нижче.


Малюнок 3. Список змонтованих файлових систем

Системний блок


Системним блоком (superblock) називається структура, що представляє файлову систему. У неї входить інформація, необхідна для керування файловою системою під час роботи. До такої інформації належить назва файлової системи (наприклад, ext2), розмір файлової системи і її стан, посилання на блоковий пристрій та інформацію метаданих (наприклад, списки вільних блоків і т.п.). Як правило, системний блок зберігається на носії, але якщо його немає, він може бути створений в реальному часі. Структуру системного блоку (див. малюнок 4) можна знайти в. / Linux / include / linux / fs.h.


Малюнок 4. Структура системного блоку і робота вузлів inode

Одним з найважливіших елементів системного блоку є визначення його операцій. Ця структура визначає набір функцій для управління вузлами inodes файлової системи. Наприклад, inodes можуть виділятися з допомогою alloc_inode і видалятися з допомогою destroy_inode. Ви можете зчитувати і записувати inodes за допомогою команд read_inode і write_inode і синхронізувати файлову систему за допомогою команди sync_fs. Структура super_operations розташована в. / Linux / include / linux / fs.h. У кожній файловій системі є власні методи inode, які реалізують роботу і виконують загальну абстракцію на рівень VFS.


Вузли inode і dentry


Вузол inode представляє об'єкт файлової системи з унікальним ідентифікатором. Кожна файлова система надає методи перетворення імен файлів в унікальні ідентифікатори inode і потім – у лінки на inode. На рисунку 5 показана частина структури inode разом з кількома пов'язаними структурами. Зверніть увагу, зокрема, на inode_operations і file_operations. Кожна з цих структур посилається на окремі операції, які можуть виконуватися з inode. Наприклад, inode_operations визначає операції, які працюють напряму з inode, а file_operations відноситься до методів, які працюють з файлами і директоріями (стандартні системні виклики).


Малюнок 5. Структура inode та пов'язані з нею операції

Нещодавно використані вузли inodes і запису dentries зберігаються в кеші inode і кеші директорій відповідно. Зверніть увагу, що кожному inode в кеші inode відповідає запис dentry в кеші директорій. Структури inode і dentry визначені ст. / linux / include / linux / fs.h.


Буферний кеш


За винятком окремих реалізацій файлових систем (які можна знайти в. / Linux / fs), в нижній частині рівня файлової системи розташовується буферний кеш. Тут зберігаються запити на читання і запис від окремих файлових систем і фізичних пристроїв (за допомогою драйверів пристроїв). З міркувань продуктивності в Linux передбачено кеш запитів, що дозволяє не звертатися по кожному запиту до фізичного пристрою. Замість цього в ньому кешуються останні використані буфери (сторінки), які можуть бути швидко надані окремим файловим системам.


Цікаві файлові системи


У цій статті не розповідається про конкретні окремих файлових системах, доступних в Linux, але тут буде корисно їх згадати, хоча б мимохідь. Linux підтримує безліч файлових систем, починаючи від найстаріших – MINIX, MS-DOS і ext2. Linux також підтримує нові файлові системи з журналювання, до яких відносяться ext3, JFS і ReiserFS. Крім того, в Linux підтримуються файлові системи з шифруванням, такі як CFS, і віртуальні файлові системи, такі як / proc.


І, нарешті, окремо варто відзначити файлову систему Filesystem in Userspace або FUSE. Це цікавий проект, який дозволяє вам направляти запити до файлової системи через VFS назад у простір користувача. Тому, якщо ви замислювалися про створення власної файлової системи, то це відмінний шанс для того, щоб почати.


Висновок


Незважаючи на те, що реалізація файлової системи аж ніяк не тривіальна, вона є відмінним прикладом розширюваної і масштабованої архітектури. Архітектура файлової системи розвивалася роками, при цьому підтримуючи безліч типів файлових систем і безліч типів пристроїв зберігання. Буде цікаво подивитися на розвиток в найближчому майбутньому файлової системи Linux, що використовує архітектуру додатків з кількома рівнями перетворення функцій.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*