получение флагов устройств по имени устройства

#c #linux #kernel #block-device

#c #linux #ядро #блок-устройство

Вопрос:

надеюсь, вы сможете мне помочь: я пытаюсь определить, является ли устройство съемным или нет, все, что у меня есть, это имя устройства (/dev / sdc). На самом деле, мне нужно определить, когда файл находится на съемном носителе или на локальном диске, по полному пути к этому файлу.

Я попытался выполнить поиск в current-> fs-> pwd, и все, что я смог найти, это набор флагов здесь: * current-> fs->pwd.mnt-> mnt_sb-> s_bdev-> bd_disk-> flags* где GENHD_FL_REMOVABLE установлен для съемных устройств

Но я всегда получаю одни и те же установленные флаги (насколько я понимаю, s_bdev всегда указывает на одно и то же устройство (/dev/sda)).

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

Есть ли возможный способ получить структуру block_device по имени устройства? (например, структура «file» может быть получена путем вызова fd = open(«name») fl = fged(fd), где fl указывает на структуру «file»)

Ответ №1:

Вы можете перебирать блочные устройства, используя class_dev_iter_init и class_dev_iter_next . Смотрите код block/genhd.c blk_lookup_devt для использования.

После того, как у вас есть устройство, вы можете использовать dev_to_disk для получения struct gendisk * , в котором вы можете проверить сменный флаг.

Комментарии:

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

2. @Makc: я думаю, вы можете использовать vfs_stat , это даст вам a struct kstat , в котором вы сможете сравнить dev_t его с блочным устройством.

3.Я столкнулся с некоторыми проблемами class_dev_iter_init при использовании class_dev_iter_next и. (система останавливается class_dev_iter_next и disk_type не определена, однако его параметр не является необходимым.) Итак, я нашел get_gendisk() функцию, которая принимает dev_t и возвращает gendisk ссылку, это то, что мне нужно, но как я могу использовать эту функцию? Он определен в /include/linux/genhd.h, но включение этого заголовка приводит к компиляции модуля с предупреждением, а сбой insmod завершается с неизвестным символом в модуле. Итак, можно ли использовать эту функцию в модуле kern?

4. @Makc: похоже, что get_gendisk() это должно быть экспортировано в последние ядра, ранее этого не было. Если возможна перекомпиляция ядра, либо обновите свое ядро, либо добавьте a EXPORT_SYMBOL в genhd.c

5. @Makc: Как я уже сказал, это было изменено в более позднем ядре (хотя у меня возникли проблемы с точным определением точной версии). Возможно, я нашел альтернативный путь, хотя это немного некрасиво, как в vfs_fstatat get a path via user_path_at , затем пройдите либо mnt.mnt_sb или dentry.d_sb , чтобы добраться до вашего block_device и gendisk

Ответ №2:

Прочитайте /sys/block/dev-name/removable, поскольку он должен содержать 1, если устройство является съемным, или 0, если нет. (dev-name = имя устройства: sda, hda, fd0, …)

Комментарии:

1. я знаю об этом, но в любом случае это не работает в старых версиях Linux, спасибо.

2. Кроме того, я не знаю никаких безопасных способов чтения файлов из модулей ядра. (Я пробовал sys_read() и vfs_read() — это вызывает «Oops» :)) Может быть, вы знаете какие-либо способы доступа к sysfs из модуля ядра?