Сообщение о ошибке при сборке модуля ядра LinuxОшибка актуальна для сборки собвственного модуля ядра Linux, или же пересборки старого чужого модуля.
error: ‘struct file_operations’ has no member named ‘ioctl’

означает, что в структуре file_operations было поле ioctl, a теперь его нет.

Во многих примерах используется старый вариант, который при сборке выдаёт ошибку.

Немного истории:

Раньше, вызов ioctl() для устройств приводил к глобальной блокировке всего ядра (Big Kernel Lock [BKL]). Особенно это замедляло работу многопроцессорных систем, ведь при вызове ioctl() блокировались все процессы.
Начиная с версии ядра 2.6.11 появилась альтернативная функция unlocked_ioctl(), которая выполняла действия без глобальной блокировки ядра. Начался переходный период, когда можно было встретить и старые и новые варианты.

Начиная с версии 2.6.36 переходный период кончился, и функция ioctl() была удалена. Вместо неё теперь функции unlocked_ioctl() и compat_ioctl().

Разница между unlocked_ioctl() и compat_ioctl()

unlocked_ioctl() вызывает функцию ядра без глобальной блокировки ядра

compat_ioctl() сделана для обращений 32-битных приложений к 64-битному ядру.

Резюмируя: ioctl() надо заменять на unlocked_ioctl() (если, конечно у вас не 32-битное приложение под 64-битным ядром)

Как исправить ошибку компиляции

Обратите внимание, что меняется не только структура, но и сигнатура функции.

Старый вариант

int device_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
// code
}

static struct file_operations FileOps =
{
    .owner      = THIS_MODULE,
    .read         = device_read,
    .write         = device_write,
    .open       = device_open,
    .ioctl         = device_ioctl,
    .release    = device_close,
};

Новый вариант

long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param)
{
// code
}

static struct file_operations FileOps =
{
    .owner          = THIS_MODULE,
    .read             = device_read,
    .write             = device_write,
    .open           = device_open,
    .unlocked_ioctl = device_ioctl,
    .release        = device_close,
};

Добавить комментарий


Поиск