Московский физико-технический институт
Опубликован: 12.12.2007 | Доступ: свободный | Студентов: 5489 / 1826 | Оценка: 4.34 / 4.14 | Длительность: 13:57:00
ISBN: 978-5-94774-827-7
Лекция 12:

Реализация файловой системы. Файловая система NTFS

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >

Управление свободным и занятым дисковым пространством

В системе Windows учет свободных и занятых дисковых блоков ведется при помощи битового вектора (bit map или bit vector), например, 00111100111100011000001, где каждый блок представлен одним битом, принимающим значение 0 или 1, в зависимости от того, занят он или свободен. В файловой системе NTFS битовый массив сам является файлом. Его атрибуты и дисковые адреса хранятся в 6-й записи таблицы MFT.

Реализация директорий

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

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

MFT запись для небольшого каталога

Рис. 12.4. MFT запись для небольшого каталога

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

Поиск файла по имени

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

При поиске файла вначале при помощи механизма символьных ссылок в пространстве имен объектов решается задача трансляции имени диска "в стиле DOS" или буквы диска во внутренние имена устройств Windows. Для этого библиотечный вызов, содержащий имя файла в качестве параметра, передается библиотеке kernel32.dll и перед именем помещается название каталога именованных ресурсов "\??\" в пространстве имен менеджера объектов. В результате "F:\tmp\MyFile.txt" преобразуется в "\??\F:\tmp\MyFile.txt". Далее в каталоге \??\ ищется символьное имя "F:", которое является ссылкой на объект-раздел жесткого диска, например, "\Device\Harddisk\Volume5". Далее находится таблица MFT этого раздела, затем осуществляется навигация по каталогам и отыскивается искомый файл, см. рис. 12.5.

Процесс поиска файла по имени

Рис. 12.5. Процесс поиска файла по имени

Для поиска файлов в каталоге применяются функции FindFirstFile и FindNextFile (см. MSDN).

Прогон программы, осуществляющей поиск файла в каталоге

Приведенная программа выводит список файлов в каталоге с заданным шаблоном поиска. Информация о найденных файлах содержится в структуре WIN32_FIND_DATA, которая является одним из параметров функций FindFirstFile и FindNextFile. Входным параметром функции FindFirstFile служит шаблон поиска, а выходным - дескриптор поиска, который является входным параметром функции FindNextFile и хранит информацию о текущем состоянии поиска (аналог указателя текущей позиции). Для закрытия описателя в данном случае применяется функция FindClose (а не CloseHandle как обычно).

Точки повторного анализа. Монтирование дисков. Образование ссылок

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

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

Операция монтирования файловой системы, хранящейся на разделе диска, обеспечивает ей связь с уже существующей иерархией файловых систем и делает ее файлы доступными для процессов. Техника монтирования описана в предыдущей лекции. Монтирование базовых дисков осуществляется автоматически при первом обращении к диску. Это делает диспетчер монтирования (Mountmgr.sys). Сведения о монтированных дисках имеются в реестре в разделе HKLM\SYSTEM\MountedDevices.

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

Точки монтирования в системе можно найти при помощи Win32-функций FindFirstVolumeMountPoint и FindNextVolumeMountPoint.

Создание связей

Связывание файлов - техника, заимствованная из Unix, - образование для файла или каталога нескольких родительских каталогов, см. рис. 12.6.

Образование связей в файловой системе

Рис. 12.6. Образование связей в файловой системе

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

ОС Windows (как и Unix) поддерживает два вида связей - жесткие (hard link) и символические (symbolic link). В случае жесткой связи запись о файле появляется в новом каталоге, а MFT-запись этого файла включает счетчик количества ссылок на данный файл. Удаление файла приводит к уменьшению счетчика на 1, и реальное удаление и освобождение его блоков происходит, когда значение счетчика равно 0.

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

Жесткие связи создаются вызовом Win32-функции CreateHardLink. Штатной утилиты, поддерживающей жесткие связи, нет, хотя в состав ресурсов Windows для этих целей включена POSIX утилита ln.

Символическую связь (иногда говорят точку соединения, junction) можно образовать при помощи входящей в состав ресурсов Windows утилиты linkd.exe или при помощи свободно распространяемой утилиты junction.exe с сайта http://www.sysinternals.com.

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

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

Образование циклического графа можно проиллюстрировать на примере [ Руссинович ] образования рекурсивной точки монтирования.

Эксперимент

Создайте на диске X: каталог Recurse и смонтируйте его с корневым каталогом диска X: Затем для этого каталога выполните команду dir /s.

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

Создайте пустой каталог и сделайте его точкой монтирования или символической связью. При помощи функции GetFileAttributes установите у данного каталога наличие флага FILE_ATTRIBUTE_REPARSE_POINT.

Совместный доступ к файлу

Пользователи часто нуждаются в разделении файлов и совместном доступе к ним.

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

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

Рис. 12.7. Организация совместного доступа к файлу

Очевидно, что потоки должны синхронизировать доступ к совместно используемым файлам или каталогам, чтобы получить предсказуемый результат. Между двумя операциями read одного потока другой поток может модифицировать данные, что для многих приложений неприемлемо. ОС Windows предлагает стандартное решение данной проблемы на уровне пользователя - предоставить возможность одному из потоков захватить часть файла между двумя записями для монопольного доступа. Для этого используются Win32-функции LockFile и UnlockFile.

< Лекция 11 || Лекция 12: 1234 || Лекция 13 >
Ирина Оленина
Ирина Оленина
Николай Сергеев
Николай Сергеев

Здравствуйте! Интересует следующий момент. Как осуществляется контроль доступа по тому или иному адресу с точки зрения обработки процессом кода процесса. Насколько я понял, есть два способа: задание через атрибуты сегмента (чтение, запись, исполнение), либо через атрибуты PDE/PTE (чтение, запись). Но как следует из многочисленных источников, эти механизмы в ОС Windows почти не задействованы. Там ключевую роль играет менеджер памяти, задающий регионы, назначающий им атрибуты (PAGE_READWRITE, PAGE_READONLY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_NOACCESS, PAGE_GUARD: их гораздо больше, чем можно было бы задать для сегмента памяти) и контролирующий доступ к этим регионам. Непонятно, на каком этапе может включаться в работу этот менеджер памяти? Поскольку процессор может встретить инструкцию: записать такие данные по такому адресу (даже, если этот адрес относится к региону, выделенному менеджером памяти с атрибутом, например, PAGE_READONLY) и ничего не мешает ему это выполнить. Таким образом, менеджер памяти остается в стороне не участвует в процессе...