LINUX.ORG.RU

[kernel][c] Определить устройство, на котором находится файл

 ,


0

1

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

Задача такая: есть обработчик sys_open (тот который в sys_call_table)

asmlinkage long sys_open(const char __user *filename,
                         int flags, int mode);

Нужно как-то определить на каком устройстве находится файл к которому происходит обращение, а именно является оно съемным (usb-flash, usb-hdd) или же несъемным. Уже несколько дней пытаюсь рыть внутри

current->fs->pwd

Единственная полезная вещь которую смог найти это

current->fs->pwd.mnt->mnt_sb->s_bdev->bd_disk->flags

в котором установлен GENHD_FL_REMOVABLE на этот же int flags можно выйти и через

...pwd->mnt_mountpoint->mnt...

и еще несколькими путями, но в первом случае получаем всегда одинаковый набор флагов, более того, одно и то же устройство, то, которое смонтировано в корень ФС (sda1 в моем случае вместо sdd, являющегося флешкой).

Во втором же случае указатель на block_device (s_bdev) внутри super_block (mnt_sb) вообще может быть null (выяснилось после нескольких падений при попытке проверки флагов).

В итоге я не смог вытащить не только тип устройства, но и вообще само устройство.

Сейчас другим способом (костыль тот еще) получаю только имя устройства, при каждом изменении mtab, вытаскиваю из него список устройств с точкой монтирования. Но и имея имя устройства вида /dev/sdd1, не могу определить является ли оно съемным или нет.

Помогите пожалуйста советом, а если бы кто подкинул алгоритм вида

1. Получаем имя устройства из current->fs->...
2. Хэндл устройства через devfs_find_handle()
3. Флаги устройства через devfs_get_flags()
4. Проверяем флаг DEVFS_FL_REMOVABLE

То я... скажу ОГРОМНОЕ человеческое спасибо.


Не нашел как редактировать сообщения, пишу новым.

флаги лежат в
block_device -> gendisk (поле bd_disk) -> flags

Имя вида /dev/sda однозначно определяет устройство, то есть соответствующую ему структуру block_device.

Но как её можно получить, ведь вызвав open(«/dev/sda») мы получим fd. Из fd можно получить структуру file, если вызвать fget(fd), есть ли подобная функция для получения структуры block_device из дескриптора fd ?

AnMakc
() автор топика
Ответ на: комментарий от ttnl

Вообщем то, да))) Заодно прокачивая знания линукса.

AnMakc
() автор топика

> определить на каком устройстве находится файл к которому происходит обращение, а именно является оно съемным (usb-flash, usb-hdd) или же несъемным.

Для Linux любое USB устройство, на котором не расположен / или swap, является съёмным.

Всегда ваш, К.О.

LamerOk ★★★★★
()
Ответ на: комментарий от LamerOk

Шутку оценил, по теме есть что сказать ?

Если интересно мнение линукса, загляните в /sys/block/DEV/removable где DEV - имя вашей флешки и вашего hdd.

А потом не забудте поведать нам об увиденном.

AnMakc
() автор топика
Ответ на: комментарий от AnMakc

по теме есть что сказать ?

Норкоман? Мой ответ был ровно по теме. По _твоей_ теме.

Если интересно мнение линукса, загляните в /sys/block/DEV/removable

А кто тебе сказал, что там «мнение линукса»? Сам придумал?

* Removable: Media can be removed but device node remains.
* Hotpluggable: Media cannot be removed without making the device node
disappear.

Removable devices in Linux are things like floppys and cdroms. Most
other things are hotpluggable.

© Pierre Ossman

А потом не забудте поведать нам об увиденном.

Обломись, у меня венда.

:3

LamerOk ★★★★★
()
Ответ на: комментарий от Manhunt

Смотрел, пробовал и sys_statfs() и vfs_stat(), во втором случае получаем структуру kstat (кликабельно),
из нее идентифицирует устройство только dev_t dev;. Сейчас пытаюсь разобраться, как из этого можно получить структуру device, после можно будет вызвать dev_to_disk() и получить block_device.
Хотел воспользоваться
class_dev_iter_init()
class_dev_iter_next()
class_dev_iter_exit()
,
но вызов class_dev_iter_next() вешает систему по непонятным мне причинам).

У кого есть идеи как получить device по известному dev_t ?

AnMakc
() автор топика

Итак, решение найдено, причем на такое простое я даже не рассчитывал - достаточно брать структуру path не из current->, а вызвать
user_path_at() (линк)
и уже в полученном path добираться до
path.mnt->mnt_sb->s_bdev->bd_disk->flags.

Да, надо внимательно следить за тем что возвращается, например при обращениях к procfs никакого s_bdev мы не получим, хотя user_path_at() отработает нормально. В таком случае попытка обратиться к чему-либо внутри s_bdev, то будет «Oops...».

Вообщем, всем спасибо)

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