diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-13 20:52:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-13 20:52:35 -0400 |
commit | 10041d2d14688e207d0d829095147aa82c1f211b (patch) | |
tree | 57ef361d05e6bbffe3ec490ca9110878a6e969e2 | |
parent | 4914c7f881845367b9198631a014ab466329b9e5 (diff) | |
parent | b19dd42faf413b4705d4adb38521e82d73fa4249 (diff) |
Merge branch 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing
* 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing:
bkl: Remove locked .ioctl file operation
v4l: Remove reference to bkl ioctl in compat ioctl handling
logfs: kill BKL
-rw-r--r-- | Documentation/filesystems/Locking | 8 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 6 | ||||
-rw-r--r-- | drivers/media/video/v4l2-compat-ioctl32.c | 7 | ||||
-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/logfs/dir.c | 2 | ||||
-rw-r--r-- | fs/logfs/file.c | 6 | ||||
-rw-r--r-- | fs/logfs/logfs.h | 3 | ||||
-rw-r--r-- | fs/proc/inode.c | 17 | ||||
-rw-r--r-- | include/linux/fs.h | 5 |
11 files changed, 19 insertions, 63 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/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c index d2f20c2acae2..073f01390cdd 100644 --- a/drivers/media/video/v4l2-compat-ioctl32.c +++ b/drivers/media/video/v4l2-compat-ioctl32.c | |||
@@ -228,11 +228,6 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
228 | 228 | ||
229 | if (file->f_op->unlocked_ioctl) | 229 | if (file->f_op->unlocked_ioctl) |
230 | ret = file->f_op->unlocked_ioctl(file, cmd, arg); | 230 | ret = file->f_op->unlocked_ioctl(file, cmd, arg); |
231 | else if (file->f_op->ioctl) { | ||
232 | lock_kernel(); | ||
233 | ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg); | ||
234 | unlock_kernel(); | ||
235 | } | ||
236 | 231 | ||
237 | return ret; | 232 | return ret; |
238 | } | 233 | } |
@@ -973,7 +968,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) | |||
973 | { | 968 | { |
974 | long ret = -ENOIOCTLCMD; | 969 | long ret = -ENOIOCTLCMD; |
975 | 970 | ||
976 | if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl) | 971 | if (!file->f_op->unlocked_ioctl) |
977 | return ret; | 972 | return ret; |
978 | 973 | ||
979 | switch (cmd) { | 974 | switch (cmd) { |
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/logfs/dir.c b/fs/logfs/dir.c index 675cc49197fe..9777eb5b5522 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -824,7 +824,7 @@ const struct inode_operations logfs_dir_iops = { | |||
824 | }; | 824 | }; |
825 | const struct file_operations logfs_dir_fops = { | 825 | const struct file_operations logfs_dir_fops = { |
826 | .fsync = logfs_fsync, | 826 | .fsync = logfs_fsync, |
827 | .ioctl = logfs_ioctl, | 827 | .unlocked_ioctl = logfs_ioctl, |
828 | .readdir = logfs_readdir, | 828 | .readdir = logfs_readdir, |
829 | .read = generic_read_dir, | 829 | .read = generic_read_dir, |
830 | }; | 830 | }; |
diff --git a/fs/logfs/file.c b/fs/logfs/file.c index 4dd0f7c06e39..e86376b87af1 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c | |||
@@ -181,9 +181,9 @@ static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | 183 | ||
184 | int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 184 | long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
185 | unsigned long arg) | ||
186 | { | 185 | { |
186 | struct inode *inode = file->f_path.dentry->d_inode; | ||
187 | struct logfs_inode *li = logfs_inode(inode); | 187 | struct logfs_inode *li = logfs_inode(inode); |
188 | unsigned int oldflags, flags; | 188 | unsigned int oldflags, flags; |
189 | int err; | 189 | int err; |
@@ -255,7 +255,7 @@ const struct file_operations logfs_reg_fops = { | |||
255 | .aio_read = generic_file_aio_read, | 255 | .aio_read = generic_file_aio_read, |
256 | .aio_write = generic_file_aio_write, | 256 | .aio_write = generic_file_aio_write, |
257 | .fsync = logfs_fsync, | 257 | .fsync = logfs_fsync, |
258 | .ioctl = logfs_ioctl, | 258 | .unlocked_ioctl = logfs_ioctl, |
259 | .llseek = generic_file_llseek, | 259 | .llseek = generic_file_llseek, |
260 | .mmap = generic_file_readonly_mmap, | 260 | .mmap = generic_file_readonly_mmap, |
261 | .open = generic_file_open, | 261 | .open = generic_file_open, |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 5e3b72077951..b8786264d243 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -504,8 +504,7 @@ extern const struct inode_operations logfs_reg_iops; | |||
504 | extern const struct file_operations logfs_reg_fops; | 504 | extern const struct file_operations logfs_reg_fops; |
505 | extern const struct address_space_operations logfs_reg_aops; | 505 | extern const struct address_space_operations logfs_reg_aops; |
506 | int logfs_readpage(struct file *file, struct page *page); | 506 | int logfs_readpage(struct file *file, struct page *page); |
507 | int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 507 | long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
508 | unsigned long arg); | ||
509 | int logfs_fsync(struct file *file, int datasync); | 508 | int logfs_fsync(struct file *file, int datasync); |
510 | 509 | ||
511 | /* gc.c */ | 510 | /* gc.c */ |
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 5f0ca2fbb2a0..9a96b4d83fc1 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 *); |