Файловые системы

 

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

Ведь вы же не будете набирать вашу программу каждый раз при новом включении компьютера. Правда, на PDP-11 такое еще было возможным; в НГУ даже ходят легенды о людях, которые набирали с консоли в пультовом режиме тетрис, и играли в него, пока сетевой файловый сервер висел. А если программа - это пакет типа CorelDraw!, исходный текст которого занимает десятки тысяч строк, а бинарный загрузочный модуль - полтора мегабайта?

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

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

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

Файл - это совокупность данных, доступ к которой осуществляется по ее имени.

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

ОС семейства Unix трактуют понятие файла более широко - там файлом называется любой объект, имеющий имя в файловой системе. Однако файлы, не являющиеся совокупностями данных (каталоги, внешние устройства, псевдоустройства, именованные программные каналы, семафоры Xenix), часто называют не простыми файлами, а ``специальными''.

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

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

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

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


Файлы с точки зрения пользователя

Формат имен файлов

В различных ФС допустимое имя файла может иметь различную длину, и в нем могут использоваться различные наборы символов. Так, в RT-11 и RSX-11 имена файлов состоят из символов кодировки RADIX-50 и имеют длину 9 символов: 6 символов - собственно имя, а 3 - расширение. При этом имя имеет вид "XXXXXX.XXX", но символ '.' не является частью имени - это просто знак препинания. Предполагается, что расширение должно соответствовать типу данных, хранящихся в файле: .SAV будет именем абсолютного загружаемого модуля, .FOR - программы на Фортране, .CRH - ``файлом информации о системном крахе", как было написано в одном переводе руководства (попросту говоря, это посмертная выдача ОС, по которой можно попытаться понять причину аварии).

В CP/M и ее потомках MS DOS-DR DOS, а также в VMS имена файлов хранятся в 8-битной ASCII-кодировке, но почему-то разрешено использование только букв верхнего регистра, цифр и некоторых печатаемых символов. При этом в системах линии CP/M имя файла имеет 8 символов + 3 символа расширения, а в VMS как имя, так и расширение могут содержать более 32 символов.

Любопытно, что MS/DR DOS при поиске в каталоге переводят в верхний регистр имя, заданное пользователем, но оставляют как есть имя, считанное из каталога. Строго говоря, это ошибка: если мы создадим имя файла, содержащее буквы нижнего регистра, то ни одна программа не сможет открыть или переименовать такой файл.

Одному из авторов довелось столкнуться с такой проблемой при попытке прочитать дискету, записанную ОС TC (Экспериментальная UNIXоподобная ОС для Паскаль-машины N9000). Проблему удалось решить только при помощи шестнадцатиричного дискового редактора прямым редактированием имен в каталогах. Возможно, существует и более элегантное решение, но авторам не удалось его найти. Использовать конструкцию *.* бесполезно, потому что, в действительности, операции над файлами, заданными таким образом, состоят из двух операций: FindFirst/FindNext, возвращающей [следующее] имя файла, соответствующее шаблону, и Open. FindFirst/FindNext возвращает недопустимое имя файла и Open не может использовать его. Программа CHKDSK не возражает против имен файлов в нижнем регистре. Строго говоря, это тоже ошибка. Все остальные способы так или иначе сводятся к прямой (в обход ДОС) модификации ФС.

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

Наибольшим либерализмом в смысле имен отличаются ОС семейства Unix, в которых имя файла может состоять из любых символов кодировки ASCII, кроме символов '\000' и '/', например, из восьми символов перевода каретки. При этом '\000' является ограничителем имени, а '/' - разделителем между именем каталога и именем файла. Никакого разделения на имя и расширение нет, и хотя имена файлов с программой на языке C заканчиваются ".c", а объектных модулей - ".o", точка здесь является частью имени. Вы можете создать файл с именем "gcc-2.5.8.tar.gz". В UNIX SVR3 длина имени файла ограничена 14 символами, а в BSD UNIX, Linux и SVR4 - только длиной блока на диске, т.е. 512 байтами или более. При этом нулевой символ считается концом имени в каталоге.

Возможность использовать в именах неалфавитные символы типа перевода каретки или ASCII EOT кажется опасным излишеством. На самом деле:

  1. Это не излишество а, скорее, упрощение - из процедур, работающих с именами, удалена проверка символа на ``допустимость''.
  2. Оно не столь уж опасно: такой файл всегда можно переименовать. В некоторых случаях процесс набора имени файла в командной строке превращается в нетривиальное упражнение, потому что shell (командный процессор) рассматривает многие неалфавитные символы как команды. Но надо отметить, что, правильно используя кавычки и символ '\', пользователь может передать команде аргумент, содержащий любые символы ASCII, кроме \000".

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

Например, OS/2, использующая файловую систему HPFS (High Performance File System - высокопроизводительная файловая система), поддерживает имена файлов длиной до 256 символов, содержащие печатаемые символы и пробелы. Точка считается частью имени, как и в UNIX, и можно создавать имена, содержащие несколько точек.

При этом нужно отметить, что система при поиске файла приводит к одному регистру все алфавитные символы в имени. С одной стороны, это означает дополнительное удобство для пользователя - при наборе имени не нужно заботиться о регистре букв, с другой - пользователь не может создать в одном каталоге файлы "text.txt" и "Text.txt". Из-за этого, например, нельзя использовать принятое в UNIX соглашение о том, что файл на языке C имеет расширение ".c", а на языке C++ - ".C".

Поддержка длинных имен файлов реализована и в наследнике линии CP/M-MS DOS, операционной системе Windows 95, ранее известной под кодовым именем Chicago.

Некоторые ОС, например, RSX-11 и VMS, поддерживают также номер версии файла. В каталоге может существовать несколько версий файла с одним именем; если номер версии при открытии файла не задается, то открывается последняя версия.

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

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

Операции над файлами

Большинство современных ОС рассматривают файл как неструктурированную последовательность байт переменной длины. В стандарте POSIX над файлом определены следующие операции:

Еще две операции выполняются уже не над файлом, а над его именем: это операции переименования и удаления файла. В некоторых системах, например в системах семейства Unix, файл может иметь несколько имен, и существует только системный вызов для удаления имени. Файл удаляется при удалении последнего имени.

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

Примерно та же модель работы с файлами принята в CP/M, а набор файловых системных вызовов MS DOS фактически скопирован с вызовов Unix v7. В свою очередь, OS/2 и Windows NT унаследовали принципы работы с файлами непосредственно от MS DOS.

Напротив, в системах, не имеющих Unix в родословной, может использоваться несколько иная трактовка понятия файла. Чаще всего файл трактуется как набор записей. Обычно система поддерживает записи как постоянной длины, так и переменной. Например, текстовый файл интерпретируется как файл с записями переменной длины, а каждой строке текста соответствует одна запись. Такова модель работы с файлами в VMS и в ОС линии OS/360-MVS фирмы IBM.

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

Тип файла

 

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

Например, с точки зрения системы исходный текст программы на языке C и документ в формате LaTeX совершенно идентичны: и то и другое представляет собой текстовый файл (или, если угодно, файл с записями переменной длины). Однако, если мы попытаемся подать наш документ на вход C-компилятора, мы получим множество синтаксических ошибок и никакого полезного результата.

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

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

Так, например Explorer - пользовательская оболочка Windows 95 и Windows NT 4.0 - позволяет связать ту или иную программу с файлами, имеющими определенное расширение, например, программу MS Word с файлами, имеющими расширение .DOC. Когда пользователь нажимает левой кнопкой мыши на иконке, представляющей такой файл, то автоматически запускается MS Word. Эти же ассоциации доступны и из командной строки - можно напечатать start Доклад.DOC и опять-таки запустится MS Word.

Такое связывание очень просто в реализации и реализуется не только в Explorer, но и в простых текстовых оболочках вроде Norton Commander. От ОС при этом требуется только дать возможность каким-то образом различать типы файлов.

Первые попытки ассоциировать с файлом признак типа были сделаны еще в 60 гг. При этом идентификатор типа добавлялся к имени файла в виде короткой, но мнемонической последовательности символов - расширения (extension). В большинстве современных ОС расширение отделяется от имени символом '.', но проследить истоки этой традиции авторам не удалось. При этом, например, файлы на языке C будут иметь расширение ".c", на C++ - ".C", а документы в формате LaTeX - ".tex".

В ОС семейства Unix имя файла может содержать несколько символов '.', и, таким образом, файл может иметь несколько каскадированных расширений. Например, файл "main.C" - это программа на языке C++; "main.C.gz" - это программа на языке C++, упакованная архиватором GNU Zip с целью сэкономить место; "main.C.gz.crypt" - это программа, которую упаковали и потом зашифровали, чтобы никто посторонний не смог ее прочитать; наконец, "main.C.gz.crypt.uue" - это упакованная и зашифрованная программа, преобразованная в последовательность печатаемых символов кода ASCII, например, для пересылки по электронной почте.

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

Например, стандартный драйвер компилятора в системах семейства Unix - программа cc - определяет тип файла именно по расширению. Командная строка

Example:

     cc main.C c-code.c asm-code.s obj-code.o\
          library.a -o program

будет интерпретироваться следующим образом:

main.C:
текст на языке C++. Его нужно пропустить через препроцессор и откомпилировать компилятором C++, а затем передать то, что получится, редактору связей. Большинство компиляторов в Unix генерируют код на ассемблере, то есть вывод компилятора еще нужно пропустить через ассемблер.

c-code.c:
текст на языке C. Он обрабатывается, так же, как и C++-программа, только вместо компилятора C++ используется обычный компилятор C.

asm-code.s:
программа на языке ассемблера. Ее нужно обработать ассемблером и получить объектный модуль.

obj-code.o:
объектный модуль, который непосредственно можно передавать редактору связей.

library.a:
объектная библиотека, которую нужно использовать для разрешения внешних ссылок наравне со стандартными библиотеками.

Многие ОС, разработанные в 70-е гг., такие как RT-11, RSX-11, VAX/VMS, CP/M, навязывают программисту разделение имени на собственно имя и расширение, интерпретируя точку в имени файла как знак препинания. В таких системах имя может содержать только одну точку и соответственно иметь только одно расширение. Напротив, в ОС нового поколения - OS/2, Windows NT и даже в Windows 95 - реализована поддержка имен файлов свободного формата, которые могут иметь несколько каскадированных расширений, как и в Unix.

Однако никакие средства операционной системы не могут навязать прикладным программам правил выбора расширения для файлов данных. Это приводит к неприятным коллизиям. Например, почти все текстовые процессоры от Лексикон до Word 7.0 включительно используют расширение файла .doc (сокращение от document), хотя форматы файлов у различных процессоров и даже у разных версий одного процессора сильно различаются.

Другая проблема связана с исполняемыми загрузочными модулями. Обычно система использует определенное расширение для исполняемых файлов. Так, VMS, MS/DR DOS, OS/2, MS Windows и Windows NT используют расширение .exe: сокращение от executable (исполняемый). Однако по мере развития системы формат загрузочного модуля может изменяться. Так, например, OS/2 v3.0 Warp поддерживает по крайней мере пять различных форматов загрузочных модулей.

  1. 16-разрядные сегментированные загрузочные модули: формат OS/2 1.x.
  2. 32-разрядные загрузочные модули, использующие ``плоскую'' (flat) модель памяти: формат OS/2 2.x.
  3. 32-разрядные модули нового формата, использующие упаковку кода и данных: формат OS/2 3.x.
  4. DOS-овские .exe и .com модули.
  5. Загрузочные модули MS Windows.

Для исполнения последних двух типов программ OS/2 создает задачу, работающую в режиме совместимости с 8086. Эта задача запускает копию ядра DOS и, если это необходимо, копию MS Windows, которые уже выполняют загрузку программы. Загрузочные модули всех трех ``родных'' форматов загружаются системой непосредственно.

Так или иначе загрузчик должен уметь правильно распознавать все форматы. При этом он не может использовать расширение файла: файлы всех перечисленных форматов имеют расширение .EXE.

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

Разработчики Unix столкнулись с этой проблемой еще в 70 гг. В качестве решения они предложили использовать магические числа (magic number) - соглашение о том, что файлы определенного формата содержат в начале определенный байт или последовательность байтов. Первоначально это были численные коды; файл /etc/magic содержал коды, соответствующие известным типам файлов. Позднее в качестве магических чисел стали использоваться длинные текстовые строки. Так, например, изображения в формате Compuserve GIF 87a должны начинаться с символов GIF87a.

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

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

Example:

GIF87a -- это очень плохой формат
хранения изображений.

будет воспринят некоторыми программами как изображение в формате Compuserve GIF 87a, каковым он, безусловно, не является.

Пытаясь как-то решить проблему идентификации типа файла, разработчики Macintoch отказались как от расширений, так и от магических чисел. В MacOS каждый файл состоит из двух частей или ветвей (forks): ветви данных (data fork) и ветви ресурсов (resource fork). Кроме идентификатора типа файла, ветвь ресурсов хранит информацию о:

Еще дальше в этом же направлении пошли разработчики системы OS/2. В этой системе с каждым файлом связан набор расширенных атрибутов (extended attributes). Атрибуты имеют вид ИМЯ:Значение. При этом значение может быть как текстовой строкой, так и блоком двоичных данных произвольного формата и размера. Некоторые расширенные атрибуты используются оболочкой Workplace Shell (WPS) как эквивалент ветви ресурсов в MacOS: для идентификации типа файла, связанной с ним иконы и размещения этой иконы в открытом окне. Тип файла идентифицируется текстовой строкой. Например, программа на языке C идентифицируется строкой C code. Это резко уменьшает вероятность конфликта имен типов - ситуацию, довольно часто возникающую при использовании расширений или магических чисел.

Другие атрибуты могут использоваться для других целей. Например, LAN Server - файловый сервер фирмы IBM - использует расширенные атрибуты для хранения информации о собственнике файла и правах доступа к нему. Некоторые текстовые редакторы используют расширенные атрибуты для хранения положения курсора при завершении последней сессии редактирования, так что пользователь всегда попадает в то место, где он остановился в прошлый раз.

Кроме того, расширенные атрибуты могут использоваться и для хранения сведений о назначении файла. В OS/2 существуют предопределенные расширенные атрибуты с именами Subject (тема), Comment (комментарии) и Key phrases (ключевые фразы), которые могут, например, использоваться для поисков документов, относящихся к заданной теме. К сожалению, такой поиск возможен только если создатель документа позаботился присвоить этим атрибутам правильные значения...

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

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

Если мы монтируем ФС, размещенную на удаленной машине (файловом сервере), то шаги 1 и 2 заменяются на установление соединения этим файловым сервером.

Многие пользователи MS/DR DOS никогда не сталкивались с понятием монтирования. Дело в том, что эта система (как и многие другие ДОС, например RT-11) выполняет упрощенную процедуру монтирования при каждом обращении к файлу. Упрощения состоят в пропуске шагов 1 и 2 и отсутствии шага 4 (ФС MS/DR DOS устойчива к сбоям).

При работе с файловыми серверами Novell Netware монтирование серверных файловых систем производится командой MAP.

Обычно имя файла в подмонтированной файловой системе имеет вид ИМЯ_ФС:\имена\каталогов\имя.файла При этом вместо разделителей ':' и '\' могут использоваться другие символы.

В RT-11, RSX-11 и VMS в качестве имени файловой системы используется имя физического устройства, на котором размещена ФС. Если используется DECNet, перед именем устройства можно поместить имя узла сети, на котором это устройство находится. Полное имя файла в VMS выглядит так: DUA0:[USERS.FAT_BROTHER.WORK]test.exe. При этом DUA0 означает дисковое устройство 0, присоединенное к дисковому контроллеру A: Disk Unit A [device #] 0, USERS.FAT_BROTHER.WORK] означает каталог WORK в каталоге FAT_BROTHER в каталоге USERS.

В CP/M, MS/DR DOS и OS/2 имена файловых систем обозначаются буквами латинского алфавита, а сами файловые системы часто почему-то называются ``драйвами''. При некотором желании можно использовать в качестве имен ФС также символы '[' и ']'. Устройства A: и B: - это всегда дисководы гибких дисков; устройство C: - обычно первый жесткий диск, или первый раздел на первом жестком диске.

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

В OS/2, Windows NT и Windows for Workgroups эта проблема решена использованием так называемых UNC-имен, задающих имя файла в виде \\NODE\SHARE\PATH\FILE.NAM, где NODE - это имя сетевого узла, SHARE - имя разделяемого ресурса на этом узле (это может быть не только разделяемый каталог, но и принтер, а в OS/2 также и модем), а PATH\FILE.NAM - путь к файлу относительно разделяемого каталога. К сожалению, далеко не все старые программы понимают такие имена. Например, даже стандартный командный процессор системы Windows NT не может исполнить команду cd \\NODE\SHARE\DIR.

ДОС, как правило, помещают в пространство имен все доступные блочные устройства, не выполняя полной процедуры монтирования. Если какое-то из этих устройств не содержит ФС известного типа, то система будет возмущаться при обращениях к такому устройству, но не удалит его из списка доступных ФС. А иногда даже не будет возмущаться - попробуйте поставить в дисковод машины под управлением MS/DR DOS дискету, не содержащую файловой системы (например, созданную программой tar) и сказать DIR A:. Скорее всего, вы увидите несколько экранов мусора, но ни одного сообщения об ошибке!

В операционных системах семейства Unix смонтированные ФС выглядят как каталоги единого дерева, начинающегося с корневого каталога, выделенной первой ФС, называемой корневой (root). Администратор системы может подмонтировать новую ФС к любому каталогу, находящемуся на любом уровне дерева. Такой каталог после этого называют ``точкой монтировки'', но это выражение отражает только текущее состояние каталога. После того как мы размонтируем ФС, мы сможем использовать этот каталог как обычный, и наоборот, мы можем сделать точкой монтировки любой каталог.

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

По традиции все Unix-системы имеют примерно одинаковую структуру дерева каталогов: системные утилиты находятся в каталоге /bin, системные библиотеки - в каталоге /lib, конфигурационные файлы - в каталоге /etc и т.д. Например, база данных об именах пользователей всегда находится в файле /etc/passwd.


Next: Структуры файловых систем Up: Contents

Т.Б.Большаков: tbolsh@inp.nsk.su
Д.В.Иртегов fat@cnit.nsu.ru
latex2html conversion Thu Mar 27 14:44:19 NSK 1997