Если файл или каталог, для которого диспетчер ввода-вывода получает от NTFS код статуса повторного разбора, не сопоставлен с одной из предопределенных в Windows точек повторного разбора, значит, его точка не обрабатывается ни одним драйвером фильтра. Тогда диспетчер ввода-вывода сообщает диспетчеру объектов об ошибке, которая передается приложению, обратившемуся к этому файлу или каталогу, в виде «file cannot be accessed by the system» («файл недоступен системе»).
Точки монтирования — это точки повторного разбора, в которых имя тома (Global??Volume{X}) хранится как данные повторного разбора. Назначая или удаляя пути для томов в оснастке Disk Management, вы создаете точки монтирования. Создавать и просматривать точки монтирования можно и с помощью встроенной утилиты командной строки Mountvol.exe (WindowsSystem32Mountvol.exe).
Диспетчер монтирования поддерживает на каждом томе NTFS удаленную базу данных, в которой регистрирует все точки монтирования, определенные для тома. Файл этой базы данных, $MountMgrRemoteDatabase, размещается в корневом каталоге NTFS. При перемещении диска между системами и в средах с двух вариантной загрузкой (различных систем Windows) перемещаются и точки монтирования — благодаря наличию удаленной базы данных диспетчера монтирования. NTFS отслеживает точки монтирования в файле метаданных lExtendIReparse (ни один из файлов метаданных NTFS не доступен приложениям). Поскольку NTFS хранит информацию о точках монтирования в файле метаданных, при соответствующем запросе Windows-приложения Windows может легко перечислить точки монтирования, определенные для тома.
ЭКСПЕРИМЕНТ: рекурсивные точки монтирования
Этот эксперимент с использованием утилиты Filemon {wwwsysinter nals.com) демонстрирует любопытное поведение системы, вызываемое рекурсивной точкой монтирования. Рекурсивной называется точка монтирования, связанная с тем томом, где она находится. Рекурсивное перечисление каталогов, выполняемое на рекурсивной точке монтирования, позволяет наглядно увидеть, как NTFS обрабатывает точки монтирования.
Для создания и просмотра точки монтирования проделайте следующее.
1. Откройте окно командной строки или Windows Explorer и создайте на NTFS-диске каталог с именем Recurse.
2. B оснастке Disk Management (Управление дисками) консоли MMC щелкните том правой кнопкой мыши и выберите из контекстного меню команду Change Drive Letter And Path (Изменить букву диска или путь к диску).
3. B появившемся диалоговом окне введите путь к созданному вами каталогу (например, I: Recurse).
4. Запустите Filemon. B меню Drives оставьте галочку только для тома, на котором создана точка монтирования.
Теперь вы готовы к трассировке рекурсивной точки монтирования. Откройте окно командной строки и введите dir /s I: Recurse. Следите за ссылками на Recurse, регистрируемыми Filemon при трассировке файловых операций. Вы заметите, что сначала идет обращение к I: Re-curse, затем к I: RecurseRecurse и т. д.
Приложение перечисляет каталоги на каждом уровне рекурсии, но всякий раз, когда встречает точку монтирования, оно закапывается все глубже и глубже, пытаясь выполнить очередное перечисление каталогов. NTFS возвращает код статуса повторного разбора, который сигнализирует диспетчеру объектов о необходимости возврата на предыдущий уровень рекурсии и повторной попытки операции. Наконец, вернувшись в корневой каталог, приложение исследует файл или каталог, найденный им при глубокой рекурсии. Приложение никогда не получает код статуса повторного разбора из-за того, что диспетчер объектов сам обрабатывает статусные коды повторного разбора при получении их от NTFS.
Filemon показывает запрос на открытие файла или каталога как IRP_ MJ_CREATE, запрос на закрытие файла или каталога — как IRP_MJ_CLOSE, а запрос сведений о каталогах — как IRP_MJ_DIRECTORY CONTROL, выполняемый с помощью функции FileBothDirectoryInfo (см. колонку Other).
Чтобы предотвратить переполнение буферов и вхождение в бесконечный цикл, командный процессор и Windows Explorer останавливают рекурсию по достижении 32-го уровня вложенности или при превышении длины пути в 256 символов — смотря что произойдет быстрее.
Монтирование томов
Тот факт, что Windows присваивает тому букву диска, еще не означает, что этот том содержит данные, организованные в формате файловой системы, известной Windows. Процесс распознавания тома заключается в том, что какая-либо файловая система объявляет раздел своим; первый раз этот процесс происходит при обращении ядра, драйвера устройства или приложения к какому-либо файлу или каталогу в данном томе. После того как драйвер файловой системы уведомляет о взятии на себя ответственности за управление разделом, диспетчер ввода-вывода направляет все адресованные этому тому запросы данному драйверу. Операции монтирования в Windows проходят в три этапа: регистрация драйвера файловой системы, обновление блоков параметров тома (volume parameter blocks, VPB) и запросы на монтирование.
ПРИМЕЧАНИЕ B Windows Server 2003 Enterprise и Datacenter Edition автоматическое монтирование отключено, чтобы не допустить агрессивного монтирования томов, подключенных к сети устройств хранения данных (System Area Network, SAN). Для включения или отключения автоматического монтирования можно использовать утилиту командной строки Diskpart, поставляемую с Windows Server 2003, а для монтирования томов вручную — утилиту Mountvol, также поставляемую с этой системой.
Процесс монтирования курирует диспетчер ввода-вывода, которому известны доступные драйверы файловых систем, поскольку они регистрируются у него при инициализации. Для регистрации драйверов файловых систем на локальных (не сетевых) дисках предназначена функция IoRegisterFileSystem, предоставляемая диспетчером ввода-вывода. Когда драйвер файловой системы регистрируется, диспетчер ввода-вывода сохраняет ссылку на драйвер в списке, который используется при операциях монтирования.
Каждый объект «устройство» содержит структуру данных VPB, но диспетчер ввода-вывода обращает внимание только на VPB объектов томов. VPB служит для связи между объектом тома и объектом «устройство», созданным драйвером файловой системы для представления экземпляра файловой системы, смонтированной для данного тома. Если ссылка VPB на файловую систему пуста, значит, том не смонтирован ни одной файловой системой. Диспетчер ввода-вывода проверяет VPB объекта тома всякий раз, когда выполняется API-функция открытия файла или каталога на этом объекте «устройство».
Например, если диспетчер монтирования назначает второму тому системы букву D, он создает символьную ссылку Global??D:, представляющую объект DeviceHarddiskVolume2. Windows-приложение, пытающееся открыть файл TempTest.txt на диске D:, указывает имя D: TempTest.txt, которое подсистема Windows преобразует в Global??D: TempTest.txt перед вызовом NtCreateFile — процедуры ядра, отвечающей за открытие файла. NtCreateFile использует диспетчер объектов для разбора имени, и диспетчер объектов обнаруживает объект «устройство» DeviceHarddiskVolume2 с еще не разрешенным путем TempTest.txt. Ha этом этапе диспетчер ввода-вывода проверяет, есть ли в VPB объекта DeviceHarddiskVolume2 ссылка на файловую систему. Если нет, диспетчер ввода-вывода выдает зарегистрированному драйверу файловой системы запрос на монтирование, чтобы выяснить, распознает ли он формат монтируемого тома как формат своей файловой системы.
ЭКСПЕРИМЕНТ: просмотр VPB
Увидеть содержимое VPB позволяет команда !vpb отладчика ядра. Поскольку на VPB указывает объект «устройство» тома, сначала нужно найти этот объект. Для этого создайте дамп объекта «драйвер» диспетчера томов, найдите объект «устройство», представляющий том, просмотрите его содержимое и вы обнаружите поле VPB.
Если в системе есть динамический диск, используйте команду !drvobj применительно к драйверу DMIO, а если нет — применительно к драйверу FtDisk. Вот пример:
Команда !drvobj перечисляет адреса объектов «устройство», принадлежащих драйверу. B этом примере таких объектов — семь. Один из них представляет программный интерфейс драйвера устройства, остальные — объекты томов. Поскольку объекты показываются в порядке, обратном порядку их создания, а первым создается объект «устройство» интерфейса драйвера устройства, то первый перечисленный объект «устройство» является объектом тома. Теперь введите команду !devobj отладчика ядра, указав в качестве параметра адрес объекта тома.
Команда !devobj показывает поле VPB объекта тома. (Данному объекту «устройство» присвоено имя HarddiskVolume6.) Теперь можно выполнить команду !vpb:
B итоге мы выяснили, что объект тома смонтирован драйвером файловой системы, который присвоил ему имя BACKUP. VPB-поле RealDevice указывает обратно на объект тома, а поле DeviceObject указывает на объект «устройство» смонтированной файловой системы.