Skip to content

Commit

Permalink
Merge branch 'bkl/ioctl' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Aug 14, 2010
2 parents 4914c7f + b19dd42 commit 10041d2
Show file tree
Hide file tree
Showing 11 changed files with 19 additions and 63 deletions.
8 changes: 1 addition & 7 deletions Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,6 @@ prototypes:
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int,
unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
Expand Down Expand Up @@ -409,8 +407,7 @@ write: no
aio_write: no
readdir: no
poll: no
ioctl: yes (see below)
unlocked_ioctl: no (see below)
unlocked_ioctl: no
compat_ioctl: no
mmap: no
open: no
Expand Down Expand Up @@ -453,9 +450,6 @@ move ->readdir() to inode_operations and use a separate method for directory
anything that resembles union-mount we won't have a struct file for all
components. And there are other reasons why the current interface is a mess...

->ioctl() on regular files is superceded by the ->unlocked_ioctl() that
doesn't take the BKL.

->read on directories probably must go away - we should just enforce -EISDIR
in sys_read() and friends.

Expand Down
6 changes: 1 addition & 5 deletions Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,6 @@ struct file_operations {
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
Expand Down Expand Up @@ -768,10 +767,7 @@ otherwise noted.
activity on this file and (optionally) go to sleep until there
is activity. Called by the select(2) and poll(2) system calls

ioctl: called by the ioctl(2) system call

unlocked_ioctl: called by the ioctl(2) system call. Filesystems that do not
require the BKL should use this method instead of the ioctl() above.
unlocked_ioctl: called by the ioctl(2) system call.

compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
are used on 64 bit kernels.
Expand Down
7 changes: 1 addition & 6 deletions drivers/media/video/v4l2-compat-ioctl32.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,6 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)

if (file->f_op->unlocked_ioctl)
ret = file->f_op->unlocked_ioctl(file, cmd, arg);
else if (file->f_op->ioctl) {
lock_kernel();
ret = file->f_op->ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
unlock_kernel();
}

return ret;
}
Expand Down Expand Up @@ -973,7 +968,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret = -ENOIOCTLCMD;

if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl)
if (!file->f_op->unlocked_ioctl)
return ret;

switch (cmd) {
Expand Down
7 changes: 0 additions & 7 deletions fs/bad_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ static unsigned int bad_file_poll(struct file *filp, poll_table *wait)
return POLLERR;
}

static int bad_file_ioctl (struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
return -EIO;
}

static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd,
unsigned long arg)
{
Expand Down Expand Up @@ -159,7 +153,6 @@ static const struct file_operations bad_file_ops =
.aio_write = bad_file_aio_write,
.readdir = bad_file_readdir,
.poll = bad_file_poll,
.ioctl = bad_file_ioctl,
.unlocked_ioctl = bad_file_unlocked_ioctl,
.compat_ioctl = bad_file_compat_ioctl,
.mmap = bad_file_mmap,
Expand Down
3 changes: 1 addition & 2 deletions fs/compat_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1699,8 +1699,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
goto out_fput;
}

if (!filp->f_op ||
(!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
goto do_ioctl;
break;
}
Expand Down
18 changes: 4 additions & 14 deletions fs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
* @arg: command-specific argument for ioctl
*
* Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
* invokes filesystem specific ->ioctl method. If neither method exists,
* returns -ENOTTY.
*
* Returns 0 on success, -errno on error.
Expand All @@ -39,21 +38,12 @@ static long vfs_ioctl(struct file *filp, unsigned int cmd,
{
int error = -ENOTTY;

if (!filp->f_op)
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
goto out;

if (filp->f_op->unlocked_ioctl) {
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -EINVAL;
goto out;
} else if (filp->f_op->ioctl) {
lock_kernel();
error = filp->f_op->ioctl(filp->f_path.dentry->d_inode,
filp, cmd, arg);
unlock_kernel();
}

error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
if (error == -ENOIOCTLCMD)
error = -EINVAL;
out:
return error;
}
Expand Down
2 changes: 1 addition & 1 deletion fs/logfs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ const struct inode_operations logfs_dir_iops = {
};
const struct file_operations logfs_dir_fops = {
.fsync = logfs_fsync,
.ioctl = logfs_ioctl,
.unlocked_ioctl = logfs_ioctl,
.readdir = logfs_readdir,
.read = generic_read_dir,
};
6 changes: 3 additions & 3 deletions fs/logfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@ static int logfs_releasepage(struct page *page, gfp_t only_xfs_uses_this)
}


int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file->f_path.dentry->d_inode;
struct logfs_inode *li = logfs_inode(inode);
unsigned int oldflags, flags;
int err;
Expand Down Expand Up @@ -255,7 +255,7 @@ const struct file_operations logfs_reg_fops = {
.aio_read = generic_file_aio_read,
.aio_write = generic_file_aio_write,
.fsync = logfs_fsync,
.ioctl = logfs_ioctl,
.unlocked_ioctl = logfs_ioctl,
.llseek = generic_file_llseek,
.mmap = generic_file_readonly_mmap,
.open = generic_file_open,
Expand Down
3 changes: 1 addition & 2 deletions fs/logfs/logfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,7 @@ extern const struct inode_operations logfs_reg_iops;
extern const struct file_operations logfs_reg_fops;
extern const struct address_space_operations logfs_reg_aops;
int logfs_readpage(struct file *file, struct page *page);
int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
int logfs_fsync(struct file *file, int datasync);

/* gc.c */
Expand Down
17 changes: 4 additions & 13 deletions fs/proc/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,28 +214,19 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
{
struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
long rv = -ENOTTY;
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
long (*ioctl)(struct file *, unsigned int, unsigned long);

spin_lock(&pde->pde_unload_lock);
if (!pde->proc_fops) {
spin_unlock(&pde->pde_unload_lock);
return rv;
}
pde->pde_users++;
unlocked_ioctl = pde->proc_fops->unlocked_ioctl;
ioctl = pde->proc_fops->ioctl;
ioctl = pde->proc_fops->unlocked_ioctl;
spin_unlock(&pde->pde_unload_lock);

if (unlocked_ioctl) {
rv = unlocked_ioctl(file, cmd, arg);
if (rv == -ENOIOCTLCMD)
rv = -EINVAL;
} else if (ioctl) {
WARN_ONCE(1, "Procfs ioctl handlers must use unlocked_ioctl, "
"%pf will be called without the Bkl held\n", ioctl);
rv = ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
}
if (ioctl)
rv = ioctl(file, cmd, arg);

pde_users_dec(pde);
return rv;
Expand Down
5 changes: 2 additions & 3 deletions include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1483,8 +1483,8 @@ struct block_device_operations;

/*
* NOTE:
* read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
* can be called without the big kernel lock held in all filesystems.
* all file operations except setlease can be called without
* the big kernel lock held in all filesystems.
*/
struct file_operations {
struct module *owner;
Expand All @@ -1495,7 +1495,6 @@ struct file_operations {
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
Expand Down

0 comments on commit 10041d2

Please sign in to comment.