aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-13 20:52:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-13 20:52:35 -0400
commit10041d2d14688e207d0d829095147aa82c1f211b (patch)
tree57ef361d05e6bbffe3ec490ca9110878a6e969e2
parent4914c7f881845367b9198631a014ab466329b9e5 (diff)
parentb19dd42faf413b4705d4adb38521e82d73fa4249 (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/Locking8
-rw-r--r--Documentation/filesystems/vfs.txt6
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c7
-rw-r--r--fs/bad_inode.c7
-rw-r--r--fs/compat_ioctl.c3
-rw-r--r--fs/ioctl.c18
-rw-r--r--fs/logfs/dir.c2
-rw-r--r--fs/logfs/file.c6
-rw-r--r--fs/logfs/logfs.h3
-rw-r--r--fs/proc/inode.c17
-rw-r--r--include/linux/fs.h5
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
409aio_write: no 407aio_write: no
410readdir: no 408readdir: no
411poll: no 409poll: no
412ioctl: yes (see below) 410unlocked_ioctl: no
413unlocked_ioctl: no (see below)
414compat_ioctl: no 411compat_ioctl: no
415mmap: no 412mmap: no
416open: no 413open: no
@@ -453,9 +450,6 @@ move ->readdir() to inode_operations and use a separate method for directory
453anything that resembles union-mount we won't have a struct file for all 450anything that resembles union-mount we won't have a struct file for all
454components. And there are other reasons why the current interface is a mess... 451components. 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
457doesn'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
460in sys_read() and friends. 454in 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
58static int bad_file_ioctl (struct inode *inode, struct file *filp,
59 unsigned int cmd, unsigned long arg)
60{
61 return -EIO;
62}
63
64static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd, 58static 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};
825const struct file_operations logfs_dir_fops = { 825const 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
184int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 184long 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;
504extern const struct file_operations logfs_reg_fops; 504extern const struct file_operations logfs_reg_fops;
505extern const struct address_space_operations logfs_reg_aops; 505extern const struct address_space_operations logfs_reg_aops;
506int logfs_readpage(struct file *file, struct page *page); 506int logfs_readpage(struct file *file, struct page *page);
507int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 507long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
508 unsigned long arg);
509int logfs_fsync(struct file *file, int datasync); 508int 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 */
1489struct file_operations { 1489struct 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 *);