Файловая подсистема

UNIX Лекция 1 UNIX Лекция 2 UNIX Лекция 3 UNIX Лекция 4 UNIX Лекция 5 UNIX Лекция 6 UNIX Лекция 7 UNIX Лекция 8 UNIX Лекция 9 : ---->> UNIX L1-9

А. Робачевский - ОC UNIX <<----- PDF ст. 279-321

Керниган, Пайк - UNIX <<------PDF

Б. Керниган, Д. Ритчи - Язык программирования С <<-------PDF

Таненбаум - Операционные системы <<------PDF

Лав Р - Системное программирование <<------PDF

Ю.Вахалия UNIX изнутри <<---PDF ст.384

Маршал Кирк МакКузик FreeBSD - Архитектура и реализация <<---PDF ст.351

Оглавление страницы

Файловая подсистема

Базовая файловая система System V

Суперблок

Индексные дескрипторы

Имена файлов

Недостатки и ограничения

Файловая система BSD UNIX

Каталоги

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

Виртуальные индексные дескрипторы

Монтирование файловой системы

Трансляция имен

Доступ к файловой системе

Файловые дескрипторы

Файловая таблица

Блокирование доступа к файлу

Буферный кэш

Внутренняя структура буферного кэша

Операции ввода/вывода

Кэширование в SVR4

Целостность файловой системы


Морис Дж. Бах - Архитектура операционной системы UNIX:

THE DESIGN OF THE UNIX § 1-3

THE DESIGN OF THE UNIX § 4-5 <<--------тут

http://www.intuit.ru/studies

Организация Файловых систем часть - 1

14:10 - 18:44--> каталог; 43:00 - 52:00--> адресация (прямая, двойная, тройная), иноды. UNIX. Профессиональное программирование ст.137

Организация Файловых систем часть - 2

05:40 -13:00 ---> каталог, mount. 15:29 - 28:36 ---> линки, хард-линки, сим-линки.



СИСТЕМНЫЕ ОПЕРАЦИИ ДЛЯ РАБОТЫ С ФАЙЛОВОЙ СИСТЕМОЙ

Файловая подсистема

Файловая подсистема — обеспечивает унифицированный интерфейс доступа к данным, расположенным на дисковых накопителях, и к периферийным устройствам. Одни и те же функции ореn, read, write, могут использоваться как при чтении или записи данных на диск, так и при выводе текста на принтер или терминал.

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

Файловая подсистема — обеспечивает перенаправление запросов, адресованных периферийным устройствам, соответствующим модулям подсистемы ввода/вывода

Основополагающие реализации UNIX:

SVR4 — System V Releas 4 (Novel 1990) SVR{1983..1990}

4xBSD — Berkeley Software Distribution 4xBSD{1980..1994}

Mach https://ru.wikipedia.org/wiki/Mach Mach.x{1985..1994}

БОЛЬШИНСТВО данных в операционной системе UNIX хранится в файлах, организованных в виде дерева и расположенных на некотором носителе данных. Обычно это локальный жесткий диск, хотя специальный тип файловой системы — NFS (Network File System) обеспечивает хранение файлов также и на удаленном компьютере. Файловая система также может располагаться и на других типах носителей , и тут можно упомянуть про объединенные файловые системы UnionFS и AuFS реализующих технологии "Каскадно-объединенного монтирования", "ярким" примером реализации которой является Docker , проявление технологий известных практически от рождения Nix-систем(BSD-1990г.), Unix продолжает раскрывать свой потенциал подтверждая определений "Unix - все файлы" и процессы, однако для простоты изложения мы рассмотрим традиционную файловую систему UNIX, расположенную на обычном жестком диске компьютера. Исконной файловой системой UNIX System V является s5fs(System V file system). Файловая система, разработанная в Беркли, FFS(Fast File System), появилась позже, в версии 4.2BSD UNIX. По сравнению с s5fs она обладает лучшей производительностью, функциональностью и надежностью. Файловые системы современных версий UNIX имеют весьма сложную архитектуру, различную для разных версий. Несмотря на это все они используют базовые идеи, заложенные разработчиками UNIX в AT&T и Калифорнийском университете в Беркли. Поэтому ниже рассматриваются основные принципы организации файловой системы UNIX на примере базовых систем System V (s5fs) и BSD (FFS), которые, и сегодня поддерживаются в большинстве версий UNIX.

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

Когда появилась файловая система FFS, архитектура UNIX поддерживала работу только с одним типом файловой системы. Таким образом, создатели различных версий операционной системы UNIX вынуждены были выбирать одну файловую систему из нескольких возможных. Это неудобство было преодолено введением независимой или виртуальной файловой системы VFS — архитектуры, позволяющей обеспечивать работу с несколькими "физическими" файловыми системами, как одинаковых так и различных типов и в этом смысл существования "VFS". VFS виртуальный коммутатор файловой системы (virtual filesystem switch) этот уровень абстракции поверх конкретной реализации файловой системы, декларирует программный интерфейс между ядром и конкретной файловой системой, таким образом, при котором для добавления поддержки новой файловой системы не требуется вносить изменений в ядро операционной системы.

Базовая файловая система System V

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

Суперблок (superblocк). Содержит общую информацию о файловой системе, например, об ее архитектуре, общем числе блоков и индексных дескрипторов, или метаданных (inode).

Массив индексных дескрипторов (ilist). Содержит метаданные всех файлов файловой системы. Индексный дескриптор содержит статусную информацию о файле и указывает на расположение данных этого файла. Ядро обращается к inode по индексу в массиве ilist. Один inode является корневым (root) inode файловой системы, через него обеспечивается доступ к структуре каталогов и файлов после монтирования файловой системы. Размер массива ilist является фиксированным и задается при создании файловой системы. Таким образом, файловая система s5fs имеет ограничение по числу файлов, которые могут храниться в ней, независимо от размера этих файлов.

Блоки хранения данных. Данные обычных файлов и каталогов хранятся в блоках. Обработка файла осуществляется через inode, содержащего ссылки на блоки данных. Блоки хранения данных занимают большую часть дискового раздела, и их число определяет максимальный суммарный объем файлов данной файловой системы. (Размер блока кратен 512 байтам.)

Суперблок

http://www.opennet.ru/docs

http://ossolaris.ru

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

Суперблок содержит следующую информацию:

  • (s_type) Тип файловой системы

  • (s_fsize) Размер файловой системы в логических блоках, включая сам суперблок, (ilist) и блоки хранения данных

  • (s_isize) Размер массива индексных дескрипторов

  • (s_tfree) Число свободных блоков, доступных для размещения

  • (s_tinode) Число свободных inode, доступных для размещения

  • Флаги (флаг модификации s_fmod, флаг режима монтирования s_fronly)

  • Размер логического блока (512, 1024, 2048)

  • Список номеров свободных inode

  • Список адресов свободных блоков

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

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

Индексные дескрипторы

https://sites.google.com/The Design of the UNIX - INODES

(Базовая файловая система UNIX System V <<---PDF)

https://ru.wikipedia.org/wiki/Inode

http://ru.bmstu.wiki/Inode <---------- тут!

http://parallel.uran.ru <<< ------------

А. Робачевский - Операционная система UNIX (ст 282) <<------PDF

Таненбаум - Современные операционные системы <<------PDF

Индексные дескрипторы фундаментальное понятие в понимании операционной системы, можно сказать, что индексные дескрипторы – это и есть файлы, их системное имя. Единственное назначение иерархии каталогов заключается в предоставлении удобных имен файлов. Внутреннее системное имя файла – это номер его индексного дескриптора (inumber), хранящего информацию о файле. (целочисленные десятичные значения номеров индексных дескрипторов покажет команда ls с ключом -i , утилита stat - display file or file system status покажет более полную информацию о файле и его атрибутах)

Индексный дескриптор, или inode (раньше было i-node, со временем дефис исчез), содержит информацию о файле, необходимую для обработки данных, т. е. метаданные файла. Каждый файл ассоциирован с одним inode, хотя может иметь несколько имен в файловой системе, каждое из которых указывает на один и тот же inode. Индексный дескриптор не содержит:

  • имени файла, которое содержится в блоках хранения данных каталога

  • содержимого файла, которое размещено в блоках хранения данных

При открытии файла ядро помещает копию дискового inode в память, в таблицу in-core inode, которая содержит несколько дополнительных полей. Структура дискового inode (struct di-node) приведена ниже. Основные поля дискового inode (приставка di_) следующие:

Пример индексного узла с прямой, двойной и тройной адресацией:

Поле di_mode хранит несколько атрибутов файла:тип файла (IFREG для обычных файлов, IFDIR для каталогов, IFBLK или IFCHR для специальных файлов блочных и символьных устройств соответственно), права доступа к файлу для трех классов пользователей и дополнительные атрибуты выполнения (SUID, SGID и sticky bit)

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

  • время последнего доступа (di_atime)

  • время последней модификации содержимого файла (di_mtime)

  • время последней модификации метаданных файла (di_ctime)

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

Массив (некоторое количество записей) имеет фиксированный размер и состоит из 13 элементов.

(128 байт в UFS(Unix File System), 256 в UFS2- 64-разрядная версия) Каждая запись однозначно соответствует одному файлу, как реально существующему, так и только могущему быть созданным. При этом первые 10 элементов адресуют непосредственно блоки хранения данных файла. Одиннадцатый элемент адресует блок, в свою очередь содержащий адреса блоков хранения данных. Двенадцатый элемент указывает на дисковый блок, также хранящий адреса блоков, каждый из который адресует блок хранения данных файла. Тринадцатый элемент используется для тройной косвенной адресации, когда для нахождения адреса блока хранения данных файла используются три дополнительных блока.

Такой подход позволяет при относительно небольшом фиксированном размере индексного дескриптора поддерживать работу с файлами, размер которых может изменяться от нескольких байтов до десятка мегабайтов. Для относительно небольших файлов (до 10 Кбайт при размере блока 1024 байтов) используется прямая индексация, обеспечивающая максимальную производительность. Для файлов, размер которых не превышает 266 Кбайт (10 Кбайт + 256x1024), достаточно простой косвенной адресации. Наконец, при использовании тройной косвенной адресации можно обеспечить доступ к 16777216 блокам (256 x 256 x 256).

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

Множество программ, в (ОС) UNIX, часто используют номера индексных дескрипторов для обозначения файлов. Популярная встроенная программа проверки жестких дисков fsck - дефолт в BSD, или команда pfiles могут послужить в данном случае примерами, так как у них есть необходимость естественным образом конвертировать номера индексных дескрипторов в пути файлов и обратно. Это может быть дополнено использованием программы поиска файлов find с ключом -inum или командой ls с соответствующим ключом (которым на большинстве платформ является -i).

Как узнать номер inode, в котором располагается файл?

ls -i /bin/ls ----> 16416853 /bin/ls

df -hTi ----> сколько использовано и сколько свободно

df -i /var

stat /home -------> метаданные

Как найти имя файла по номеру inode?

find / -inum 22282928

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

<&Цифра Стандартный ввод связывается с файлом, дескриптор которого указан в параметре Цифра.

>&Цифра Стандартный вывод связывается с файлом, дескриптор которого указан в параметре Цифра.

Иноды могут 'закончиться'. В этом случае нельзя записать информацию на устройство, даже если там достаточно свободного места. (Стандартно, очень много мелких файлов..??? Надо подчистить....Проверить каталог /var/spool/clientmqueue)

od (octal dump – восьмеричный дамп) hd (hex dump - шестнадцатиричный дaмп)

http://docs.kpda.ru/index/octal dump http://citforum.ru/operating_systems/manpages/OD

http://docs.kpda.ru/index/hex dump http://bsdadmin.ru/mans-freebsd/ASII-dump-HD/

https://drive.google.com/file OD=sharing <<------------- примеры OD PDF

od — общепринятая утилита отладки, в данном случае будет удобно при помощи ее взглянуть на внутренность файла с точки зрения системы, однако если проводить эти "эксперименты" на Linux, то в силу новизны используемых файловых систем (ext2-3-4) это не s5fs или организации системных вызовов, утилита не покажет нам дамп каталога, что будет важно для понимания системного и читабельного имени файла, поэтому будем использовать BSD где то же однако не явно (если это не s5fs) но можно продемонстрировать связь inode-ов с именем файла по средствам восьмиричного-шеснадцатиричного дампа (о чем ниже) , реализации файловых систем современных версий отошли от записей фиксированной длины (в них формат файла каталога более сложный) и не ограничивают длину имени файла 14-ю символами, как это было когда то, FFS (Fast File System), появившаяся впервые в BSD 4.2, допускает уже 255-символьные имена файлов. Команда od без параметров выводит дамп файла 16-битными порциями или 2-байтовыми словами.

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

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

$ od -cx

od test chek tab

0000000 o d t e s t c h e k \t t a b

646f 7420 7365 2074 6863 6b65 7409 6261

^C

$

В общем виде формат запуска утилиты можно представить так: (параметры в скобках не обязательны)

od [- опции] [-A в каком формате будет колонка позиций ] [-j начать с какого байта ] [-N длина ] [-t формат вывода ] [файл]

http://pubs.opengroup.org/onlinepubs http://www.thegeekstuff.com https://www.opennet.ru/MAN

Синтаксис: od [-bcdox] [файл]

Описание: Вывод содержимого файла в указанном формате.

Опции, коротко:

Выходные форматы:

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

-a синоним -t a, именованные символы, старший бит игнорируется

-b синоним -t o1, восьмеричные байты

-c синоним -t c, печатные символы или управляющие последовательности

с обратной косой чертой

-d синоним -t u2, беззнаковые десятичные двухбайтовые единицы

-f синоним -t fF, числа с плавающей точкой

-i синоним -t dI, десятичные целые

-l синоним -t dL, десятичные длинные целые

-o синоним -t o2, восьмеричные двухбайтовые единицы

-s синоним -t d2, десятичные двухбайтовые единицы

-x синоним -t x2, шестнадцатеричные двухбайтовые единицы


ТИП составляется из одного или нескольких следующих спецификаций:

a именованный символ, старший бит игнорируется

c печатный символ или управляющая последовательность

d[ЧИСЛО] знаковое десятичное целое размером заданное ЧИСЛО байт

f[ЧИСЛО] число с плавающей точкой размером заданное ЧИСЛО байт

o[ЧИСЛО] восьмеричное целое размером заданное ЧИСЛО байт

u[ЧИСЛО] беззнаковое десятичное целое размером заданное ЧИСЛО байт

x[ЧИСЛО] шестнадцатеричное целое размером заданное ЧИСЛО байт

$ cat > input

now is the time

for all

people

^C

$ od -c input

0000000 n o w i s t h e t i m e \n

0000020 f o r a l l \n p e o p l e \n

0000037

$ od -b input

0000000 156 157 167 040 151 163 040 164 150 145 040 164 151 155 145 012

0000020 146 157 162 040 141 154 154 012 160 145 157 160 154 145 012

0000037

$ od -cb input

0000000 n o w i s t h e t i m e \n

156 157 167 040 151 163 040 164 150 145 040 164 151 155 145 012

0000020 f o r a l l \n p e o p l e \n

146 157 162 040 141 154 154 012 160 145 157 160 154 145 012

0000037

$

В примере выше: параметр c - «интерпретировать байты как символы». Если задан параметр b, то будет показано и восьмеричное представление байтов.

Семизначные числа слева обозначают местоположение в файле – порядковый номер следующего выведенного символа, в восьмеричной записи. Шестнадцатеричная запись – параметр x, после каждой строки встречается символ с восьмеричным значением 012. Это ASCII символ новой строки, то есть то, что система помещает в поток ввода, когда пользователь нажимает клавишу Return. По соглашению, заимствованному из Си, представление символа новой строки выглядит как \n, но это просто условность, используемая такими программами, как od, для удобства чтения, на самом же деле величина, хранимая в файле, – это один байт 012.

Символ новой строки – это наиболее часто употребляемый специальный символ. Другие символы, сопоставленные некоторым операциям управления терминалом, включают в себя возврат на одну позицию (восьмеричное значение 010, выводится как \b), табуляцию (011, \t) и возврат каретки (015,\r). Важно различать значение, сохраняемое для символа в файле, и то, как он интерпретируется в различных ситуациях. Например, когда с клавиатуры вводится возврат на одну позицию (Backspace), если этот символ в конкретной системе служит для удаления, ядро интерпретирует его как отказ от предыдущего введенного символа. В итоге и символ возврата, и символ, стоявший перед ним, исчезают, но введение возврата на одну позицию отражается на терминале, курсор перемещается на одну позицию назад........

(Опция -A команды cat также позволяет увидеть, где расположены символы табуляции и конца строки)

Керниган, Пайк - UNIX. Программное окружение <<------(ст 62) PDF

hex редакторы <<-------- https://traditio.wiki https://ru.wikipedia.org/wiki/Hex

Имена файлов

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

Каталог файловой системы s5fs представляет собой таблицу, каждый элемент которой имеет фиксированный размер в 16 байтов: 2 байта хранят номер индексного дескриптора файла, а 14 байтов — его имя. Это накладывает ограничение на число inode, которое не может превышать 65 535. Также ограничена и длина имени файла: его максимальный размер — 14 символов. Структура каталога приведена на рисунке ниже. Первые два элемента каталога адресуют сам каталог (текущий каталог) под именем ''.''и родительский каталог под именем ''..''.

При удалении имени файла из каталога (например, с помощью команды rm), номер inode соответствующего элемента устанавливается равным Ø. Ядро обычно не удаляет такие свободные элементы, поэтому размер каталога не уменьшается даже при удалении файлов. Это является потенциальной проблемой для каталогов, в которые временно было помещено большое количество файлов. После удаления большинства из них размер каталога останется достаточно большим, поскольку записи удаленных файлов будут по-прежнему существовать. Иллюстрацию этого явления в SCO UNIX можно привести, применив команду hd (manpages/HD ), обеспечивающую вывод неинтерпретированного содержимого файла (шестнадцатеричный дамп). (hexdump)

$ hd .

0000 fc 0a 2e 00 00 00 00 00 00 00 00 00 00 00 00 00

0010 02 00 2е 2е 00 00 00 00 00 00 00 00 00 00 00 00

0020 33 72 6d 61 69 6с 00 00 00 00 00 00 00 00 00 00 3rmail

0030 0а 2с 4е 65 77 73 00 00 00 00 00 00 00 00 00 00 .,News

0040 33 7d 2е 6e 65 77 73 72 63 00 00 00 00 00 00 00 3}.newsrc

0050 00 40 62 69 6e 00 00 00 00 00 00 00 00 00 00 00 .@bin

0060 da 91 64 65 61 64 2е 6с 65 74 74 65 72 00 00 00 ..dead.letter...

0290 00 00 70 69 6e 65 72 63 30 30 30 37 36 39 00 00 ..pinerc000769..

02a0 00 00 30 35 6e 61 64 75 76 61 2е 6а 70 67 00 00 ..05naduva.jpg..

02b0 00 00 30 36 73 70 75 73 74 69 2е 6а 70 67 00 00 ..06spusti.jpg..

02с0 00 00 30 37 67 75 69 74 61 72 2е 6а 70 67 00 00 ..07guitar.jpg..

02d0 00 00 30 38 73 75 6e 73 65 74 2е 6а 70 67 00 00 ..08sunset.jpg..

02е0 00 00 37 31 72 6f 70 65 73 31 2е 6а 70 67 00 00 ..71ropes1.jpg..

$ ls

.newsrc

bin

dead.letter

News

mail

Можно заметить, что имен файлов, расположенных во второй части вывода команды hd на самом деле не существует — об этом свидетельствуют нулевые значения номеров inode, это же подтверждает вывод команды ls.

Следует обратить внимание, что справа представлена структура каталога файловой системы S5FS, в UFS, UFS2, FFS структура будет несколько иной .

Linux:

$ ls -a | hd

00000000 1b 5b 30 6d 1b 5b 30 31 3b 33 34 6d 2e 1b 5b 30 |.[0m.[01;34m..[0|

00000010 6d 2f 0a 1b 5b 30 31 3b 33 34 6d 2e 2e 1b 5b 30 |m/..[01;34m...[0|

00000020 6d 2f 0a 61 72 63 68 69 76 5f 66 69 6c 65 0a 1b |m/.archiv_file..|

00000030 5b 30 31 3b 33 32 6d 62 61 63 6b 66 75 6e 63 1b |[01;32mbackfunc.|

....................................................................

Недостатки и ограничения

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

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

Использование дискового пространства также не оптимально. Для увеличения производительности файловой системы более предпочтительным является использование блоков больших размеров. Это позволяет считывать большее количество данных за одну операцию ввода/вывода. Так, например, в UNIX SVR2 размер блока составлял 512 байтов, а в SVR3 — уже 1024 байтов. Однако поскольку блок может использоваться только одним файлом, увеличение размера блока приводит к увеличению неиспользуемого дискового пространства за счет частичного заполнения последнего блока файла. В среднем для каждого файла теряется половина блока.

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

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

Berkeley Fast File System, или FFS:

Файловая система BSD UNIX

http://mf.grsu.by/UchProc/livak/b_org/hard.htm <<<------- Физическая структура жестких дисков

В версии 4.3BSD UNIX были внесены существенные улучшения в архитектуру файловой системы, повышающие как ее производительность, так и надежность. Новая файловая система получила название Berkeley Fast File System (FFS) UNIX File System (UFS)

Файловая система FFS, обладая полной функциональностью системы s5fs, использует те же структуры данных ядра. Основные изменения затронули расположение файловой системы на диске, дисковые структуры данных и алгоритмы размещения свободных блоков.

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

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

Организация файловой системы предусматривает логическое деление дискового раздела на одну или несколько групп цилиндров (cylinder group).

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

Эти группы цилиндров состоят из:

Резервное копирование суперблока

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

Количество дескрипторов в группе цилиндров

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

Каждая группа цилиндров имеет собственную файловую структуру.

Группа управляет данными цилиндра, хранящиеся в блоках, содержащихся группами цилиндров.

http://www.linux.org/threads/unix-file-system-ufs.

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

Для каждой группы цилиндров при создании файловой системы выделяется место под определенное количество inode. При этом обычно на каждые 2 Кбайт блоков хранения данных создается один inode. Поскольку размеры группы цилиндров и массива inode фиксированы, в файловой системе BSD UNIX присутствуют ограничения, аналогичные s5fs.

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

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

Производительность файловой системы существенным образом зависит от размера блока хранения данных. Чем больше размер блока, тем большее количество данных может быть прочитано без поиска и перемещения дисковой головки. Файловая система FFS поддерживает размер блока до 64 Кбайт. Проблема заключается в том, что типичная файловая система UNIX состоит из значительного числа файлов небольшого размера. Это приводит к тому, что частично занятые блоки используются неэффективно, что может привести к потере до 60% полезной емкости диска.

Этот недостаток был преодолен с помощью возможности фрагментации блока. Каждый блок может быть разбит на два, четыре или восемь фрагментов. В то время как блок является единицей передачи данных в операциях ввода/вывода, фрагмент определяет адресуемую единицу хранения данных на диске. Таким образом был найден компромисс между производительностью ввода/вывода и эффективностью хранения данных. Размер фрагмента задается при создании файловой системы, его максимальное значение определяется размером блока (0,5 размера блока), а минимальный — физическими ограничениями дискового устройства, а именно: минимальной единицей адресации диска — сектором.

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

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

В отличие от s5fs, файловая система FFS при размещении блоков использует стратегию,

направленную на увеличение производительности. Некоторые из принципов приведены ниже:

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

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

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

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

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

Описанная архитектура является весьма эффективной с точки зрения надежности и производительности. К сожалению, эти параметры файловой системы FSS начинают значительно ухудшаться по мере уменьшения свободного места. В этом случае системе не удается следовать вышеприведенным правилам и размещение блоков далеко от оптимального. Практика показывает, что FSS имеет удовлетворительные характеристики при наличии более 10% свободного места.

Каталоги

Брайан Керниган, Деннис Ритчи <<-------- ст. 170 Печать каталогов

Для начала возможно следует вспомнить, что каталог есть файл содержащий список файлов, и к слову пользователи не "замысловатые" (пользователи рожденные до Mach) вспоминая, что UNIX - все файлы, делят файлы на две группы - каталоги и прочие файлы. Предназначение каталогов — единственное, и ритуально важное: быть хранителями имен входящих в них файлов, которым однозначно поставлены в соответствие идентификаторы inodes, хранящих метаданные этих файлов, что бы явно проиллюстрировать этот факт воспользуемся выше упомянутыми утилитами отладки и вывода дампа файла - od и hd:

$ ls -i

1148387 file1 1148388 file2 1148389 file3

$ hd .

00000000 e2 85 11 00 0c 00 04 01 2e 00 00 00 1e 57 0b 00 |.............W..|

00000010 0c 00 04 02 2e 2e 00 00 e3 85 11 00 10 00 08 05 |................|

00000020 66 69 6c 65 31 00 ff ff e4 85 11 00 10 00 08 05 |file1...........|

00000030 66 69 6c 65 32 00 ff ff e5 85 11 00 c8 01 08 05 |file2...........|

00000040 66 69 6c 65 33 00 ff ff 00 00 00 00 00 00 00 00 |file3...........|

00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

*

00000200

В примере были созданы три пустых файла в одной директории, команда ls -i показала их иноды, а команда od -ix , опцией -i выводит десятиричные целые числа, а опцией -x покажет шеснадцатиричный 2-х байтовый вывод, результат очевиден, однако чтобы до конца разобраться что такое файл каталога совершенно необходимо понимать стуктуру "struct dirent" , поскольку тема эта основательная то придется "почитать" и в итоге выяснится что все не так сложно: выше приведенную книгу Кернигана и Ритчи на странице 170, в интернете так же "много интересного" например здесь https://www.ibm.com/developerworks/unix , BSD ---> /usr/include/sys/dirent.h, в выше приведенном "видео часть-1" время: 14.10 -->18.44, "видео часть-2" время: 05:40 - 13:00 ---> каталог, mount ..... и тд.

$ od -ix .

0000000 1148386 17039372 46 743198

85e2 0011 000c 0104 002e 0000 571e 000b

0000020 33816588 11822 1148387 84410384

000c 0204 2e2e 0000 85e3 0011 0010 0508

0000040 1701603686 -65487 1148388 84410384

6966 656c 0031 ffff 85e4 0011 0010 0508

0000060 1701603686 -65486 1148389 84410824

6966 656c 0032 ffff 85e5 0011 01c8 0508

0000100 1701603686 -65485 0 0

6966 656c 0033 ffff 0000 0000 0000 0000

0000120 0 0 0 0

0000 0000 0000 0000 0000 0000 0000 0000

*

0001000

$

Если кратко то так:

# hd -x .

00000000 e2 85 11 00 0c 00 04 01 2e 00 00 00 1e 57 0b 00 |.............W..|

0000000 85e2 0011 000c 0104 002e 0000 571e 000b

00000010 0c 00 04 02 2e 2e 00 00 e3 85 11 00 10 00 08 05 |................|

0000010 000c 0204 2e2e 0000 85e3 0011 0010 0508

00000020 66 69 6c 65 31 00 ff ff e4 85 11 00 10 00 08 05 |file1...........|

0000020 6966 656c 0031 ffff 85e4 0011 0010 0508

00000030 66 69 6c 65 32 00 ff ff e5 85 11 00 c8 01 08 05 |file2...........|

0000030 6966 656c 0032 ffff 85e5 0011 01c8 0508

00000040 66 69 6c 65 33 00 ff ff 00 00 00 00 00 00 00 00 |file3...........|

0000040 6966 656c 0033 ffff 0000 0000 0000 0000

00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

0000050 0000 0000 0000 0000 0000 0000 0000 0000

*

0000200

#

============= /usr/include/sys/dirent.h:

struct dirent {

__uint32_t d_fileno; /* file number of entry */

__uint16_t d_reclen; /* length of this record */

__uint8_t d_type; /* file type, see below */

__uint8_t d_namlen; /* length of string in d_name */

#if __BSD_VISIBLE

#define MAXNAMLEN 255

char d_name[MAXNAMLEN + 1]; /* name must be no longer than this */

#else

char d_name[255 + 1]; /* name must be no longer than this */

#endif

};

==============================================================================================

d_fileno (1148387)

/ ,--------- d_reclen (16)

/ / ,----- d_type (8 = DT_REG)

/ / / ,--- d_namlen (5)

vvvvvvvvvvv vvvvv vv vv

00000010 0c 00 04 02 2e 2e 00 00 e3 85 11 00 10 00 08 05 |.................|

00000020 66 69 6c 65 31 00 ff ff e4 85 11 00 10 00 08 05 |file1...........|

^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^

\ \-------------------------------- padding

\------------------------------------------- d_name

==============================================================================================

Структура каталога файловой системы FFS была изменена для поддержки длинных имен файлов (до 255 символов). Вместо записей фиксированной длины запись каталога FFS представлена структурой, имеющей следующие поля: (в UFS поля не много другие, но общий принцип сохранен)

d_ino номер inode (индекс в массив ilist)

d_reclen длина записи

d_namelen длина имени файла

d_name имя файла

Имя файла имеет переменную длину, дополненную нулями до 4-байтной границы. При удалении имени файла принадлежавшая ему запись присоединяется к предыдущей, и значение поля d_reclen увеличивается на соответствующую величину. Удаление первой записи выражается в присвоении нулевого значения полю d_ino.

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

Более эффективный метод реализации - хеш-таблица (двоичное дерево)– линейный список с хеш-оглавлением и подразделением на (небольшие) списки элементов с одним и тем же значением хеш-функции. Такой метод уменьшает время поиска в директории.

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

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

Как было показано, различные типы файловых систем существенно отличаются по внутренней архитектуре. В то же время современные версии UNIX обеспечивают одновременную работу с несколькими типами файловых систем. Среди них можно выделить локальные файловые системы различной архитектуры, удаленные и даже отличные от файловой системы UNIX, например DOS. Такое сосуществование обеспечивается путем разделения каждой файловой системы на зависимый и независимый от реализации уровни, последний из которых является общим и представляет для остальных подсистем ядра некоторую абстрактную файловую систему. Независимый уровень также называется виртуальной файловой системой - VFS. При этом дополнительные файловые системы различных типов могут быть встроены в ядро UNIX подобно тому, как это происходит с драйверами устройств.

Виртуальные файловые системы (VFS) обеспечивают объектно-ориентированный способ реализации файловых систем. VFS обеспечивает единый интерфейс системных вызовов (API) для различных типов файловых систем, которые могут быть очень разными по своей реализации, включая сетевые файловые системы. Данный API является набором операций над самой VFS, а не над каким-либо специфическим типом файловых систем.


Виртуальные индексные дескрипторы

Маршал Кирк МакКузик FreeBSD - Архитектура и реализация <<---PDF ст. 291

Как и вслучае с основной файловой системой дисковый файл имеет связанную с ним структуру данных, называемую метаданными или inode, где хранятся основные характеристики данного файла и с помощью которой обеспечивается доступ к его данным. Одним из исключений из этого правила является файловая система DOS, в которой структуры файла и его метаданных существенно отличаются от принятых в UNIX. Тем не менее виртуальная файловая система основана на представлении метаданных файла в виде, сходном с традиционной семантикой UNIX. Интерфейсом работы с файлами является vnode (от virtual inode — виртуальный индексный дескриптор).

Первоначально этот интерфейс был разработан в 1984 году фирмой Sun Microsystems для обеспечения требуемой унификации работы с файловыми системами различных типов, в частности, с NFS и UFS (FFS). Сегодня виртуальная файловая система является стандартом в SVR4, хотя ряд других версий UNIX также реализуют подобную архитектуру (например, независимая файловая система SCO UNIX).

Метаданные всех активных файлов (файлов, на которые ссылаются один или более процессов) представлены в памяти в виде in-core inode, в качестве которых в виртуальной файловой системе выступают vnode. Структура данных vnode одинакова для всех файлов, независимо от типа реальной файловой системы, где фактически располагается файл. Данные vnode содержат информацию, необходимую для работы виртуальной файловой системы, а также неизменные характеристики файла, например, такие как тип файла.

Основные поля vnode

Каждый vnode содержит число ссылок v_count, которое увеличивается при открытии процессом файла и уменьшается при его закрытии. Когда число ссылок становится равным нулю, вызывается операция vn .inactive e, которая сообщает реальной файловой системе, что на vnode никто больше не ссылается. После этого файловая система может освободить vnode (и, например, соответствующий ему inode) или поместить его в кэш для дальнейшего использования.Поле v_vfsp указывает на файловую систему (структуру vfs, о которой мы поговорим в следующем разделе), в которой расположен файл, адресованный данным vnode. Если vnode является точкой монтирования, то поле v_vfsmountednere указывает на подключенную файловую систему, "перекрывающую" данный vnode. Поле v_data указывает на данные, относящиеся к конкретной реализации реальной файловой системы. Например, для дисковой файловой системы ufs, v_data указывает на запись в таблице in-core inode. Набор операций над vnode указан полем v_op. В терминах объектно ориентированного программирования этот набор представляет собой виртуальные методы класса vnode. Он является своего рода шлюзом к реальной файловой системе, позволяя предоставить общий интерфейс виртуальной файловой системы и в то же время обеспечить специфические реализации функций работы с файлами, необходимые для различных типов файловых систем. Некоторые операции, большинство из которых знакомы по системным вызовам.

Операции с vnode виртуальной файловой системы:

Взаимосвязь между независимыми дескрипторами (vnode) и зависимыми от реализации метаданными файла

Монтирование файловой системы

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

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

Поля структуры vfs

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

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

Для инициализации и монтирования реальной файловой системы UNIX хранит коммутатор файловых систем (File System Switch), адресующий процедурный интерфейс для каждого типа файловой системы, поддерживаемой ядром. UNIX System V для этого использует глобальную таблицу, каждый элемент которой соответствует определенному типу реальной файловой системы, например s5fs, ufs или nfs. Элемент этой таблицы vf ssw имеет поля, указанные в табл. 4.5.

Поля vf ssw

Операции файловой системы

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

Монтирование файловой системы производится системным вызовом mount. В качестве аргументов передаются тип монтируемой файловой системы, имя каталога, к которому подключается файловая система (точка монтирования), флаги (например, доступ к файловой системе только для чтения) и дополнительные данные, конкретный вид и содержимое которых зависят от реализации реальной файловой системы. При этом производится поиск vnode, соответствующего файлу — точке монтирования (операция lookup или namei трансляции имени), и проверяется, что файл является каталогом и не используется в настоящее время для монтирования других файловых систем.

Затем происходит поиск элемента коммутатора файловых систем vf ssw, соответствующего типу монтируемой файловой системы. Если такой элемент найден, вызывается операция инициализации, адресованная полем vsw_init . При этом выполняется размещение специфических для данного типа файловой системы данных, после чего ядро размещает структуру vfs и помещает ее в связанный список подключенных файловых систем, как это показано на рисунке. Поле vfs_vnodecovered указывает на vnode точки монтирования. Это поле устанавливается нулевым для корневой (root) файловой системы, элемент vfs которой всегда расположен первым в списке подключенных файловых систем. Поле vfs_op адресует вектор операций, определенный для данного типа файловой системы. Наконец, указатель на данный элемент vfs сохраняется в поле v_vfsmountedhere виртуального индексного дескриптора каталога — точки монтирования.


После этого вызывается операция vfs_mount , соответствующая данному типу файловой системы. Конкретные действия определяются реализацией файловой системы и могут существенно различаться. Например, операция монтирования локальной файловой системы ufs предусматривает считывание в память метаданных системы, таких как суперблок, в то время как монтирование удаленной NFS файловой системы включает передачу сетевого запроса файловому серверу. Однако монтирование предусматривает выполнение и ряда общих операций, включающих:

проверку соответствующих прав на выполнение монтирования;

размещение и инициализацию специфических для файловой системы данного типа данных, сохранение адреса этих данных в поле vfs_data элемента vfs;

размещение vnode для корневого каталога подключаемой файловой системы, доступ к которому осуществляется с помощью операции vfs_root;

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

Определение корневого vnode для подключенной файловой системы производится с помощью операции vfs_root . Заметим, что в некоторых реализациях независимой файловой системы (например, в SCO UNIX, хотя там используется другая терминология) одно из полей записи таблицы монтирования явно указывало на корневой vnode. Подход, предложенный фирмой Sun Microsystems, позволяет не хранить корневой vnode постоянно, размещая его только при необходимости работы с файловой системой. Это минимизирует ресурсы, занимаемые подключенными файловыми системами, которые продолжительное время не используются.

На рисунке справа приведен вид логического файлового дерева до и после монтирования файловой системы А к каталогу /usr/local. Далее приведен вид виртуальной файловой системы после этой операции монтирования.


/proc LINUX

Трансляция имен

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

Системные вызовы, для выполнения которых требуется трансляция имени файла.

Говоря формально, полное имя файла представляет собой последовательность слов, разделенных символом '/'. Каждый компонент имени, кроме последнего, является именем каталога. Последний компонент определяет собственно имя файла. При этом полное имя может быть абсолютным или относительным. Если полное имя начинается с символа '/', представляющего корневой каталог общего логического дерева файловой системы, то оно является абсолютным, однозначно определяющим файл из любого места файловой системы. В противном случае, имя является относительным и адресует файл относительно текущего каталога. Примером относительного имени может служить include/sys/user.h, а абсолютное имя этого файла — /usr/include/sys/user.h. Как следует из этих рассуждений, два каталога играют ключевую роль при трансляции имени: корневой каталог и текущий каталог. Каждый процесс адресует эти каталоги двумя полями структуры u_area:

struct vnode *u_cdir Указатель на vnode текущего каталога

struct vnode *u_rdir Указатель на vnode корневого каталога

В зависимости от имени файла трансляция начинается с vnode, адресованного либо полем u_cdir, либо u_rdir. Трансляция имени осуществляется по компонентно, при этом для vnode текущего каталога вызывается соответствующая ему операция vn_lookup (), в качестве аргумента которой передается имя следующего компонента. В результате операции возвращается vnode, соответствующий искомому компоненту.

Если для vnode каталога установлен указатель vn_vf smountedhere, то данный каталог является точкой монтирования. Если имя файла требует дальнейшего спуска по дереву файловой системы (т. е. пересечения точки монтирования), то операция vn_lookup() следует указателю vn_vfsmountedhere для перехода в подключенную файловую систему и вызывает для нее операцию vfs_root () для получения ее корневого vnode. Трансляция имени затем продолжается с этого места.

Пересечение границы файловых систем возможно и при восхождении по дереву, например, если имя файла задано указанием родительского каталога — ../../myfile.txt. Если при движении в этом направлении по пути встречается корневой vnode подключенной файловой системы (установлен флаг VR00T в поле v_flag), то операция vn_lookup следует указателю vfs_vnodecovered, расположенному в записи vfs этой файловой системы. При этом происходит пересечение границы файловых систем, и дальнейшая трансляция продолжается с точки монтирования.

Если искомый файл является символической связью, и системный вызов, от имени которого происходит трансляция имени, "следует" символической связи, операция vn_lookup вызывает vn_readlink для получения имени целевого файла. Если оно является абсолютным (т. е. начинается с "/"), то трансляция начинается с vnode корневого каталога, адресованного полем u_rdir области u-area.

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

Доступ к файловой системе

Файловый дескриптор — это неотрицательное целое число. Файловый дескриптор, в отличии от индексного имеет отношение к потокам ввода/вывода, через файловый дескриптор они и получают к ним доступ (упрощенный указатель на файл, ниже), самый очевидный пример - stdin, stdout, stderr. Когда создается новый поток ввода-вывода, ядро возвращает процессу, создавшему поток ввода-вывода, его файловый дескриптор.

Процесс совершает операции с файлами, адресуя их при помощи файловых дескрипторов целых чисел, имеющих локальное для процесса значение. Это значит, что файловый дескриптор одного процесса может адресовать совершенно другой файл, нежели файловый дескриптор с таким же номером, используемый другим процессом. Процесс получает файловый дескриптор с помощью ряда системных вызовов, например, ореn или creat, выполняющих операцию трансляции имени, в результате которой выделяемый файловый дескриптор адресует определенный inode (или vnode) и, соответственно, файл файловой системы.

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


Файловый дескриптор, используемый для доступа процесса к файлу, является индексом таблицы файловых дескрипторов (file descriptor table). Каждый процесс имеет собственную таблицу файловых дескрипторов, которая расположена в его u-area. На рисунке выше показаны два процесса, каждый из которых использует собственную таблицу файловых дескрипторов.

Каждая активная запись этой таблицы, представляющая открытый файл, адресует запись системной файловой таблицы (system file table), в которой хранятся такие параметры, как режим доступа к файлу (запись, чтение, добавление и т. д.), текущее смещение в файле (файловый указатель), а также указатель на vnode этого файла. Системная файловая таблица одна и совместно используется всеми процессами. Несколько записей системной файловой таблицы могут адресовать один и тот же файл, который представлен единственной записью в таблице vnode.

Файловые дескрипторы

https://ru.wikipedia.org/wiki/

Ю.Вахалия UNIX изнутри ст.338

Файловый дескриптор представляет собой неотрицательное целое число, возвращаемое системными вызовами, такими как creat, ореn или pipe. После получения файлового дескриптора процесс может использовать его для дальнейшей работы с файлом, например с помощью системных вызовов read, write, close или fcntl.

В самом общем случае перед тем как читать или писать файл, необходимо сообщить системе о своем намерении; этот процесс называется открытием файла. Если вы собираетесь записывать в файл, возможно, его надо предварительно создать. Система проверяет права пользователя на выполнение операции (существует ли файл? есть ли разрешение на доступ к нему?) и, если все в порядке, возвращает неотрицательное целое число, которое и называется дескриптором файла. Можно сказать проще: дескриптор файла -- это просто число, по которому система идентифицирует открытые файлы. Рассматривайте его как упрощенную версию указателя на файл.

По умолчанию Unix-оболочки связывают:

файловый дескриптор 0 - stdin — с потоком стандартного ввода процесса (терминал),

файловый дескриптор 1 - stdout — с потоком стандартного вывода (терминал)

файловый дескриптор 2 - stderr — с потоком диагностики (куда обычно выводятся сообщения об ошибках).

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

Поля структуры user, которые используются ядром для обеспечения доступа процесса к файлу:

u_ofile — Указатель на системную файловую таблицу

u_pofiie — Флаги файлового дескриптора

Файловый дескриптор связан с этими двумя полями и, таким образом, обеспечивает доступ к соответствующему элементу файловой таблицы (структуре данных file).

В настоящее время в качестве единственного флага файлового дескриптора определен флаг FD_CLOEXEC. Если этот флаг установлен, то производится закрытие файлового дескриптора (аналогично явному вызову close) при выполнении процессом системного вызова ехес). При этом для запущенной программы не происходит наследования файлового дескриптора и доступа к файлу.

Более старые версии UNIX используют статическую таблицу дескрипторов, которая целиком хранится в u-area. Номер дескриптора является индексом этой таблицы. Таким образом, размер таблицы, которая обычно содержит 64 элемента, накладывает ограничение на число одновременно открытых процессом файлов. В современных версиях таблица размещается динамически и может увеличиваться при необходимости. Следует, однако, иметь в виду, что и в этом случае максимальное число одновременно открытых файлов регламентируется пределом rlimit_nofile. В некоторых версиях, например, Solaris 2.5, данные файловых дескрипторов хранятся не в виде таблицы, а в виде блоков структур uf_entry. Содержимое таблицы дескрипторов процесса можно посмотреть с помощью утилиты crash. Команда user покажет содержимое u-area процесса. Например, для текущего командного интерпретатора мы получим следующую информацию:

# crash

dumpfile = /dev/mem, namelist = /dev/ksyms, outfile = stdout

> proc #8591

PROC TABLE SIZE = 1498

SLOT ST PID PPID PGID SID UID PRI NAME FLAGS

121 s 8591 8589 8591 8591 286 48 bash load jctl

> user 121

PER PROCESS USER AREA FOR PROCESS 121

PROCESS MISC:

command: bash, psargs: -bash

start: PO Mon 24 18:11:31 1997

mem: lebc, type: exec

vnode of current directory: f5b95e40

OPEN FILES, POFILE FLAGS, AND THREAD REFCNT:

[0] : F 0:-:f 62b6030, 0, 0 [1] : F Oxf62b6030, О, О

[2] : F Oxf62b6030 ,0,0

cmask: 0022

......................................

Файловая таблица

Поля файлового дескриптора u_ofile и u_pofile содержат начальную информацию, необходимую для доступа процесса к данным файла. Дополнительная информация находится в системной файловой таблице и таблице индексных дескрипторов. Для обеспечения доступа процесса к данным файла ядро должно полностью создать цепочку от файлового дескриптора до vnode и, соответственно, до блоков хранения данных.

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

Некоторые поля элемента файловой таблицы:

Поля структуры

Блокирование доступа к файлу

Традиционно архитектура файловой подсистемы UNIX разрешает нескольким процессам одновременный доступ к файлу для чтения и записи. Хотя операции записи и чтения, осуществляемые с помощью системных вызовов read или write, являются атомарными, в UNIX по умолчанию отсутствует синхронизация между отдельными вызовами. Другими словами, между двумя последовательными вызовами read одного процесса другой процесс может модифицировать данные файла. Это, в частности, может привести к несогласованным операциям с файлом,............При этом перед фактической файловой операцией (чтения или записи) процесс устанавливает блокирование соответствующего типа (для чтения или для записи). Если блокирование завершилось успешно, это означает, что требуемая файловая операция не создаст конфликта или нарушения целостности данных, например, при одновременной записи в файл несколькими процессами.

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

Как следует из описания поля l_type структуры flock, существуют два типа блокирования записи: для чтения (F_ RDLCK) и для записи (F_WRLCK). Правила блокирования таковы, что может быть установлено несколько блокирований для чтения на конкретный байт файла, при этом в установке блокирования для записи на этот байт будет отказано. Напротив, блокирование для записи на конкретный байт должно быть единственным, при этом в установке блокирования для чтения будет отказано.

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

struct flock lock;

/‘Заполним описание lock с целью блокирования всего файла для записи*/

lock.l_type = F__WRLCK;

lock.l_st.art = О;

lock.whence = SEEK_SET;

lock.len = 0;

/*Заблокируем файл. Если блокирования, препятствующие данной операции, уже существуют — ждем их снятия*/

fcntl(fd, SETLKW, Slock);

/‘Запишем данные в файл — нам никто не помешает*/

write(fd, record, sizeof(record));

/*Снимем блокирование*/

lock.l_type = F_UNLCK;

fcntl(fd, SETLKW, Slock);

В отличие от рекомендательного в UNIX существует обязательное блокирование (mandatory lock), при котором ограничение на доступ к записям файла накладывается самим ядром. Реализация обязательных блокировок может быть различной. Например, в SCO UNIX(SVR3) снятие бита х для группы и установка бита SGID для группы приводит к тому, что блокировки, установленные fcntl или lockf, станут обязательными. UNIX SVR4 поддерживает установку блокирования отдельно для записи и для чтения, обеспечивая тем самым доступ для чтения многим, а для записи — только одному процессу. Эти установки также осуществляются с помощью системного вызова fcntl. Следует иметь в виду, что использование обязательного блокирования таит потенциальную опасность. Например, если процесс блокирует доступ к жизненно важному системному файлу и по каким-либо причинам теряет контроль, это может привести к аварийному останову операционной системы.

Буферный кэш

Работа файловой подсистемы тесно связана с обменом данными с периферийными устройствами. Для обычных файлов и каталогов — это устройство, на котором размещается соответствующая файловая система, для специальных файлов устройств — это принтер, терминал, или сетевой адаптер. Не вдаваясь в подробности подсистемы ввода/вывода, рассмотрим, как во многих версиях UNIX организован обмен данными с дисковыми устройствами — традиционным местом хранения подавляющего большинства файлов.

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

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

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


Внутренняя структура буферного кэша

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

Основные поля структуры buf :

Поле b_flags хранит различные флаги связанного с заголовком буфера. Часть флагов используется буферным кэшем, а часть — драйвером устройства. Например, с помощью флага B_BUSY осуществляется синхронизация доступа к буферу. Флаг B_DELWRI отмечает буфер как модифицированный, или "грязный", требующий сохранения на диске перед повторным использованием. Флаги B READ, B WRITE, B_ASYNC, B DONE И BERROR ИСПОЛЬзуются драйвером диска. Более подробно операция ввода/вывода для драйвера будет рассмотрена в следующей главе.

Буферный кэш использует механизм отложенной записи (write-behind), при котором модификация буфера не вызывает немедленной записи на диск. Такие буферы отмечаются как "грязные", а синхронизация их содержимого с дисковыми данными происходит через определенные промежутки времени. Примерно одна треть операций дискового ввода/вывода приходится на запись, причем один и тот же буфер может на протяжении ограниченного промежутка времени модифицироваться несколько раз. Поэтому буферный кэш позволяет значительно уменьшить интенсивность записи на диск4 и реорганизовать последовательность записи отдельных буферов для повышения производительности ввода/вывода (например, уменьшая время поиска, группируя запись соседних дисковых блоков). Однако этот механизм имеет свои недостатки, поскольку может привести к нарушению целостности файловой системы в случае неожиданного останова или сбоя операционной системы.

Операции ввода/вывода

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

Когда процессу требуется прочитать или записать данные он использует системные вызовы read или write, направляя тем самым запрос файловой подсистеме. В свою очередь файловая подсистема транслирует этот запрос в запрос на чтение или запись соответствующих дисковых блоков файла и направляет его в буферный кэш. Прежде всего кэш просматривается на предмет наличия требуемого блока в памяти. Если соответствующий буфер найден, его содержимое копируется в адресное пространство процесса в случае чтения и наоборот при записи, и операция завершается. Если блок в кэше не найден, ядро размещает буфер, связывает его с дисковым блоком с помощью заголовка buf и направляет запрос на чтение драйверу устройства. Обычно используется схема чтения вперед (read-ahead), когда считываются не только запрашиваемые блоки, но и блоки, которые с высокой вероятностью могут потребоваться в ближайшее время (рис. 4.14, а). Таким образом, последующие вызовы read скорее всего не потребуют дискового ввода/вывода, а будут включать лишь копирование данных из буферов в память процесса, — операция, которая, как отмечалось, обладает на несколько порядков большей производительностью (рис. 4.14, б—в). При запросе на модификацию блока изменения также затрагивают только буфер кэша. При этом ядро помечает буфер как "грязный" в заголовке buf (рис. 4.14, г). Перед освобождением такого буфера для повторного использования, его содержимое должно быть предварительно сохранено на диске (рис. 4.14, д).

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

Использование буферного кэша позволяет избежать 95% операций чтения с диска и 85% операций записи на диск для типичной конфигурации операционной системы.

Не заблокированные буферы помечаются как свободные и помещаются в специальный список. Буферы в этом списке располагаются в порядке наименее частого использования (Least Recently Used, LRU). Таким образом, когда ядру необходим буфер, оно выбирает тот, к которому не было обращений в течение наиболее продолжительного промежутка времени. После того как работа с буфером завершена, он помещается в конец списка и является наименее вероятным кандидатом на освобождение и повторное использование. Поэтому, если процесс вскоре опять обратится к тому же блоку данных, операция ввода/вывода по-прежнему будет происходить с буфером кэша. С течением времени буфер перемещается в направлении начала очереди, но при каждом последующем обращении к нему, будет помещен в ее конец.


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

Для уменьшения вероятности таких потерь в UNIX имеется несколько возможностей:

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

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

##Наконец, через регулярные промежутки времени в системе пробуждается специальный системный процесс — диспетчер буферного кэша (в различных версиях UNIX его названия отличаются, чаще всего используется fsflush или bdflush). Этот процесс освобождает

В распоряжении администратора имеется командный интерфейс к системному вызову — утилита sync(lM). Поскольку выполнение команды еще не свидетельствует о фактическом завершении ввода/вывода, администраторы практикуют вызов sync( 1М) несколько раз. Повторные вызовы повышают вероятность того, что ввод/вывод будет завершен прежде, чем будет введена другая команда или остановлена система, поскольку набор команды занимает определенное время. Тот же эффект может быть достигнут просто ожиданием нескольких секунд после ввода sync( 1М), но набор команды позволяет "скрасить ожидание".

"грязные" буферы, сохраняя их содержимое в соответствующих дисковых блоках6 (рис. 4.14, д).

Кэширование в SVR4

Центральной концепцией в архитектуре виртуальной памяти SVR4 является отображение файлов. При этом подходе все адресное пространство может быть представлено набором отображений различных файлов в память. Действительно, в страницы памяти, содержащие кодовые сегменты, отображаются соответствующие секции исполняемых файлов. Процесс может задать отображение с помощью системного вызова mmap, при этом страницам памяти будут соответствовать определенные участки отображаемого файла. Даже области памяти, содержимое которых изменяется и не связано ни с каким файлом файловой системы, т. н. анонимные страницы, можно отобразить на определенные участки специального файла устройства, отвечающего за область свопинга (именно там сохраняются анонимные объекты памяти). При этом фактический обмен данными между памятью и устройствами их хранения, инициируется возникновением страничной ошибки. Такая архитектура позволяет унифицировать операции ввода/вывода практически для всех случаев.

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

Целостность файловой системы

Значительная часть файловой системы находится в оперативной памяти. А именно, в оперативной памяти расположены суперблок примонтиро- ванной системы, метаданные активных файлов (в виде системно-зависимых inode и соответствующих им vnode) и даже отдельные блоки хранения данных файлов, временно находящиеся в буферном кэше.

Работа диспетчера буферного кэша зависит от версии UNIX и конкретных настроек ядра системы. Например, в SCO UNIX для этого используются несколько параметров. Параметр BDFLUSHR задает интервал между последовательными пробуждениями bdflush, его значение по умолчанию составляет 30 секунд. Параметр nautqup задает промежуток времени, который буфер должен оставаться "грязным", прежде чем bdflush сохранит его на диске.

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

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

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

##Создать новую запись в необходимом каталоге, указывающую на inode файла.

##Увеличить счетчик связей в inode.

Предположим, что аварийный останов системы произошел между первой и второй операциями. В этом случае после запуска в файловой системе будут существовать два имени файла (две записи каталогов), адресующие inode со счетчиком связей di_nlinks, равным 1. Эта ситуация показана на рис. 4.15 (а). Если теперь будет удалено одно из имен, это приведет к удалению файла как такового, т. е. к освобождению блоков хранения данных и inode, поскольку счетчик связей di_nlinks станет равным 0. Оставшаяся запись каталога будет указывать на неразмещенный индексный дескриптор, или inode, адресующий уже другой файл (рис. 4.15, б).

Порядок операций с метаданными может иметь существенное влияние на целостность файловой системы. Рассмотрим, например, предыдущий пример. Допустим, порядок операций был изменен и, как и прежде, останов произошел между первой и второй операциями. После запуска системы файл будет иметь лишнюю жесткую связь, но существующая запись каталога останется правильной. Тем не менее при удалении имени файла фактически файл удален не будет, поскольку число связей останется равным 1 (рис. 4.15, в). Хотя это также является ошибкой, результатом которой является засорение дискового пространства, ее последствия все же менее катастрофичны, чем в первом случае.

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

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



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

2. Блок помечен как свободный, но в то же время занят (на него ссылается inode).

3. Блок помечен как занятый, но в то же время свободен (ни один inode на него не ссылается).

4. Неправильное число ссылок в inode (недостаток или избыток ссылающихся записей в каталогах).

5. Несовпадение между размером файла и суммарным размером адресуемых inode блоков.

6. Недопустимые адресуемые блоки (например, расположенные за пределами файловой системы).

7. "Потерянные" файлы (правильные inode, на которые не ссылаются записи каталогов).

8. Недопустимые или неразмещенные номера inode в записях каталогов.

Эти ошибки схематически показаны на рис. 4.16.

Если нарушение все же произошло, на помощь может прийти утилита fsck, производящая исправление файловой системы. Запуск этой утилиты может производиться автоматически каждый раз при запуске системы, или администратором, с помощью команды:

fsck [options] filesystem где filesystem — специальный файл устройства, на котором находится файловая система.

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

=======================================

Дамп памяти (англ. memory dump; в Unixcore dump) — содержимое рабочей памяти одного процесса, ядра или всей операционной системы. Также может включать дополнительную информацию о состоянии программы или системы, например значения регистров процессора и содержимое стека. Многие операционные системы позволяют сохранять дамп памяти для отладки программы. Как правило, дамп памяти процесса сохраняется автоматически, когда процесс завершается из-за критической ошибки (например, из-за ошибки сегментации). Дамп также можно сохранить вручную через отладчик или любую другую специальную программу.

-----------------

https://www.esetnod32.ru/support

http://support.kaspersky.ru/general/dumps

-----------------

=======================================