diff options
-rw-r--r-- | drivers/media/video/v4l2-dev.c | 52 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap.h | 8 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_ioctl.c | 52 | ||||
-rw-r--r-- | drivers/staging/easycap/easycap_main.c | 38 | ||||
-rw-r--r-- | fs/autofs/root.c | 67 | ||||
-rw-r--r-- | fs/autofs4/root.c | 49 | ||||
-rw-r--r-- | fs/compat_ioctl.c | 36 | ||||
-rw-r--r-- | fs/ncpfs/ioctl.c | 1 | ||||
-rw-r--r-- | include/linux/auto_fs.h | 1 |
9 files changed, 180 insertions, 124 deletions
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 9e89bf61779..249af6a1d56 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -25,6 +25,7 @@ #include <linux/init.h> #include <linux/kmod.h> #include <linux/slab.h> +#include <linux/smp_lock.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -215,28 +216,24 @@ static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) return vdev->fops->poll(filp, poll); } -static int v4l2_ioctl(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct video_device *vdev = video_devdata(filp); + int ret; - if (!vdev->fops->ioctl) - return -ENOTTY; /* Allow ioctl to continue even if the device was unregistered. Things like dequeueing buffers might still be useful. */ - return vdev->fops->ioctl(filp, cmd, arg); -} - -static long v4l2_unlocked_ioctl(struct file *filp, - unsigned int cmd, unsigned long arg) -{ - struct video_device *vdev = video_devdata(filp); + if (vdev->fops->unlocked_ioctl) { + ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); + } else if (vdev->fops->ioctl) { + /* TODO: convert all drivers to unlocked_ioctl */ + lock_kernel(); + ret = vdev->fops->ioctl(filp, cmd, arg); + unlock_kernel(); + } else + ret = -ENOTTY; - if (!vdev->fops->unlocked_ioctl) - return -ENOTTY; - /* Allow ioctl to continue even if the device was unregistered. - Things like dequeueing buffers might still be useful. */ - return vdev->fops->unlocked_ioctl(filp, cmd, arg); + return ret; } #ifdef CONFIG_MMU @@ -307,22 +304,6 @@ static int v4l2_release(struct inode *inode, struct file *filp) return ret; } -static const struct file_operations v4l2_unlocked_fops = { - .owner = THIS_MODULE, - .read = v4l2_read, - .write = v4l2_write, - .open = v4l2_open, - .get_unmapped_area = v4l2_get_unmapped_area, - .mmap = v4l2_mmap, - .unlocked_ioctl = v4l2_unlocked_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = v4l2_compat_ioctl32, -#endif - .release = v4l2_release, - .poll = v4l2_poll, - .llseek = no_llseek, -}; - static const struct file_operations v4l2_fops = { .owner = THIS_MODULE, .read = v4l2_read, @@ -330,7 +311,7 @@ static const struct file_operations v4l2_fops = { .open = v4l2_open, .get_unmapped_area = v4l2_get_unmapped_area, .mmap = v4l2_mmap, - .ioctl = v4l2_ioctl, + .unlocked_ioctl = v4l2_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = v4l2_compat_ioctl32, #endif @@ -521,10 +502,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, ret = -ENOMEM; goto cleanup; } - if (vdev->fops->unlocked_ioctl) - vdev->cdev->ops = &v4l2_unlocked_fops; - else - vdev->cdev->ops = &v4l2_fops; + vdev->cdev->ops = &v4l2_fops; vdev->cdev->owner = vdev->fops->owner; ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); if (ret < 0) { diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index ad836d2d26f..f3c827eb0ab 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -463,15 +463,12 @@ struct data_buffer audio_buffer[]; void easycap_complete(struct urb *); int easycap_open(struct inode *, struct file *); int easycap_release(struct inode *, struct file *); -int easycap_ioctl(struct inode *, struct file *, \ - unsigned int, unsigned long); +long easycap_ioctl(struct file *, unsigned int, unsigned long); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) int easycap_open_noinode(struct file *); int easycap_release_noinode(struct file *); -long easycap_ioctl_noinode(struct file *, \ - unsigned int, unsigned long); int videodev_release(struct video_device *); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -515,8 +512,7 @@ void easysnd_complete(struct urb *); ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *); int easysnd_open(struct inode *, struct file *); int easysnd_release(struct inode *, struct file *); -int easysnd_ioctl(struct inode *, struct file *, \ - unsigned int, unsigned long); +long easysnd_ioctl(struct file *, unsigned int, unsigned long); unsigned int easysnd_poll(struct file *, poll_table *); void easysnd_delete(struct kref *); int submit_audio_urbs(struct easycap *); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 276b63dfe27..9a42ae02cd5 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -25,6 +25,7 @@ */ /*****************************************************************************/ +#include <linux/smp_lock.h> #include "easycap.h" #include "easycap_debug.h" #include "easycap_standard.h" @@ -773,19 +774,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAY("WARNING: failed to adjust mute: control not found\n"); return -ENOENT; } -/****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -long -easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg)\ - { - return easycap_ioctl((struct inode *)NULL, file, cmd, arg); -} -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + /*--------------------------------------------------------------------------*/ -int easycap_ioctl(struct inode *inode, struct file *file, \ - unsigned int cmd, unsigned long arg) +static int easycap_ioctl_bkl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { static struct easycap *peasycap; static struct usb_device *p; @@ -1956,19 +1948,22 @@ default: { } return 0; } -/****************************************************************************/ -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -long -easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) + +long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - return easysnd_ioctl((struct inode *)NULL, file, cmd, arg); + struct inode *inode = file->f_dentry->d_inode; + long ret; + + lock_kernel(); + ret = easycap_ioctl_bkl(inode, file, cmd, arg); + unlock_kernel(); + + return ret; } -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + /*--------------------------------------------------------------------------*/ -int easysnd_ioctl(struct inode *inode, struct file *file, \ - unsigned int cmd, unsigned long arg) +static int easysnd_ioctl_bkl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; @@ -2158,6 +2153,19 @@ default: { } return 0; } + +long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file->f_dentry->d_inode; + long ret; + + lock_kernel(); + ret = easysnd_ioctl_bkl(inode, file, cmd, arg); + unlock_kernel(); + + return ret; +} + /*****************************************************************************/ int explain_ioctl(__u32 wot) { diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 09c194ce10a..5a4bbd9b453 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -60,13 +60,13 @@ struct usb_driver easycap_usb_driver = { */ /*---------------------------------------------------------------------------*/ const struct file_operations easycap_fops = { -.owner = THIS_MODULE, -.open = easycap_open, -.release = easycap_release, -.ioctl = easycap_ioctl, -.poll = easycap_poll, -.mmap = easycap_mmap, -.llseek = no_llseek, + .owner = THIS_MODULE, + .open = easycap_open, + .release = easycap_release, + .unlocked_ioctl = easycap_ioctl, + .poll = easycap_poll, + .mmap = easycap_mmap, + .llseek = no_llseek, }; struct vm_operations_struct easycap_vm_ops = { .open = easycap_vma_open, @@ -83,12 +83,12 @@ struct usb_class_driver easycap_class = { #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #if defined(EASYCAP_NEEDS_V4L2_FOPS) const struct v4l2_file_operations v4l2_fops = { -.owner = THIS_MODULE, -.open = easycap_open_noinode, -.release = easycap_release_noinode, -.ioctl = easycap_ioctl_noinode, -.poll = easycap_poll, -.mmap = easycap_mmap, + .owner = THIS_MODULE, + .open = easycap_open_noinode, + .release = easycap_release_noinode, + .unlocked_ioctl = easycap_ioctl, + .poll = easycap_poll, + .mmap = easycap_mmap, }; #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ int video_device_many /*=0*/; @@ -102,12 +102,12 @@ struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device; */ /*--------------------------------------------------------------------------*/ const struct file_operations easysnd_fops = { -.owner = THIS_MODULE, -.open = easysnd_open, -.release = easysnd_release, -.ioctl = easysnd_ioctl, -.read = easysnd_read, -.llseek = no_llseek, + .owner = THIS_MODULE, + .open = easysnd_open, + .release = easysnd_release, + .unlocked_ioctl = easysnd_ioctl, + .read = easysnd_read, + .llseek = no_llseek, }; struct usb_class_driver easysnd_class = { .name = "usb/easysnd%d", diff --git a/fs/autofs/root.c b/fs/autofs/root.c index 9a0520b5066..11b1ea786d0 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c @@ -16,6 +16,7 @@ #include <linux/slab.h> #include <linux/param.h> #include <linux/time.h> +#include <linux/compat.h> #include <linux/smp_lock.h> #include "autofs_i.h" @@ -25,13 +26,17 @@ static int autofs_root_symlink(struct inode *,struct dentry *,const char *); static int autofs_root_unlink(struct inode *,struct dentry *); static int autofs_root_rmdir(struct inode *,struct dentry *); static int autofs_root_mkdir(struct inode *,struct dentry *,int); -static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); +static long autofs_root_ioctl(struct file *,unsigned int,unsigned long); +static long autofs_root_compat_ioctl(struct file *,unsigned int,unsigned long); const struct file_operations autofs_root_operations = { .llseek = generic_file_llseek, .read = generic_read_dir, .readdir = autofs_root_readdir, - .ioctl = autofs_root_ioctl, + .unlocked_ioctl = autofs_root_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = autofs_root_compat_ioctl, +#endif }; const struct inode_operations autofs_root_inode_operations = { @@ -492,6 +497,25 @@ static int autofs_root_mkdir(struct inode *dir, struct dentry *dentry, int mode) } /* Get/set timeout ioctl() operation */ +#ifdef CONFIG_COMPAT +static inline int autofs_compat_get_set_timeout(struct autofs_sb_info *sbi, + unsigned int __user *p) +{ + unsigned long ntimeout; + + if (get_user(ntimeout, p) || + put_user(sbi->exp_timeout / HZ, p)) + return -EFAULT; + + if (ntimeout > UINT_MAX/HZ) + sbi->exp_timeout = 0; + else + sbi->exp_timeout = ntimeout * HZ; + + return 0; +} +#endif + static inline int autofs_get_set_timeout(struct autofs_sb_info *sbi, unsigned long __user *p) { @@ -546,7 +570,7 @@ static inline int autofs_expire_run(struct super_block *sb, * ioctl()'s on the root directory is the chief method for the daemon to * generate kernel reactions */ -static int autofs_root_ioctl(struct inode *inode, struct file *filp, +static int autofs_do_root_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); @@ -571,6 +595,10 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, return 0; case AUTOFS_IOC_PROTOVER: /* Get protocol version */ return autofs_get_protover(argp); +#ifdef CONFIG_COMPAT + case AUTOFS_IOC_SETTIMEOUT32: + return autofs_compat_get_set_timeout(sbi, argp); +#endif case AUTOFS_IOC_SETTIMEOUT: return autofs_get_set_timeout(sbi, argp); case AUTOFS_IOC_EXPIRE: @@ -579,4 +607,37 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, default: return -ENOSYS; } + +} + +static long autofs_root_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int ret; + + lock_kernel(); + ret = autofs_do_root_ioctl(filp->f_path.dentry->d_inode, + filp, cmd, arg); + unlock_kernel(); + + return ret; +} + +#ifdef CONFIG_COMPAT +static long autofs_root_compat_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + int ret; + + lock_kernel(); + if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) + ret = autofs_do_root_ioctl(inode, filp, cmd, arg); + else + ret = autofs_do_root_ioctl(inode, filp, cmd, + (unsigned long)compat_ptr(arg)); + unlock_kernel(); + + return ret; } +#endif diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index db4117ed780..48e056e70fd 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -18,7 +18,9 @@ #include <linux/slab.h> #include <linux/param.h> #include <linux/time.h> +#include <linux/compat.h> #include <linux/smp_lock.h> + #include "autofs_i.h" static int autofs4_dir_symlink(struct inode *,struct dentry *,const char *); @@ -26,6 +28,7 @@ static int autofs4_dir_unlink(struct inode *,struct dentry *); static int autofs4_dir_rmdir(struct inode *,struct dentry *); static int autofs4_dir_mkdir(struct inode *,struct dentry *,int); static long autofs4_root_ioctl(struct file *,unsigned int,unsigned long); +static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); static int autofs4_dir_open(struct inode *inode, struct file *file); static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); static void *autofs4_follow_link(struct dentry *, struct nameidata *); @@ -40,6 +43,9 @@ const struct file_operations autofs4_root_operations = { .readdir = dcache_readdir, .llseek = dcache_dir_lseek, .unlocked_ioctl = autofs4_root_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = autofs4_root_compat_ioctl, +#endif }; const struct file_operations autofs4_dir_operations = { @@ -840,6 +846,26 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode) } /* Get/set timeout ioctl() operation */ +#ifdef CONFIG_COMPAT +static inline int autofs4_compat_get_set_timeout(struct autofs_sb_info *sbi, + compat_ulong_t __user *p) +{ + int rv; + unsigned long ntimeout; + + if ((rv = get_user(ntimeout, p)) || + (rv = put_user(sbi->exp_timeout/HZ, p))) + return rv; + + if (ntimeout > UINT_MAX/HZ) + sbi->exp_timeout = 0; + else + sbi->exp_timeout = ntimeout * HZ; + + return 0; +} +#endif + static inline int autofs4_get_set_timeout(struct autofs_sb_info *sbi, unsigned long __user *p) { @@ -933,6 +959,10 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, return autofs4_get_protosubver(sbi, p); case AUTOFS_IOC_SETTIMEOUT: return autofs4_get_set_timeout(sbi, p); +#ifdef CONFIG_COMPAT + case AUTOFS_IOC_SETTIMEOUT32: + return autofs4_compat_get_set_timeout(sbi, p); +#endif case AUTOFS_IOC_ASKUMOUNT: return autofs4_ask_umount(filp->f_path.mnt, p); @@ -961,3 +991,22 @@ static long autofs4_root_ioctl(struct file *filp, return ret; } + +#ifdef CONFIG_COMPAT +static long autofs4_root_compat_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct inode *inode = filp->f_path.dentry->d_inode; + int ret; + + lock_kernel(); + if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) + ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); + else + ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, + (unsigned long)compat_ptr(arg)); + unlock_kernel(); + + return ret; +} +#endif diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 63ae8583146..5d9b936c458 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -131,23 +131,6 @@ static int w_long(unsigned int fd, unsigned int cmd, return err; } -static int rw_long(unsigned int fd, unsigned int cmd, - compat_ulong_t __user *argp) -{ - mm_segment_t old_fs = get_fs(); - int err; - unsigned long val; - - if(get_user(val, argp)) - return -EFAULT; - set_fs (KERNEL_DS); - err = sys_ioctl(fd, cmd, (unsigned long)&val); - set_fs (old_fs); - if (!err && put_user(val, argp)) - return -EFAULT; - return err; -} - struct compat_video_event { int32_t type; compat_time_t timestamp; @@ -594,12 +577,6 @@ static int do_smb_getmountuid(unsigned int fd, unsigned int cmd, return err; } -static int ioc_settimeout(unsigned int fd, unsigned int cmd, - compat_ulong_t __user *argp) -{ - return rw_long(fd, AUTOFS_IOC_SETTIMEOUT, argp); -} - /* Bluetooth ioctls */ #define HCIUARTSETPROTO _IOW('U', 200, int) #define HCIUARTGETPROTO _IOR('U', 201, int) @@ -1284,13 +1261,6 @@ COMPATIBLE_IOCTL(SOUND_MIXER_PRIVATE5) COMPATIBLE_IOCTL(SOUND_MIXER_GETLEVELS) COMPATIBLE_IOCTL(SOUND_MIXER_SETLEVELS) COMPATIBLE_IOCTL(OSS_GETVERSION) -/* AUTOFS */ -COMPATIBLE_IOCTL(AUTOFS_IOC_CATATONIC) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE) -COMPATIBLE_IOCTL(AUTOFS_IOC_EXPIRE_MULTI) -COMPATIBLE_IOCTL(AUTOFS_IOC_PROTOSUBVER) -COMPATIBLE_IOCTL(AUTOFS_IOC_ASKUMOUNT) /* Raw devices */ COMPATIBLE_IOCTL(RAW_SETBIND) COMPATIBLE_IOCTL(RAW_GETBIND) @@ -1557,9 +1527,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd, case RAW_GETBIND: return raw_ioctl(fd, cmd, argp); #endif -#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,unsigned int) - case AUTOFS_IOC_SETTIMEOUT32: - return ioc_settimeout(fd, cmd, argp); /* One SMB ioctl needs translations. */ #define SMB_IOC_GETMOUNTUID_32 _IOR('u', 1, compat_uid_t) case SMB_IOC_GETMOUNTUID_32: @@ -1614,9 +1581,6 @@ static long do_ioctl_trans(int fd, unsigned int cmd, case KDSKBMETA: case KDSKBLED: case KDSETLED: - /* AUTOFS */ - case AUTOFS_IOC_READY: - case AUTOFS_IOC_FAIL: /* NBD */ case NBD_SET_SOCK: case NBD_SET_BLKSIZE: diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c index 023c03d0207..84a8cfc4e38 100644 --- a/fs/ncpfs/ioctl.c +++ b/fs/ncpfs/ioctl.c @@ -20,7 +20,6 @@ #include <linux/smp_lock.h> #include <linux/vmalloc.h> #include <linux/sched.h> -#include <linux/smp_lock.h> #include <linux/ncp_fs.h> diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h index 7b09c8348fd..da64e15004b 100644 --- a/include/linux/auto_fs.h +++ b/include/linux/auto_fs.h @@ -79,6 +79,7 @@ struct autofs_packet_expire { #define AUTOFS_IOC_FAIL _IO(0x93,0x61) #define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) #define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int) +#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t) #define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long) #define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire) |