Скачиваний:
22
Добавлен:
09.05.2014
Размер:
354.82 Кб
Скачать

5, Как пользуясь блочным интерфейсом, так и не прибегая к структурированию

данных. Непосредственно работают с диском две важные программы - mkfs и

fsck. Программа mkfs форматирует раздел диска для файловой системы UNIX,

создавая при этом суперблок, список индексов, список свободных дисковых бло-

ков с указателями и корневой каталог новой файловой системы. Программа fsck

проверяет целостность существующей файловой системы и исправляет ошибки, как

показано в главе 5.

Рассмотрим программу, приведенную на Рисунке 10.8, в применении к файлам

"/dev/dsk15" и "/dev/rdsk15", и предположим, что команда ls выдала следующую

информацию:

ls -1 /dev/dsk15 /dev/rdsk15

br-------- 2 root root 0,21 Feb 12 15:40 /dev/dsk15

crw-rw---- 2 root root 7,21 Mar 7 09:29 /dev/rdsk15

Отсюда видно, что файл "/dev/dsk15" соответствует устройству блочного

типа, владельцем которого является пользователь под именем "root", и только

пользователь "root" может читать с него непосредственно. Его старший номер -

0, Младший - 21. Файл "/dev/rdsk15" соответствует устройству посимвольного

ввода-вывода, владельцем которого является пользователь "root", однако права

доступа к которому на запись и чтение есть как у владельца, так и у группы.

Его старший номер - 7, младший - 21. Процесс, открывающий файлы, получает

доступ к устройству через таблицу клю-

чей устройств ввода-вывода блоками и таблицу ключей устройств посимвольного

ввода-вывода, соответственно, а младший номер устройства 21 информирует

драйвер о том, к какому разделу диска производится обращение, например, дис-

ковод 2, раздел 1. Поскольку младшие номера у файлов совпадают, они ссылают-

ся на один и тот же раздел диска, если предположить, что это одно устройство

(***). Таким образом, процесс, выполняющий программу, открывает один и тот

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

(***) Не существует иного способа установить, что символьный и блочный драй-

веры ссылаются на одно и то же устройство, кроме просмотра таблиц сис-

темной конфигурации и текста программ драйвера.

303

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

смещению с адресом 8192 и считывает данные с этого места. Результаты выпол-

нения операций чтения должны быть идентичными при условии, что работает

только одна файловая система.

+------------------------------------------------------------+

| #include "fcntl.h" |

| main() |

| { |

| char buf1[4096], buf2[4096] |

| int fd1, fd2, i; |

| |

| if (((fd1 = open("/dev/dsk5/", O_RDONLY)) == -1) || |

| ((fd2 = open("/dev/rdsk5", O_RDONLY)) == -1))|

| { |

| printf("ошибка при открытии\n"); |

| exit(); |

| } |

| |

| lseek(fd1, 8192L, 0); |

| lseek(fd2, 8192L, 0); |

| |

| if ((read(fd1, buf1, sizeof(buf1)) == -1) || |

| (read(fd2, buf2, sizeof(buf2)) == -1)) |

| { |

| printf("ошибка при чтении\n"); |

| exit(); |

| } |

| |

| for (i = 0; i < sizeof(buf1); i++) |

| if (buf1[i] != buf2[i]) |

| { |

| printf("различие в смещении %d\n", i); |

| exit(); |

| } |

| printf("данные совпадают\n"); |

| } |

+------------------------------------------------------------+

Рисунок 10.8. Чтение данных с диска с использованием блочного

интерфейса и без структурирования данных

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

ставляют опасность, поскольку манипулируют с чувствительной информацией,

рискуя нарушить системную защиту. Администраторам следует защищать интерфей-

сы ввода-вывода путем установки прав доступа к файлам дисковых устройств.

Например, дисковые файлы "/dev/dsk15" и "/dev/rdsk15" должны принадлежать

пользователю с именем "root", и права доступа к ним должны быть определены

таким образом, чтобы пользователю "root" было разрешено чтение, а всем ос-

тальным пользователям и чтение, и запись должны быть запрещены.

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

также нарушить целостность данных в файловой системе. Алгоритмы файловой

системы, рассмотренные в главах 3, 4 и 5, координируют выполнение операций

ввода-вывода, связанных с диском, тем самым поддерживая целостность информа-

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

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

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

даже их программы написаны с большой осторожностью, проблема целостности все

304

равно не исчезнет, если они выполняются параллельно с работой другой файло-

вой системы. По этой причине программа fsck не должна выполняться при нали-

чии активной файловой системы.

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

буферного кеша. При работе с блочным интерфейсом ядро пользуется тем же ал-

горитмом, что и для файлов обычного типа, исключение составляет тот момент,

когда после преобразования адреса смещения логического байта в адрес смеще-

ния логического блока (см. алгоритм bmap в главе 4) оно трактует адрес сме-

щения логического блока как физический номер блока в файловой системе. За-

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

к стратегическому интерфейсу драйвера. Однако, при обращении к диску через

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

смещения в адрес файла, а передает его немедленно драйверу, используя для

передачи рабочее пространство задачи. Процедуры чтения и записи, входящие в

состав драйвера, преобразуют смещение в байтах в смещение в блоках и копиру-

ют данные непосредственно в адресное пространство задачи, минуя буферы ядра.

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

а второй процесс затем считывает с устройства символьного типа по тому же

адресу, второй процесс может не считать информацию, записанную первым про-

цессом, так как информация может еще находиться в буферном кеше, а не на

диске. Тем не менее, если второй процесс обратится к устройству блочного ти-

па, он автоматически попадет на новые данные, находящиеся в буферном кеше.

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

ситуацией. Если процесс читает или пишет на устройство посимвольного вво-

да-вывода порциями меньшего размера, чем, к примеру, блок, результаты будут

зависеть от драйвера. Например, если производить запись на ленту по 1 байту,

каждый байт может попасть в любой из ленточных блоков.

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

если не возникает необходимость в кешировании данных для дальнейшей работы.

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

мацию блоками, размер каждого из которых ограничивается размером логического

блока в данной файловой системе. Например, если размер логического блока в

файловой системе 1 Кбайт, за одну операцию ввода-вывода может быть передано

не больше 1 Кбайта информации. При этом процессы, обращающиеся к диску с по-

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

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

лера. С функциональной точки зрения, процесс получает тот же самый резуль-

тат, но символьный интерфейс может работать гораздо быстрее. Если воспользо-

ваться примером, приведенным на Рисунке 10.8, можно увидеть, что когда про-

цесс считывает 4096 байт, используя блочный интерфейс для файловой системы с

размером блока 1 Кбайт, ядро производит четыре внутренние итерации, на каж-

дом шаге обращаясь к диску, прежде чем вызванная системная функция возвраща-

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

жет закончить чтение за одну дисковую операцию. Более того, использование

блочного интерфейса вызывает дополнительное копирование данных между адрес-

ным пространством задачи и буферами ядра, что отсутствует в символьном ин-

терфейсе.

Соседние файлы в папке материалы к собеседованию