- •Архитектура ОС UNIX
- •Контрольные вопросы
- •Функции для работы с файловой системой (системные функции)
- •Open
- •Open. Процесс 1
- •Open. Процесс 2
- •read
- •Алгоритм работы read
- •Алгоритм работы read
- •Read. Пример
- •Конкурирующие процессы
- •write
- •write
- •Указание позиции в файле, где будет выполняться ввод-вывод
- •close(fd)
- •Close
- •creat
- •mknod – создание спецфайлов
- •Процесс запоминает индекс нового каталога
- •stat(pathname,statbuffer);
- •Каналы
- •Каналы
- •Каналы
- •Пример использования каналов
- •Монтирование
- •Монтирование
- •Таблица монтирования:
- •Монтирование
- •Ссылки
- •Целостность файловой системы
- •АБСТРАКТНЫЕ ОБРАЩЕНИЯ К ФАЙЛОВЫМ СИСТЕМАМ
- •СОПРОВОЖДЕНИЕ ФАЙЛОВОЙ СИСТЕМЫ
Архитектура ОС UNIX
Работа с файловой системой.
Контрольные вопросы
Изобразите архитектуру ядра системы
Опишите структуру буферного кэша и заголовок буфера
Опишите дисковый индекс на диске и в памяти
Где и в какой структуре в системе хранятся номера свободных дисковых блоков?
Какие информационные структуры ядро использует для работы с процессами?
Откуда ядро берет индекс для создания нового файла?
Функции для работы с файловой системой (системные функции)
Open
fd = open(pathname,flags,modes)
pathname – имя файла flags – режим открытия
modes – права доступа, если файл создается
Возвращает целое число – пользовательский дескриптор файла.
* Все системные функции возвращают в случае неудачного завершения код -1
Open. Процесс 1
fd1 = open("/etc/passwd", O_RDONLY);
fd2 = open("local",O_RDWR);
fd3 = open("/etc/passwd", O_WRONLY);
Запись в таблице пользовательских дескрипторов файла по умолчанию хранит смещение в файле до адреса следующей операции ввода/вывода и указывает непосредственно на точку входа в таблице индексов для файла
Open. Процесс 2
fd1=open("/etc/passwd",O_RDONLY); fd2 = open("private",O_RDONLY);
Взаимосвязь между записями таблицы пользовательских дескрипторов файла и записями в таблице файлов ядра типа «один к одному».
Первые три пользовательских дескриптора (0, 1 и 2) именуются дескрипторами файлов: стандартного ввода, стандартного вывода и стандартного файла ошибок.
read
number = read(fd,buffer,count)
fd – файловый дескриптор, полученный из open;
buffer – адрес структуры данных в пользовательском процессе, где будут размещаться считанные данные;
count – количество байт, которые пользователю нужно прочитать;
number – количество фактически прочитанных байт.
Алгоритм работы read
1.Ядро обращается в таблице файлов к записи, которая соответствует значению пользовательского дескриптора файла fd
2.Ядро устанавливает значения нескольких параметров ввода-вывода в адресном пространстве процесса (чтобы не передавать как параметры функции)
3.Затем ядро обращается к индексу, используя указатель из таблицы файлов, и блокирует его прежде, чем начать чтение из файла
Алгоритм работы read
4.Затем выполняется цикл, пока операция чтения не будет произведена до конца.
1.Ядро преобразует смещение в байтах внутри файла в номер блока и вычисляет смещение внутри блока
2.Ядро считывает блок с диска в буфер
3.Ядро копирует данные из буфера по назначенному адресу в пользовательском процессе
4.Освобождает буфер и корректирует значения
параметров ввода-вывода в адресном пространстве процесса (смещение в файле через таблицу файлов и в принимаемом буфере)
5.Цикл завершается, либо когда ядро выполнит запрос пользователя, либо когда в файле не будет данных.
Read. Пример
|
#include <fcntl.h> |
|
#include <fcntl.h> |
|
|
|
|
||
|
main() |
|
main() |
|
|
{ |
|
{ |
|
|
int fd; |
|
int fd1,fd2; |
|
|
char lilbuf[20],bigbuf[1024]; |
|
char buf1[512],buf2[512]; |
|
|
|
|
||
|
|
|
|
|
|
|
|
fd1 = open("/etc/passwd",O_RDONLY); |
|
|
fd = open("/etc/passwd",O_RDONLY); |
|
fd2 = open("/etc/passwd",O_RDONLY); |
|
|
|
|||
|
read(fd,lilbuf,20); |
|
read(fd1,buf1,sizeof(buf1)); |
|
|
read(fd,bigbuf,1024); |
|||
|
read(fd2,buf2,sizeof(buf2)); |
|||
|
read(fd,lilbuf,20); |
|||
|
} |
|||
|
} |
|||
|
|
Выгодно для запросов ввода-вывода работать с данными, начинающимися на границах блоков файловой системы и имеющими размер, кратный размеру блока (1024 байта).
Это позволяет:
1.ядру избегать дополнительных итераций при выполнении цикла в алгоритме read
2.избегать всех вытекающих последствий, связанных с дополнительными обращениями к индексу в поисках номера блока, который содержит данные,
3.избегать конкуренции за использование буферного пула.