Why is there an incompatible pointer type warning?

10,662

Solution 1

The return type of your read_proc function (which throws the warning) does not match the the function that compiles cleanly.

static ssize_t dev_read(struct file *pfil, char __user *pBuf, size_t len, loff_t *p_off)

vs.

static int read_proc(struct file *pfil, char __user *pBuf, size_t len, loff_t *p_off)

ssize_t and int may be different sizes. Your function's return type should be ssize_t.

Solution 2

While working with file operations just follow rules according to this structure

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);
    ssize_t (*read_iter) (struct kiocb *, struct iov_iter *);
    ssize_t (*write_iter) (struct kiocb *, struct iov_iter *);
    int (*iterate) (struct file *, struct dir_context *);
    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 *);
    int (*release) (struct inode *, struct file *);
    int (*fsync) (struct file *, loff_t, loff_t, 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 *, size_t, unsigned int);
    ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
    int (*setlease)(struct file *, long arg, struct file_lock **);
    long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len);
    int (*show_fdinfo)(struct seq_file *m, struct file *f); };

You can find this structure in Kernel Documentation Documentation/filesystems/vfs.txt or you can find it using tag vim -t file_operations from Kernel Source or you can look at header file /include/linux/fs.h.

Just Your mistake is return type you used static int instead of using ssize_t.

Solution 3

The function pointer expects a function with return type of ssize_t but you've given it one of int

You need a ssize_t there, not an int.

Share:
10,662

Related videos on Youtube

Tansir1
Author by

Tansir1

Updated on July 18, 2022

Comments

  • Tansir1
    Tansir1 over 1 year

    I'm writing a Linux device driver using kernel 3.13.0 and I'm confused as to why I'm getting this warning.

    warning: initialization from incompatible pointer type [enabled by default]
         .read = read_proc,
         ^
    warning: (near initialization for ‘proc_fops.read’) [enabled by default]
    

    As far as I can tell my file_operations setup for the proc functions are identical to the device functions. I can read/write to /dev/MyDevice with no issue and there are no warnings. The proc write function does not throw a warning, only the read. What did I do wrong?

    /*****************************************************************************/
    //DEVICE OPERATIONS
    /*****************************************************************************/ 
    static ssize_t dev_read(struct file *pfil, char __user *pBuf, size_t
      len, loff_t *p_off)
    {
        //Not relevant to this question
    }
    
    static ssize_t dev_write(struct file *pfil, const char __user *pBuf,
                             size_t len, loff_t *p_off)
    {
        //Not relevant to this question
    }
    
    static struct file_operations dev_fops =
    { //None of these cause a warning but the code is identical the proc code below
        .owner = THIS_MODULE,
        .read = dev_read,
        .write = dev_write
    };
    
    /*****************************************************************************/
    //PROCESS OPERATIONS
    /*****************************************************************************/
    static int read_proc(struct file *pfil, char __user *pBuf, size_t
                  len, loff_t *p_off)
    {
        //Not relevant to this question
    }
    
    static ssize_t write_proc(struct file *pfil, const char __user *pBuf,
                             size_t len, loff_t *p_off)
    {
        //Not relevant to this question
    }
    
    struct file_operations proc_fops = 
    {
        .owner = THIS_MODULE,
        .write = write_proc,
        .read = read_proc, //This line causes the warning.
    };
    

    EDIT: So the answer is that I'm an idiot for not seeing the "int" versus "ssize_t". Thank you everyone! Both Codenheim and Andrew Medico had the correct answer at roughly the same time but I chose Medico's because it's more pedantic and obvious for future visitors.

  • nobody
    nobody over 9 years
    It's not that, either. The function that doesn't warn returns a ssize_t.
  • codenheim
    codenheim over 9 years
    @AndrewMedico - That was a typo. I first read it as size_t, but the point is still the same.