Выбрать главу

Windows включает клиентский удаленный FSD, LANMan Redirector (редиректор), и серверный удаленный FSD, LANMan Server (сервер) (\Windows\ System32\Drivers\Srv.sys). Редиректор реализован в виде комбинации порт- и минипорт-драйверов, где порт-драйвер (\Windows\System32\Drivers \Rdbss.sys) представляет собой библиотеку подпрограмм, а минипорт-драйвер (\Windows\System32\Drivers\Mrxsmb.sys) использует сервисы, реализуемые порт-драйвером. Еще один минипорт-драйвер редиректора — WebDAV (\Win-dows\System32\Drivers\Mrxdav.sys), который реализует клиентскую часть поддержки доступа к файлам по HTTR Модель «порт-минипорт» упрощает разработку редиректора, потому что порт-драйвер, совместно используемый всеми минипорт-драйверами удаленных FSD, берет на себя многие рутинные операции, требуемые при взаимодействии между клиентским FSD и диспетчером ввода-вывода Windows. B дополнение к FSD-компонентам LANMan Redirector и LANMan Server включают Windows-службы рабочей станции и сервера соответственно. Взаимодействие между клиентом и сервером при доступе к файлам на серверной стороне через редиректор и серверные FSD показано на рис. 12-6.

Для форматирования сообщений, которыми обмениваются редиректор и сервер, Windows использует протокол CIFS (Common Internet File System). CIFS — это версия протокола Microsoft SMB (Server Message Block). (Подробнее o CIFS см. книгу «Сети TCP/IP. Ресурсы Microsoft Windows 2000 Server» и сайт www.cifs.com.)

Как и локальные FSD, удаленные FSD на клиентской стороне обычно используют сервисы диспетчера кэша для локального кэширования файловых данных, относящихся к удаленным файлам и каталогам. Однако удаленный FSD на клиентской стороне должен реализовать протокол поддержки когерентности распределенного кэша, называемый oplock (opportunistic locking), гарантирующий, что любое приложение при обращении к удаленному файлу получит те же данные, что и приложения на других компьютерах в сети. Хотя удаленные FSD на серверной стороне участвуют в поддержании коге рентности клиентских кэшей, они не кэшируют данные локальных FSD, поскольку те сами кэшируют свои данные.

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

Level I oplock предоставляется при монопольном доступе клиента к файлу Клиент, удерживающий для файла oplock этого типа, может кэшировать операции как чтения, так и записи.

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

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

B отсутствие oplock клиент не может осуществлять локальное кэширование ни операций чтения, ни операций записи; вместо этого он должен получать данные с сервера и посылать все изменения непосредственно на сервер.

Проиллюстрировать работу oplock поможет пример на рис. 12-7. Первому клиенту, открывающему файл, сервер автоматически предоставляет Level I oplock. Редиректор на клиентской стороне кэширует файловые данные при чтении и записи в кэше файловой системы локальной машины. Если тот же файл открывает второй клиент, он также запрашивает Level I oplock. Теперь уже два клиента обращаются к одному и тому же файлу, поэтому сервер должен принять меры для согласования представления данных файла обоим клиентам. Если первый клиент произвел запись в файл (этот случай и показан на рис. 12-7), сервер отзывает oplock и больше не предоставляет его ни одному клиенту. После отзыва oplock первый клиент сбрасывает все кэшированные данные файла обратно на сервер.

Если бы первый клиент не произвел запись, его oplock был бы понижен до Level II oplock, т. е. до oplock того же типа, который сервер предоставляет второму клиенту. B этом случае оба клиента могли бы кэшировать операции чтения, но после операции записи любым из клиентов сервер отозвал бы их oplock, и последующие операции были бы некэшируемыми. Однажды отозванный, oplock больше не предоставляется для этого экземпляра открытого файла. Однако, если клиент закрывает файл и повторно открывает его, сервер заново решает, какой oplock следует предоставить клиенту. Решение сервера зависит от того, открыт ли файл другими клиентами и производил ли хоть один из них запись в этот файл.

ЭКСПЕРИМЕНТ: просмотр списка зарегистрированных файловых систем

Диспетчер ввода-вывода, загружая в память драйвер устройства, обычно присваивает имя объекту «драйвер», который создается для представления этого драйвера. Этот объект помещается в каталог \Drivers диспетчера объектов. Объекты «драйвер» любого загружаемого диспетчером ввода-вывода драйвера с атрибутом Туре, равным SERVICEFILE _SYSTEM_DRIVER (2), помещаются этим диспетчером в каталог \File-System. Таким образом, утилита типа Winobj (wwwsysintemals.com) позволяет увидеть зарегистрированные файловые системы, как показано на следующей иллюстрации. (Заметьте, что некоторые драйверы файловых систем помещают в каталог \FileSystem и объекты «устройство».)

Еще один способ увидеть зарегистрированные файловые системы — запустить программу System Information (Сведения о системе). B Windows 2000 запустите оснастку Computer Management (Управление компьютером) и выберите Drivers (Драйверы) в Software Environment (Программная среда) в узле System Information (Сведения о системе); в Windows XP и Windows Server 2003 запустите Msinfo32 и выберите System Drivers (Системные драйверы) в узле Software Environment (Программная среда). Отсортируйте список драйверов, щелкнув колонку Туре (Тип), и драйверы с атрибутом SERVICE_FILE_SYSTEM_DRIVER окажутся в начале списка.

Заметьте: если драйвер регистрируется как SERVICE_FILE_SYSTEM_DRIVER, это еще не означает, что он служит локальным или удаленным FSD. Например, Npfs (Named Pipe File System), присутствующий на только что показанной иллюстрации, на самом деле является драйвером сетевого API — он поддерживает именованные каналы, но реализует закрытое пространство имен и поэтому в какой-то мере подобен драйверу файловой системы. Пространство имен Npfs исследуется в одном из экспериментов в главе 13.

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

Система и приложения могут обращаться к файлам двумя способами: напрямую (через функции ввода-вывода вроде ReadFile и WriteFile) и косвенно, путем чтения или записи части своего адресного пространства, где находится раздел проецируемого файла (подробнее о проецируемых файлах см. главу 7). Упрощенная схема на рис. 12-8 иллюстрирует компоненты, участвующие в работе файловой системы, и способы их взаимодействия. Как видите, есть несколько путей вызова FSD:

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

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

неявно из подсистемы отложенной записи, принадлежащей диспетчеру кэша;

неявно из потока опережающего чтения, принадлежащего диспетчеру кэша;

из обработчика ошибок страниц, принадлежащего диспетчеру памяти.

Явный файловый ввод-вывод

Наиболее очевидный способ доступа приложения к файлам — вызов Windows-функций ввода-вывода, например CreateFile, ReadFile и WriteFile. Приложение открывает файл с помощью CreateFile, а затем читает, записывает и удаляет его, передавая описатель файла, возвращенный CreateFile, другим Windows-функциям. CreateFile, реализованная в Kernel32.dll, вызывает встроенную функцию NtCreateFile и формирует полное имя файла, обрабатывая символы «.» и «…» и предваряя путь строкой «\??» (например, \??\C: \Daryl\Todo.txt).