Question

I am trying to call an ioctl function in my toy file system module. I would simply like to have this ioctl set a variable that is passed in by the caller. So far I have set up the ioctl infrastructure that has allowed me to make ioctl calls. I have this function in my module to handle ioctl.

int ospfs_ioctl(struct inode *inode, struct file *filp,
      unsigned int cmd, unsigned long arg)
{
    if(cmd == OSPFSIOCRASH)
    {
        eprintk("crash: %ld\n", arg);
        return 0;
    }
    else
        return -ENOTTY;
}

And my test function looks like this.

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#define OSPFSIOCRASH 42

int main()
{
    int fd = open("/tmp/cs111/lab3-thief/test/hello.txt", O_RDWR);
    printf("ioctl call: %d\n", ioctl(fd, OSPFSIOCRASH, 100));
    close(fd);
}

I expect the output to be

crash: 100
ioctl call: 0

but the output is actually

crash: 0
ioctl call: 0

I bet I'm doing something simple wrong. Could someone please help and point out what the issue is? Thank you kindly.

Was it helpful?

Solution

This might not be the solution which solves your problem, but based on the limited information from your question and the comments, this what I could gather.

Based on the question and the comments, it looks like you have defined a struct file_operations structure in this fashion:

struct file_operations fops = { .ioctl=ospfs_ioctl };

And the signature of your ospfs_ioctl suggests that you're using the older ioctl.

With the recent kernels (at least after 2.6.35+ or something), it is recommended to use .unlocked_ioctl instead of .ioctl.

struct file_operations fops = { .unlocked_ioctl=ospfs_ioctl };

And the definition of the ospfs_ioctl function would change to:

long ospfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)

The differences between unlocked_ioctl and the regular ioctl can be found here. In short it does not take the dreaded BKL before invoking the ioctl.

And also as per Chris Dodd's suggestion, you should double check how you're defining your OSPFIOCRASH. The recommended way is to make use of the _IO(magic, some_num_for_ioctl)

OTHER TIPS

As per Chris Dodd's suggestion I changed #define OSPFIOCRASH 42 to #define OSPFSIOCRASH _IO(magic, 0) and have since gotten the desired behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top