diff options
| -rw-r--r-- | Documentation/filesystems/Locking | 8 | ||||
| -rw-r--r-- | Documentation/filesystems/vfs.txt | 6 | ||||
| -rw-r--r-- | fs/bad_inode.c | 7 | ||||
| -rw-r--r-- | fs/compat_ioctl.c | 3 | ||||
| -rw-r--r-- | fs/ioctl.c | 18 | ||||
| -rw-r--r-- | fs/proc/inode.c | 17 | ||||
| -rw-r--r-- | include/linux/fs.h | 5 |
7 files changed, 13 insertions, 51 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index bbcc15651a21..2db4283efa8d 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
| @@ -374,8 +374,6 @@ prototypes: | |||
| 374 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); | 374 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); |
| 375 | int (*readdir) (struct file *, void *, filldir_t); | 375 | int (*readdir) (struct file *, void *, filldir_t); |
| 376 | unsigned int (*poll) (struct file *, struct poll_table_struct *); | 376 | unsigned int (*poll) (struct file *, struct poll_table_struct *); |
| 377 | int (*ioctl) (struct inode *, struct file *, unsigned int, | ||
| 378 | unsigned long); | ||
| 379 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); | 377 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); |
| 380 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); | 378 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); |
| 381 | int (*mmap) (struct file *, struct vm_area_struct *); | 379 | int (*mmap) (struct file *, struct vm_area_struct *); |
| @@ -409,8 +407,7 @@ write: no | |||
| 409 | aio_write: no | 407 | aio_write: no |
| 410 | readdir: no | 408 | readdir: no |
| 411 | poll: no | 409 | poll: no |
| 412 | ioctl: yes (see below) | 410 | unlocked_ioctl: no |
| 413 | unlocked_ioctl: no (see below) | ||
| 414 | compat_ioctl: no | 411 | compat_ioctl: no |
| 415 | mmap: no | 412 | mmap: no |
| 416 | open: no | 413 | open: no |
| @@ -453,9 +450,6 @@ move ->readdir() to inode_operations and use a separate method for directory | |||
| 453 | anything that resembles union-mount we won't have a struct file for all | 450 | anything that resembles union-mount we won't have a struct file for all |
| 454 | components. And there are other reasons why the current interface is a mess... | 451 | components. And there are other reasons why the current interface is a mess... |
| 455 | 452 | ||
| 456 | ->ioctl() on regular files is superceded by the ->unlocked_ioctl() that | ||
| 457 | doesn't take the BKL. | ||
| 458 | |||
| 459 | ->read on directories probably must go away - we should just enforce -EISDIR | 453 | ->read on directories probably must go away - we should just enforce -EISDIR |
| 460 | in sys_read() and friends. | 454 | in sys_read() and friends. |
| 461 | 455 | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 94677e7dcb13..ed7e5efc06d8 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
| @@ -727,7 +727,6 @@ struct file_operations { | |||
| 727 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); | 727 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); |
| 728 | int (*readdir) (struct file *, void *, filldir_t); | 728 | int (*readdir) (struct file *, void *, filldir_t); |
| 729 | unsigned int (*poll) (struct file *, struct poll_table_struct *); | 729 | unsigned int (*poll) (struct file *, struct poll_table_struct *); |
| 730 | int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); | ||
| 731 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); | 730 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); |
| 732 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); | 731 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); |
| 733 | int (*mmap) (struct file *, struct vm_area_struct *); | 732 | int (*mmap) (struct file *, struct vm_area_struct *); |
| @@ -768,10 +767,7 @@ otherwise noted. | |||
| 768 | activity on this file and (optionally) go to sleep until there | 767 | activity on this file and (optionally) go to sleep until there |
| 769 | is activity. Called by the select(2) and poll(2) system calls | 768 | is activity. Called by the select(2) and poll(2) system calls |
| 770 | 769 | ||
| 771 | ioctl: called by the ioctl(2) system call | 770 | unlocked_ioctl: called by the ioctl(2) system call. |
| 772 | |||
| 773 | unlocked_ioctl: called by the ioctl(2) system call. Filesystems that do not | ||
| 774 | require the BKL should use this method instead of the ioctl() above. | ||
| 775 | 771 | ||
| 776 | compat_ioctl: called by the ioctl(2) system call when 32 bit system calls | 772 | compat_ioctl: called by the ioctl(2) system call when 32 bit system calls |
| 777 | are used on 64 bit kernels. | 773 | are used on 64 bit kernels. |
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 52e59bf4aa5f..f024d8aaddef 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
| @@ -55,12 +55,6 @@ static unsigned int bad_file_poll(struct file *filp, poll_table *wait) | |||
| 55 | return POLLERR; | 55 | return POLLERR; |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | static int bad_file_ioctl (struct inode *inode, struct file *filp, | ||
| 59 | unsigned int cmd, unsigned long arg) | ||
| 60 | { | ||
| 61 | return -EIO; | ||
| 62 | } | ||
| 63 | |||
| 64 | static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd, | 58 | static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd, |
| 65 | unsigned long arg) | 59 | unsigned long arg) |
| 66 | { | 60 | { |
| @@ -159,7 +153,6 @@ static const struct file_operations bad_file_ops = | |||
| 159 | .aio_write = bad_file_aio_write, | 153 | .aio_write = bad_file_aio_write, |
| 160 | .readdir = bad_file_readdir, | 154 | .readdir = bad_file_readdir, |
| 161 | .poll = bad_file_poll, | 155 | .poll = bad_file_poll, |
| 162 | .ioctl = bad_file_ioctl, | ||
| 163 | .unlocked_ioctl = bad_file_unlocked_ioctl, | 156 | .unlocked_ioctl = bad_file_unlocked_ioctl, |
| 164 | .compat_ioctl = bad_file_compat_ioctl, | 157 | .compat_ioctl = bad_file_compat_ioctl, |
| 165 | .mmap = bad_file_mmap, | 158 | .mmap = bad_file_mmap, |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 70227e0dc01d..03e59aa318eb 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -1699,8 +1699,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd, | |||
| 1699 | goto out_fput; | 1699 | goto out_fput; |
| 1700 | } | 1700 | } |
| 1701 | 1701 | ||
| 1702 | if (!filp->f_op || | 1702 | if (!filp->f_op || !filp->f_op->unlocked_ioctl) |
| 1703 | (!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl)) | ||
| 1704 | goto do_ioctl; | 1703 | goto do_ioctl; |
| 1705 | break; | 1704 | break; |
| 1706 | } | 1705 | } |
diff --git a/fs/ioctl.c b/fs/ioctl.c index 2d140a713861..f855ea4fc888 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | * @arg: command-specific argument for ioctl | 29 | * @arg: command-specific argument for ioctl |
| 30 | * | 30 | * |
| 31 | * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise | 31 | * Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise |
| 32 | * invokes filesystem specific ->ioctl method. If neither method exists, | ||
| 33 | * returns -ENOTTY. | 32 | * returns -ENOTTY. |
| 34 | * | 33 | * |
| 35 | * Returns 0 on success, -errno on error. | 34 | * Returns 0 on success, -errno on error. |
| @@ -39,21 +38,12 @@ static long vfs_ioctl(struct file *filp, unsigned int cmd, | |||
| 39 | { | 38 | { |
| 40 | int error = -ENOTTY; | 39 | int error = -ENOTTY; |
| 41 | 40 | ||
| 42 | if (!filp->f_op) | 41 | if (!filp->f_op || !filp->f_op->unlocked_ioctl) |
| 43 | goto out; | 42 | goto out; |
| 44 | 43 | ||
| 45 | if (filp->f_op->unlocked_ioctl) { | 44 | error = filp->f_op->unlocked_ioctl(filp, cmd, arg); |
| 46 | error = filp->f_op->unlocked_ioctl(filp, cmd, arg); | 45 | if (error == -ENOIOCTLCMD) |
| 47 | if (error == -ENOIOCTLCMD) | 46 | error = -EINVAL; |
| 48 | error = -EINVAL; | ||
| 49 | goto out; | ||
| 50 | } else if (filp->f_op->ioctl) { | ||
| 51 | lock_kernel(); | ||
| 52 | error = filp->f_op->ioctl(filp->f_path.dentry->d_inode, | ||
| 53 | filp, cmd, arg); | ||
| 54 | unlock_kernel(); | ||
| 55 | } | ||
| 56 | |||
| 57 | out: | 47 | out: |
| 58 | return error; | 48 | return error; |
| 59 | } | 49 | } |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 23561cda7245..9c2b5f484879 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
| @@ -214,8 +214,7 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne | |||
| 214 | { | 214 | { |
| 215 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); | 215 | struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); |
| 216 | long rv = -ENOTTY; | 216 | long rv = -ENOTTY; |
| 217 | long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long); | 217 | long (*ioctl)(struct file *, unsigned int, unsigned long); |
| 218 | int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long); | ||
| 219 | 218 | ||
| 220 | spin_lock(&pde->pde_unload_lock); | 219 | spin_lock(&pde->pde_unload_lock); |
| 221 | if (!pde->proc_fops) { | 220 | if (!pde->proc_fops) { |
| @@ -223,19 +222,11 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne | |||
| 223 | return rv; | 222 | return rv; |
| 224 | } | 223 | } |
| 225 | pde->pde_users++; | 224 | pde->pde_users++; |
| 226 | unlocked_ioctl = pde->proc_fops->unlocked_ioctl; | 225 | ioctl = pde->proc_fops->unlocked_ioctl; |
| 227 | ioctl = pde->proc_fops->ioctl; | ||
| 228 | spin_unlock(&pde->pde_unload_lock); | 226 | spin_unlock(&pde->pde_unload_lock); |
| 229 | 227 | ||
| 230 | if (unlocked_ioctl) { | 228 | if (ioctl) |
| 231 | rv = unlocked_ioctl(file, cmd, arg); | 229 | rv = ioctl(file, cmd, arg); |
| 232 | if (rv == -ENOIOCTLCMD) | ||
| 233 | rv = -EINVAL; | ||
| 234 | } else if (ioctl) { | ||
| 235 | WARN_ONCE(1, "Procfs ioctl handlers must use unlocked_ioctl, " | ||
| 236 | "%pf will be called without the Bkl held\n", ioctl); | ||
| 237 | rv = ioctl(file->f_path.dentry->d_inode, file, cmd, arg); | ||
| 238 | } | ||
| 239 | 230 | ||
| 240 | pde_users_dec(pde); | 231 | pde_users_dec(pde); |
| 241 | return rv; | 232 | return rv; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 7a0625e26a39..3c786fdaeab6 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1483,8 +1483,8 @@ struct block_device_operations; | |||
| 1483 | 1483 | ||
| 1484 | /* | 1484 | /* |
| 1485 | * NOTE: | 1485 | * NOTE: |
| 1486 | * read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl | 1486 | * all file operations except setlease can be called without |
| 1487 | * can be called without the big kernel lock held in all filesystems. | 1487 | * the big kernel lock held in all filesystems. |
| 1488 | */ | 1488 | */ |
| 1489 | struct file_operations { | 1489 | struct file_operations { |
| 1490 | struct module *owner; | 1490 | struct module *owner; |
| @@ -1495,7 +1495,6 @@ struct file_operations { | |||
| 1495 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); | 1495 | ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); |
| 1496 | int (*readdir) (struct file *, void *, filldir_t); | 1496 | int (*readdir) (struct file *, void *, filldir_t); |
| 1497 | unsigned int (*poll) (struct file *, struct poll_table_struct *); | 1497 | unsigned int (*poll) (struct file *, struct poll_table_struct *); |
| 1498 | int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); | ||
| 1499 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); | 1498 | long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); |
| 1500 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); | 1499 | long (*compat_ioctl) (struct file *, unsigned int, unsigned long); |
| 1501 | int (*mmap) (struct file *, struct vm_area_struct *); | 1500 | int (*mmap) (struct file *, struct vm_area_struct *); |
