LINUX.ORG.RU

Ошибка обработки запроса в блочном устройстве


0

0

Есть свой собственнй модуль для блочного устройств по ядро 2.4.27.

В нем есть функция block_request которая инициализируется как обработчик очереди.

После обработки запроса (чтения или записи), если все хорошо end_request(1)

Но если возникает ошибка обработки запроса, то вызываю функцию end_request( 0 )

При этом в основной программе я открываю данное блочное устройсво и начинаю писать в него данные (например линейно). Я вижу как перебираются сектора и данные. Если все хорошо write возращает количество записаннх данных - все Ок.

Но если все плохо, (я говорю end_request(0)), то на экране я вижу сообщение ядра о том что возникла ошибка ввода вывода по такомоту сектору, но приетом в главной программе write по прежнему не знает о ней - возвращает количество якобы успешно записанных байт и наступает следующий запрос на обработку блока.

Что надо сказать в блочном устройстве (в обрабочике очереди запросов), что бы write вернул ошибку записи в блочное устройство?

С уважением, Подколзин Игорь.

Re: Ошибка обработки запроса в блочном устройстве

Во-первых, нужно ли тебе именн _блочное_ устройство? Во-вторых, LDD[23] :)

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Да мне нужно именно блочное устройство - это диск.

Так в данной редакции предлагают следующий код:

/* Process all of the buffers in this (possibly clustered) request. */ do { status = sbull_transfer(device, req); } while (end_that_request_first(req, status, DEVICE_NAME)); spin_unlock(&device->lock); spin_lock_irq (&io_request_lock); end_that_request_last(req);

А в моих исходных кодах данного примера было по другому:

spin_lock(&device->lock); status = sbull_transfer(device, CURRENT); spin_unlock(&device->lock); end_request(status);

Жаль... Пойду пробовать. спасибо.

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

После размышлений на свежую голову, вот моя версия: у тебя в драйвере всё правильно (раз система жалуется - значит, она видит возвращенный тобой код ошибки). Но вот _тест_ у тебя принципиально неправильный: вызов write в Linux (и любом UNIX) не пишет данные на устройство, а оставляет их в кэше, и ошибка при записи происходит потом, когда о ней уже некому сообщить. Решения - смонтировать ФС с опциями синхронной записи, делать fsync или fdatasync, или использовать direct io (если на твоем устройстве нет ФС).

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Переделал под новую концепцию (как написано в LDD) - все тоже самое.

Да, судя по всему дело во write (кеше).

Как сделать direct io? Просто там еще нет ФС. Она накладывается чуть позже.

Спасибо.

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

> Как сделать direct io? Просто там еще нет ФС. Она накладывается чуть позже.

Если верить man 2 open. надо открыть файл с флагом O_DIRECT. Почитай там о требованиях по выравниванию.

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Хотя я припоминаю еще один способ direct io (времен еще 2.2) - создание специальных символьных устройств, и работа с ними.

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Сивольное устройство это конечно хорошо. Можно и реализовать.

Но как при этом файловая система поверх блочного устройства узнает, что призошла ошибка на диске?

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

>Сивольное устройство это конечно хорошо. Можно и реализовать.

:-D

Всё учтено могучим ураганом. Ты не реализовываешь его _сам_б ты просто конфигурируешь character raw device для своего существующего block device, и читаешь пишешь через raw device - и система прозрачно для тебя делает синхронные запись/чтение.

> Но как при этом файловая система поверх блочного устройства узнает, что призошла ошибка на диске?

raw device - это, AFAIK, устаревший интерфейс, и применим только к дискам без ФС (но для твоего теста такие и нужны).

Если же тебе нужен direct io на из файла на ФС - только O_DIRECT.

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве


RHEL4:

--- man open ---
O_DIRECT
Try to minimize cache effects of the I/O to and from this file. In general this
will degrade performance, but it is useful in special situations, such as when
applications do their own caching. File I/O is done directly to/from user space
buffers. The I/O is synchronous, i.e., at the completion of the read(2) or
write(2) system call, data is guaranteed to have been transferred. Under Linux 2.4
transfer sizes, and the alignment of user buffer and file offset must all be multi-
ples of the logical block size of the file system. Under Linux 2.6 alignment to
512-byte boundaries suffices.
A semantically similar interface for block devices is described in raw(8).
--- man open ---

// wbr

klalafuda ★☆☆ ()

Re: Ошибка обработки запроса в блочном устройстве

Целевая машина

ARM AT91RM9200 Kernel 2.4.27-vrs1-ATMEL GCC 2.95.3 ARM LINUX uClibC 0.9.27

Свойя плата, свой жесткий диск, свой модуль блочного устройства для него, поверх файловая система Ext2

Диск может быть извлечен на ходу (нежелательно но возможно).

Но нужно и писать в него напрямую минуя ФС.

Как определить в программе (write) что блочное устройство завершилось с ошибкой? Как драйвер ФС определяет что операция чтения записи завершилась с ошибкой?

Ядро явно "видит", что операция завершилась с ошибкой.

Разработка на ASP Linux 7.0

Флага O_DIRECT нет и не компилирует соответсвенно.

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

> Разработка на ASP Linux 7.0

Я в местных дистрибутивах не разбираюсь, но это явно что-то древнее.

> Флага O_DIRECT нет и не компилирует соответсвенно.

Ну, по=быструхе, #define O_DIRECT 040000

Или попробуй man 8 raw

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

При #define O_DIRECT 0x40000 ничего не меняется

ASP тут вовсе не причем, ну может быть man старый.

Все ведь работает на ARM и.....

А может мне uClibC такую свинью подложила????

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

> При #define O_DIRECT 0x40000 ничего не меняется

<грубая матерная ругань/> Не 0x40000, а 040000 :-P

> А может мне uClibC такую свинью подложила????

Всё может быть...

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Ошибочка вышла в дефайнах

fcntl.h

#ifdef __USE_GNU # define O_DIRECTORY 040000 /* Must be a directory. */ # define O_NOFOLLOW 0100000 /* Do not follow links. */ # define O_DIRECT 0200000 /* Direct disk access. */ # define O_STREAMING 04000000/* streaming access */ #endif

Хотя и с данными определениями все не так.

Я немогу определить, что запись не состоялась.

mke2fs как нормальное приложение не может этого определить. Продолжает форматировать хотя диска и в помине нет.

Запись в файл (тоесть фаловая система) тоже не может определить что все плохо, хотя ядро и говорит, что завершает ввод вывод с ошибкой

end_request: I/O error, dev f5:01 (at91_hdd), sector 268336

Значит всеже в драйвере что то не так. А как надо?

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

> Ошибочка вышла в дефайнах

> fcntl.h

> #ifdef __USE_GNU # define O_DIRECTORY 040000 /* Must be a directory. */ # define O_NOFOLLOW 0100000 /* Do not follow links. */ # define O_DIRECT 0200000 /* Direct disk access. */ # define O_STREAMING 04000000/* streaming access */ #endif

Я не подумал, что они на ARM могут быть другие. У меня:

bits/fcntl.h:# define O_DIRECT 040000 /* Direct disk access. */

bits/fcntl.h:# define O_DIRECTORY 0200000 /* Must be a directory. */

Насчет end_request(0) - судя по исходникам, этого недостаточно, надо делать buffer_IO_error на ошибочном буфере. Хотя я не специалист по блочным драйверам :/

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Если добавить при ошибке записи следующий код:

buffer_IO_error( CURRENT->bh );

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

теперь это выглядит так: end_request: I/O error, dev f5:00 (at91_hdd), sector 50944 VFS: brelse: Trying to free free buffer

Но приложение все равно ни чего не знает об ошибке ввода/вывода.

p_igorek ()

Re: Ошибка обработки запроса в блочном устройстве

> теперь это выглядит так: end_request: I/O error, dev f5:00 (at91_hdd), sector 50944 VFS: brelse: Trying to free free buffer

Прикольно. Должен же быть какой-то способ... А ты делаешь buffer_IO_error до или после end_request(0) ?

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

Да, и еще - я бы на твоем месте пока работал только с _чтением_ (сразу после перезагрузки драйвера) - думаю, там эффекты кэша не проявляются. А когда научишься передавать ошибку в read, можно будет попробовать делать то же write.

tailgunner ★★★★★ ()

Re: Ошибка обработки запроса в блочном устройстве

До.

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

Да, еще добавил такой код: CURRENT->errors++; buffer_IO_error(CURRENT->bh);

p_igorek ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.