Ошибка актуальна для сборки собвственного модуля ядра 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,
};