Два разных прототипа функций для модуля ядра Linux ioctl

Я предполагаю, что вы имели в виду десятичные числа. В этом случае вы можете использоватьawk:

awk '{ if ($2 == ($2+0)) print $0 }' my_file

Это пытается добавить 0во второй столбец, чтобы проверить, является ли он числовым. (приводит к тому же значению ), и только затем печатает всю строку, т.е. $0.

Будет напечатано только первые три строки из предоставленных вами данных.


Спасибо @msp9011 за еще более короткое эквивалентное решение:

awk '$2 == ($2+0)' my_file
0
26.11.2021, 15:25
1 ответ
  1. Are both the above prototypes suitable in this case? If yes, why? If no, how to choose the right one?

Они оба не подходят. В настоящее время в ядре доступна только версии 2 , так что эту версию следует использовать.

  1. What header/source file(s) contain these prototypes? In other words: what is the official reference file for these prototypes?

Они находятся вinclude/linux/fs.h(это путь относительно корневого каталога исходного кода ядра ), внутри определения struct file_operations:

long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

То есть :элемент unlocked_ioctlдолжен быть указателем на функцию

long ioctl(struct file *f, unsigned int cmd, unsigned long arg);

, что в точности соответствует версии 2 . Если функция my_ioctl()определена внутри модуля ядра с использованием версии 1 , будет сгенерирована ошибка компилятора :

.
error: initialization of ‘long int (*)(struct file *, unsigned int,  long unsigned int)’ from incompatible pointer type ‘long int (*)(struct inode *, struct file *, unsigned int,  long unsigned int)’ [-Werror=incompatible-pointer-types]
 .unlocked_ioctl = my_ioctl
                    ^~~~~~~~

Некоторые дополнительные комментарии

Версия 1 была единственной до ядра 2.6.10 , где struct file_operationsимел только

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

Эта ioctlфункция, однако, создала большую блокировку ядра (BKL ):, она заблокировала все ядро ​​во время своей работы. Это нежелательно. Так, из 2.6.11 ,

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);

Добавлен новый способ использования ioctls, который не блокирует ядро. Здесь старый ioctlс блокировкой ядра и новый unlocked_ioctlсосуществуют. Из 2.6.36 старый ioctlудален. Все драйверы должны быть соответствующим образом обновлены, чтобы использовать только unlocked_ioctl.См. этот ответ для получения дополнительной информации.

В недавнем выпуске ядра (5.15.2 )кажется, что по-прежнему мало файлов, использующих старыйioctl:

linux-5.15.2$ grep -r "ioctl(struct inode" *
Documentation/cdrom/cdrom-standard.rst: int cdrom_ioctl(struct inode *ip, struct file *fp,
drivers/staging/vme/devices/vme_user.c:static int vme_user_ioctl(struct inode *inode, struct file *file,
drivers/scsi/dpti.h:static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg);
drivers/scsi/dpt_i2o.c:static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
fs/fuse/ioctl.c:static int fuse_priv_ioctl(struct inode *inode, struct fuse_file *ff,
fs/btrfs/ioctl.c:static noinline int search_ioctl(struct inode *inode,
fs/ocfs2/refcounttree.h:int ocfs2_reflink_ioctl(struct inode *inode,
fs/ocfs2/refcounttree.c:int ocfs2_reflink_ioctl(struct inode *inode,
net/sunrpc/cache.c:static int cache_ioctl(struct inode *ino, struct file *filp,
Однако

vme_user.c, dpt_i2o.cи cache.cимеют:

static const struct file_operations adpt_fops = {
       .unlocked_ioctl = adpt_unlocked_ioctl,

, а затем

static long adpt_unlocked_ioctl(struct file *file, uint cmd, ulong arg)
{
        struct inode *inode;
        long ret;

        inode = file_inode(file);

        mutex_lock(&adpt_mutex);
        ret = adpt_ioctl(inode, file, cmd, arg);

Таким образом, они используют старую версию, внутри новой (получая inodeиз доступных данных, как предложил Энди Далтон в комментариях ). Что касается файлов внутри fs:, похоже, они не используют struct file_operations; кроме того, их функции не являются ioctl, определенными в

.
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

, потому что они принимают разные параметры(fuse_priv_ioctlв fs/fuse/ioctl.c, search_ioctlв fs/btrfs/ioctl.c, ocfs2_reflink_ioctlв fs/ocfs2/refcounttree.c), поэтому они, возможно, используются только внутри драйвера.

Таким образом, предположение в связанном вопросе о том, что для функции ioctlвнутри модуля ядра Linux доступны две версии, неверно. Должна использоваться толькоunlocked_ioctl(версии 2 ).

1
27.11.2021, 11:04

Теги

Похожие вопросы