Linux Kernel (Ядро линукса) (часть 2)


Блокировки FL_FLOCK

На этом сайте мы заказали дешевые авиабилеты из санкт петербурга через интернет

Блокировка fl flock всегда связана с файловым объектом и, следовательно, принадлежит процессу, открывшему файл (или всем клонированным процессам, совместно использующим один открытый файл). Когда блокировка запрошена и предоставлена, ядро меняет любую другую блокировку, имеющуюся у данного процесса для данного файла, на новую. Это происходит только в том случае, если процесс хочет сменить блокировку чтения на блокировку записи, или наоборот. Далее, когда файловый объект освобождается функцией fput , все блокировки fl flock, ссылающиеся на данный файловый объект, разрушаются. Однако могут существовать иные блокировки fl flock, установленные другими процессами для того же файла (индексного дескриптора), и они останутся активными.

Системный вызов flock о позволяет процессу применить или снять рекомендательную блокировку по отношению к открытому файлу. Он имеет два параметра: дескриптор fd файла, на который нужно воздействовать, и cmd — параметр, определяющий операцию блокирования. Параметр cmd, имеющий значение lock sh, запрашивает совместную блокировку на чтение, значение lock ex определяет исключительную блокировку на запись, a lock un снимает блокировку.

Фактически системный вызов flock в состоянии устанавливать обязательные блокировки в совместном режиме с помощью команды lock mand. Однако мы не будем обсуждать этот случай.

Как правило, этот системный вызов блокирует текущий процесс, если запрос не может быть удовлетворен немедленно, например, если процессу требуется исключительная блокировка, в то время как другой процесс ее уже имеет. Однако если флаг lock nb передан вместе с операцией lock sh или lock ex, системный вызов не приостанавливает процесс. То есть если блокировка не может быть получена немедленно, системный вызов возвращает код ошибки.
Когда вызывается служебная процедура sys flock , она выполняет следующие действия:
1. Проверяет, является ли fd допустимым дескриптором файла. Если это не так, возвращает код ошибки. Получает адрес fiip соответствующего файлового объекта.
2. Проверяет, есть ли у процесса право на чтение/запись в отношении открытого файла. Если нет, возвращает код ошибки.
3. Получает lock, новый объект fiie iock, и инициализирует его должным образом: поле fi type устанавливается в соответствии со значением параметра cmd; в поле fi fiie записывается адрес fiip файлового объекта; полю fi fiags присваивается значение fl flock; в поле fi pid записывается значение current->tgid; а поле fi end устанавливается в значение -1, чтобы отметить тот факт, что блокирование относится ко всему файлу (а не к какой-то его части).
4. Если параметр cmd не включает в себя lock nb, процедура добавляет в поле fl_flags флаг FL_SLEEP.
5. Если для файла определена операция flock, процедура вызывает ее, передавая в качестве параметров указатель на файловый объект fiip, некий флаг (f setlkw или f setlk, в зависимости от значения lock nb) и адрес НОВОГО объекта lock типа f ile_lock.
6. В противном случае, если файловая система не определяет функцию flock (что является типичной ситуацией), процедура вызывает fiock_iock_ fiie waito, пытаясь выполнить требуемую операцию блокировки. Этой функции передаются два параметра: fiip, указатель на файловый объект, и адрес нового объекта lock, типа fiie iock, созданного на шаге 3.
7. Если дескриптор fiie iock не был занесен в список активных или задержанных блокировок на предыдущем шаге, процедура освобождает его.
8. В случае успеха возвращает 0.

Функция f lock iock f iie wait выполняет в цикле следующие действия:
1. Вызывает функцию fiock iock fiieо, передавая в качестве параметров
fiip, указатель на файловый объект, а также адрес нового объекта lock,
типа fiie iock. Вызванная функция, в свою очередь, выполняет следующие операции:
• производит поиск в списке, на который указывает fiip->f_dentry->
d_inode->i_flock. ЕСЛИ блокировка FL FLOCK ДЛЯ ТОГО Же фаЙЛОВОГО
объекта найдена, функция проверяет ее тип (lock sh или lock ex). Если тип совпадает с типом новой блокировки, функция возвращает 0 (ничего не нужно делать). В противном случае она удаляет старый элемент из списка блокировок для данного индексного дескриптора и из глобального списка блокировок файлов, возобновляет выполнение всех ждущих процессов в очередях блокировок из списка fi biock и освобождает структуру file lock;
• если процесс выполняет снятие блокировки (lock un), больше ничего делать не нужно. Блокировки не было, либо она уже снята. Возвращается 0;
• если блокировка fl flock для того же файлового объекта найдена (то есть процесс меняет уже имеющуюся блокировку чтения на блокировку записи или наоборот), то функция предоставляет некоторым высокоприоритетным процессам, в частности, каждому процессу, ранее приостановленному по причине старой блокировки, возможность поработать, ДЛЯ чего она вызывает функцию cond_resched ;
• снова выполняет поиск в списке блокировок для данного индексного дескриптора, чтобы убедиться, что никакая из существующих блокировок fl flock не конфликтует с запрошенной. В списке не должно быть блокировок чтения fl flock, а если процесс запрашивает блокировку чтения, то там вообще не должно быть блокировок fl flock;
• если конфликтующие блокировки отсутствуют, функция вставляет новую структуру fiie iock в список блокировок индексного дескриптора и в глобальный список блокировок файлов, после чего возвращает 0 (успешное завершение);
• если конфликтующая блокировка найдена, происходит следующее. Если флаг fl sleep в поле fi fiags установлен, функция заносит новую блокировку (ждущую) в циклический список задерживающей блокировки и в глобальный список задержанных блокировок;
• возвращает код ошибки -eagain.
2. Проверяет код возврата функции f lock iock fiie :
• если код возврата 0 (нет конфликтов), возвращает 0 (успешное завершение);
• обнаружена несовместимость. Если флаг fl sleep в поле fi fiags сброшен, функция освобождает дескриптор fiie iock и возвращает
-eagain;
• в противном случае, когда несовместимость есть, но процесс может быть приостановлен, функция вызывает wait_event_interruptible, чтобы занести текущий процесс в очередь iock->fi_wait и приостановить его. Когда выполнение процесса будет возобновлено (сразу после снятия задерживающей блокировки), функция возвращается к шагу 1 и повторяет цикл.

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

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без проблем

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга для вас. А так как к книге прилагается компакт- диск с готовой к работе операционной системой Knoppix Live CD, то лишь достаточно вставить его в привод и перегрузить компьютер,...

Linux Kernel (Ядро линукса) (часть 1)

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть другие прерывания того же типа, и другие процессоры могут приступить к их обработке. Без спин-блокировки к главному дескриптору прерывания могли бы обратиться сразу несколько процессоров. Как мы...

Linux Kernel (Ядро линукса) (часть 2)

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно неуклюже: получив системный вызов fork о, ядро в буквальном смысле дублировало все адресное пространство родителя и присваивало копию процессу-потомку. Такая операция...

Linux Kernel (Ядро линукса) (часть 3)

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