file_operations structure changes

Working on a device driver for Linux 3.0.4. In class we are modifying some existing code:
static struct file_operations simple_fops = {
    .read =       simple_read,
    .write =      simple_write,
    .ioctl =      NULL,
    .open =       simple_open,
    .release =    simple_release,
};
However, this doesn't compile with the latest kernel source. The error is:
error: unknown field ‘ioctl’ specified in initializer
The new structure, as defined in <source>/include/linux/fs.h is:
struct file_operations {
        struct module *owner;
        loff_t (*llseek) (struct file *, loff_t, int);
        ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
        ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
        ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
        ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
        int (*readdir) (struct file *, void *, filldir_t);
        unsigned int (*poll) (struct file *, struct poll_table_struct *);
        long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
        long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
        int (*mmap) (struct file *, struct vm_area_struct *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *, fl_owner_t id);
        int (*release) (struct inode *, struct file *);
        int (*fsync) (struct file *, int datasync);
        int (*aio_fsync) (struct kiocb *, int datasync);
        int (*fasync) (int, struct file *, int);
        int (*lock) (struct file *, int, struct file_lock *);
        ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
        unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
        int (*check_flags)(int);
        int (*flock) (struct file *, int, struct file_lock *);
        ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
        ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
        int (*setlease)(struct file *, long, struct file_lock **);
        long (*fallocate)(struct file *file, int mode, loff_t offset,
                          loff_t len);
};
It appears that *ioctl has been replaced with *unlocked_ioctl and *compat_ioctl. Why? Well, according to this post, the old structure was a security risk, and was deprecated. With the new 3.0 kernel, the call must now be completely missing from the headers. The correct thing to do is to use the unlocked_ioctl element instead of ioctl.

Comments

Popular posts from this blog

KnockoutJS, WebAPI, and TypeScript

The most efficient algorithm to scan a bitmap