最近在做Linux驱动方面的东西。发现涉及到.ioctl部分存在着问题。我的电脑是2.6.32.127的内核,这个用起来没有问题。而我把它放到2.6.36的内核中就有了问题,报错为.ioctl不存在。我特意查了源码中的相关定义,发现2.6.36中少了
int (*ioctl) (struct inode *, struct file *, unsigned int,unsigned long);
这一行,而仅剩下
long (*unlocked_ioctl) (struct file *,unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsignedint, unsigned long);
这两行关于ioctl操作的函数
在这种情况下,我们只能用long (*unlocked_ioctl) (struct file *, unsigned int,unsigned long);来替换掉之前的int (*ioctl) (struct inode *, struct file *,unsigned int, unsigned long);但是还是存在着问题,即他们的返回值是不同的。
unlocked_ioctl: long ioctl(struct file *filp, unsigned int cmd,unsigned long args);
old ioctl: int ioctl(struct inode *inode, struct file *filp,unsigned int cmd, unsigned long args);
同时unlocked_ioctl去除了"inode" 函数指针(which can be obtained anywaysthrough the filp),
另外The 'inode' value that was passed to 'ioctl' function isavailable for use with the'unlocked_ioctl' function by way offilp->d_entry->d_inode:
long(*unlocked_ioctl) (struct file *filp, unsigned intcmd, unsigned long arg);
...
struct inode*inode = filp->d_entry->d_inode;
There is a nice explanation of this at http://lwn.net/Articles/119652/
其在几个版本中的具体定义如下:
2.6.36的fs.h中file_operations 定义
#define HAVE_COMPAT_IOCTL 1
#define HAVE_UNLOCKED_IOCTL 1
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 structiovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, conststruct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *,filldir_t);
unsigned int (*poll) (struct file *, structpoll_table_struct *);
long (*unlocked_ioctl) (struct file *, unsignedint, unsigned long);
long (*compat_ioctl) (struct file *, unsignedint, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct*);
int (*open) (struct inode *, struct file*);
int (*flush) (struct file *, fl_owner_tid);
int (*release) (struct inode *, struct file*);
int (*fsync) (struct file *, int datasync);
int (*aio_fsync) (struct kiocb *, intdatasync);
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, structfile_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, structfile_lock **);
};
2.6.34版本的fs.h这里如下
1480 //
1481 // NOTE:
1482 // read, write, poll, fsync, readv, writev,unlocked_ioctl and compat_ioctl
1483 // can be called without the big kernel lockheld in all filesystems.
1484 //
1485 struct file_operations{
1486 struct module *owner;
1487 loff_t (*llseek) (struct file *, loff_t,int);
1488 ssize_t (*read) (struct file *, char __user *, size_t, loff_t*);
1489 ssize_t (*write) (struct file *, const char __user *, size_t,loff_t *);
1490 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsignedlong, loff_t);
1491 ssize_t (*aio_write) (struct kiocb *, const struct iovec *,unsigned long, loff_t);
1492 int (*readdir) (struct file *, void *,filldir_t);
1493 unsigned int (*poll) (struct file *, struct poll_table_struct*);
1494 int (*ioctl) (struct inode *, struct file *, unsigned int, unsignedlong);
1495 long (*unlocked_ioctl) (struct file *, unsigned int, unsignedlong);
1496 long (*compat_ioctl) (struct file *, unsigned int, unsignedlong);
1497 int (*mmap) (struct file *, struct vm_area_struct*);
1498 int (*open) (struct inode *, struct file*);
1499 int (*flush) (struct file *, fl_owner_tid);
1500 int (*release) (struct inode *, struct file*);
1501 int (*fsync) (struct file *, struct dentry *, intdatasync);
1502 int (*aio_fsync) (struct kiocb *, intdatasync);
1503 int (*fasync) (int, struct file *,int);
1504 int (*lock) (struct file *, int, struct file_lock*);
1505 ssize_t (*sendpage) (struct file *, struct page *, int, size_t,loff_t *, int);
1506 unsigned long (*get_unmapped_area)(struct file *, unsigned long,unsigned long, unsigned long, unsignedlong);
1507 int (*check_flags)(int);
1508 int (*flock) (struct file *, int, struct file_lock*);
1509 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *,loff_t *, size_t, unsignedint);
1510 ssize_t (*splice_read)(struct file *, loff_t *, structpipe_inode_info *, size_t, unsignedint);
1511 int (*setlease)(struct file *, long, struct file_lock**);
1512 };
2.6.32.2的fs.h中file_operations 定义
//These macros are for out of kernel modules to test that
// the kernel supports the unlocked_ioctl andcompat_ioctl
// fields in struct file_operations.
#define HAVE_COMPAT_IOCTL 1
#define HAVE_UNLOCKED_IOCTL 1
//
// NOTE:
// read, write, poll, fsync, readv, writev,unlocked_ioctl and compat_ioctl
// can be called without the big kernel lock heldin all filesystems.
//
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 structiovec *, unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *, conststruct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *,filldir_t);
unsigned int (*poll) (struct file *, structpoll_table_struct *);
int (*ioctl) (struct inode *, struct file *,unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsignedint, unsigned long);
long (*compat_ioctl) (struct file *, unsignedint, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct*);
int (*open) (struct inode *, struct file*);
int (*flush) (struct file *, fl_owner_tid);
int (*release) (struct inode *, struct file*);
int (*fsync) (struct file *, struct dentry *, intdatasync);
int (*aio_fsync) (struct kiocb *, intdatasync);
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, structfile_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, structfile_lock **);
};