Amumu
Amumu

Reputation: 18552

How Linux knows which ioctl function to call?

Here is the ioctl call in user space:

int ioctl(int fd, int cmd, ...);

As far as I know, when we want to perfrom IO operations, we define our own ioctl function with a set of requests (commands), assign our ioctl to a file_operations structure like this:

struct file_operations fops = {
 .read = device_read,
 .write = device_write,
 .ioctl = device_ioctl, // device_ioctl is our function
 .open = device_open,
 .release = device_release,
};

And the device_ioctl function is defined differently compared to the user space interface:

static long device_ioctl(struct file *f, unsigned int cmd, unsigned long arg)

I think based on the file descriptor, the kernel can get the appropriate file structure and calls the device's ioctl.

This is just a guess because I cannot find it the generic function definition where the kernel selects appropriate ioctl function based on the file descriptor fd passed into the generic ioctl interface? There are only 3 ioctl definitions I can find, but apparently those are just the devices' definitions, not the kernel: ioctl

Upvotes: 9

Views: 12104

Answers (4)

Lev Iserovich
Lev Iserovich

Reputation: 134

Look in the Linux source code, fs/ioctl.c (http://lxr.free-electrons.com/source/fs/ioctl.c)
There you will see the syscall for ioctl:

SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)

This in turns calls do_vfs_ioctl(), which calls vfs_ioctl() which then calls the unlocked_ioctl function defined for that filesystem in the file_operations structure.
This will be your device_ioctl function that you registered.

Upvotes: 8

ouah
ouah

Reputation: 145829

When you call ioctl you pass a file descriptor. You got the file descriptor from opening a device file like /dev/tty0:

$ ls -l /dev/tty0
crw--w---- 1 root tty 4, 0 Mar  6 10:47 /dev/tty0
$

The number 4 here is the device major number which is encoded into the driver module the kernel has to use.

Upvotes: 1

sergico
sergico

Reputation: 2621

The kernel will know which ioctl function to call because of the file descriptor. To be able to call an ioctl() from userspace you will have to open a file to get the fd, tipically a /dev/[some_device] whose driver will implement the file_operations struct, as you pointed out.

Upvotes: 1

Shahbaz
Shahbaz

Reputation: 47493

device_ioctl is a function pointer. The kernel simply takes fd as an index to an array of struct file_operations and calls the .ioctl of the corresponding element. The kernel never needs to knows what the function itself is which device it refers to.

This is the basis of "Everything is a file", which is Unix's moto.

Upvotes: 3

Related Questions