«Персонаж за один раз» является неправильным (как и идея, что символьные устройства обязательно не поддерживают поиск и рассказ). Фактически устройства «блок за раз» (то есть строго ориентированные на запись, такие как стример *) должны быть символьными устройствами. Такова идея о том, что символьное устройство обязательно должно быть недоступным - драйверы символьного устройства определяют полную file_operations
структуру, которая может свободно определять или нет в зависимости от того, поддерживает ли устройство операцию. Символьные устройства, которые большинство людей считают примерами, - это null, urandom, TTY-устройства, звуковая карта, мышь и т. Д., Которые невозможно найти из-за специфики этих устройств, но / dev / vcs, / dev / fb0 и / dev / kmem также являются символьными устройствами, и все они доступны для поиска.
Как я уже упоминал, драйвер символьного устройства определяет структуру file_operations, в которой есть указатели на функции для всех операций, которые кто-то может захотеть вызвать над файлом - поиск, чтение, запись, ioctl и т. Д., И каждый из них вызывается один раз, когда соответствующий системный вызов выполняется с открытым файлом этого устройства. И поэтому чтение и запись могут делать со своими аргументами все, что захотят - он может отказаться принимать слишком большую запись или писать только то, что подходит; он может читать только данные, соответствующие одной записи, а не все запрошенное количество байтов.
Итак, что же такое блочное устройство? По сути, блочные устройства - это дисководы. Никакое другое устройство (кроме виртуальных дисков, таких как ramdisk и loopback) не является блочным устройством. Они интегрированы в систему запросов ввода-вывода, уровень файловой системы, систему буферов / кэш-памяти и систему виртуальной памяти так, как это делают символьные устройства, даже когда вы обращаетесь, например, к / dev / sda из пользовательского процесса. , Даже «необработанные устройства», упомянутые на странице в качестве исключения, являются символьными устройствами .
* В некоторых системах UNIX реализован так называемый «режим с фиксированными блоками», который позволяет ядру группировать и разбивать запросы ввода-вывода так, чтобы они соответствовали настроенным границам блоков более или менее таким же образом, как это делается для дисковых накопителей, - как блок. устройство. Символьное устройство необходимо для «режима переменных блоков», который сохраняет границы блоков из пользовательской программы, так как один вызов write (2) записывает один блок, а один вызов read (2) возвращает один блок. Поскольку переключение режимов теперь реализовано как ioctl, а не как отдельный файл устройства, используется символьное устройство. Ленточные накопители с переменными записями в большинстве случаев не доступны для поиска, поскольку поиск включает в себя подсчет количества записей, а не байтов, а собственная операция поиска реализована в виде ioctl.