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
This commit is contained in:
Коммит
10041d2d14
|
@ -374,8 +374,6 @@ prototypes:
|
||||||
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||||
int (*readdir) (struct file *, void *, filldir_t);
|
int (*readdir) (struct file *, void *, filldir_t);
|
||||||
unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
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 (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
int (*mmap) (struct file *, struct vm_area_struct *);
|
int (*mmap) (struct file *, struct vm_area_struct *);
|
||||||
|
@ -409,8 +407,7 @@ write: no
|
||||||
aio_write: no
|
aio_write: no
|
||||||
readdir: no
|
readdir: no
|
||||||
poll: no
|
poll: no
|
||||||
ioctl: yes (see below)
|
unlocked_ioctl: no
|
||||||
unlocked_ioctl: no (see below)
|
|
||||||
compat_ioctl: no
|
compat_ioctl: no
|
||||||
mmap: no
|
mmap: no
|
||||||
open: no
|
open: no
|
||||||
|
@ -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
|
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...
|
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
|
->read on directories probably must go away - we should just enforce -EISDIR
|
||||||
in sys_read() and friends.
|
in sys_read() and friends.
|
||||||
|
|
||||||
|
|
|
@ -727,7 +727,6 @@ struct file_operations {
|
||||||
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||||
int (*readdir) (struct file *, void *, filldir_t);
|
int (*readdir) (struct file *, void *, filldir_t);
|
||||||
unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
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 (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
int (*mmap) (struct file *, struct vm_area_struct *);
|
int (*mmap) (struct file *, struct vm_area_struct *);
|
||||||
|
@ -768,10 +767,7 @@ otherwise noted.
|
||||||
activity on this file and (optionally) go to sleep until there
|
activity on this file and (optionally) go to sleep until there
|
||||||
is activity. Called by the select(2) and poll(2) system calls
|
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.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
|
compat_ioctl: called by the ioctl(2) system call when 32 bit system calls
|
||||||
are used on 64 bit kernels.
|
are used on 64 bit kernels.
|
||||||
|
|
|
@ -228,11 +228,6 @@ static long native_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
|
|
||||||
if (file->f_op->unlocked_ioctl)
|
if (file->f_op->unlocked_ioctl)
|
||||||
ret = file->f_op->unlocked_ioctl(file, cmd, arg);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -973,7 +968,7 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
long ret = -ENOIOCTLCMD;
|
long ret = -ENOIOCTLCMD;
|
||||||
|
|
||||||
if (!file->f_op->ioctl && !file->f_op->unlocked_ioctl)
|
if (!file->f_op->unlocked_ioctl)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
|
|
@ -55,12 +55,6 @@ static unsigned int bad_file_poll(struct file *filp, poll_table *wait)
|
||||||
return POLLERR;
|
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,
|
static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd,
|
||||||
unsigned long arg)
|
unsigned long arg)
|
||||||
{
|
{
|
||||||
|
@ -159,7 +153,6 @@ static const struct file_operations bad_file_ops =
|
||||||
.aio_write = bad_file_aio_write,
|
.aio_write = bad_file_aio_write,
|
||||||
.readdir = bad_file_readdir,
|
.readdir = bad_file_readdir,
|
||||||
.poll = bad_file_poll,
|
.poll = bad_file_poll,
|
||||||
.ioctl = bad_file_ioctl,
|
|
||||||
.unlocked_ioctl = bad_file_unlocked_ioctl,
|
.unlocked_ioctl = bad_file_unlocked_ioctl,
|
||||||
.compat_ioctl = bad_file_compat_ioctl,
|
.compat_ioctl = bad_file_compat_ioctl,
|
||||||
.mmap = bad_file_mmap,
|
.mmap = bad_file_mmap,
|
||||||
|
|
|
@ -1699,8 +1699,7 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
|
||||||
goto out_fput;
|
goto out_fput;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!filp->f_op ||
|
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
|
||||||
(!filp->f_op->ioctl && !filp->f_op->unlocked_ioctl))
|
|
||||||
goto do_ioctl;
|
goto do_ioctl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
18
fs/ioctl.c
18
fs/ioctl.c
|
@ -29,7 +29,6 @@
|
||||||
* @arg: command-specific argument for ioctl
|
* @arg: command-specific argument for ioctl
|
||||||
*
|
*
|
||||||
* Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
|
* Invokes filesystem specific ->unlocked_ioctl, if one exists; otherwise
|
||||||
* invokes filesystem specific ->ioctl method. If neither method exists,
|
|
||||||
* returns -ENOTTY.
|
* returns -ENOTTY.
|
||||||
*
|
*
|
||||||
* Returns 0 on success, -errno on error.
|
* Returns 0 on success, -errno on error.
|
||||||
|
@ -39,21 +38,12 @@ static long vfs_ioctl(struct file *filp, unsigned int cmd,
|
||||||
{
|
{
|
||||||
int error = -ENOTTY;
|
int error = -ENOTTY;
|
||||||
|
|
||||||
if (!filp->f_op)
|
if (!filp->f_op || !filp->f_op->unlocked_ioctl)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (filp->f_op->unlocked_ioctl) {
|
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
|
||||||
error = filp->f_op->unlocked_ioctl(filp, cmd, arg);
|
if (error == -ENOIOCTLCMD)
|
||||||
if (error == -ENOIOCTLCMD)
|
error = -EINVAL;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,7 +824,7 @@ const struct inode_operations logfs_dir_iops = {
|
||||||
};
|
};
|
||||||
const struct file_operations logfs_dir_fops = {
|
const struct file_operations logfs_dir_fops = {
|
||||||
.fsync = logfs_fsync,
|
.fsync = logfs_fsync,
|
||||||
.ioctl = logfs_ioctl,
|
.unlocked_ioctl = logfs_ioctl,
|
||||||
.readdir = logfs_readdir,
|
.readdir = logfs_readdir,
|
||||||
.read = generic_read_dir,
|
.read = generic_read_dir,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||||
unsigned long arg)
|
|
||||||
{
|
{
|
||||||
|
struct inode *inode = file->f_path.dentry->d_inode;
|
||||||
struct logfs_inode *li = logfs_inode(inode);
|
struct logfs_inode *li = logfs_inode(inode);
|
||||||
unsigned int oldflags, flags;
|
unsigned int oldflags, flags;
|
||||||
int err;
|
int err;
|
||||||
|
@ -255,7 +255,7 @@ const struct file_operations logfs_reg_fops = {
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = generic_file_aio_write,
|
||||||
.fsync = logfs_fsync,
|
.fsync = logfs_fsync,
|
||||||
.ioctl = logfs_ioctl,
|
.unlocked_ioctl = logfs_ioctl,
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.mmap = generic_file_readonly_mmap,
|
.mmap = generic_file_readonly_mmap,
|
||||||
.open = generic_file_open,
|
.open = generic_file_open,
|
||||||
|
|
|
@ -504,8 +504,7 @@ extern const struct inode_operations logfs_reg_iops;
|
||||||
extern const struct file_operations logfs_reg_fops;
|
extern const struct file_operations logfs_reg_fops;
|
||||||
extern const struct address_space_operations logfs_reg_aops;
|
extern const struct address_space_operations logfs_reg_aops;
|
||||||
int logfs_readpage(struct file *file, struct page *page);
|
int logfs_readpage(struct file *file, struct page *page);
|
||||||
int logfs_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
|
long logfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||||
unsigned long arg);
|
|
||||||
int logfs_fsync(struct file *file, int datasync);
|
int logfs_fsync(struct file *file, int datasync);
|
||||||
|
|
||||||
/* gc.c */
|
/* gc.c */
|
||||||
|
|
|
@ -214,8 +214,7 @@ 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);
|
struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
|
||||||
long rv = -ENOTTY;
|
long rv = -ENOTTY;
|
||||||
long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
|
long (*ioctl)(struct file *, unsigned int, unsigned long);
|
||||||
int (*ioctl)(struct inode *, struct file *, unsigned int, unsigned long);
|
|
||||||
|
|
||||||
spin_lock(&pde->pde_unload_lock);
|
spin_lock(&pde->pde_unload_lock);
|
||||||
if (!pde->proc_fops) {
|
if (!pde->proc_fops) {
|
||||||
|
@ -223,19 +222,11 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
pde->pde_users++;
|
pde->pde_users++;
|
||||||
unlocked_ioctl = pde->proc_fops->unlocked_ioctl;
|
ioctl = pde->proc_fops->unlocked_ioctl;
|
||||||
ioctl = pde->proc_fops->ioctl;
|
|
||||||
spin_unlock(&pde->pde_unload_lock);
|
spin_unlock(&pde->pde_unload_lock);
|
||||||
|
|
||||||
if (unlocked_ioctl) {
|
if (ioctl)
|
||||||
rv = unlocked_ioctl(file, cmd, arg);
|
rv = 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
pde_users_dec(pde);
|
pde_users_dec(pde);
|
||||||
return rv;
|
return rv;
|
||||||
|
|
|
@ -1483,8 +1483,8 @@ struct block_device_operations;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* read, write, poll, fsync, readv, writev, unlocked_ioctl and compat_ioctl
|
* all file operations except setlease can be called without
|
||||||
* can be called without the big kernel lock held in all filesystems.
|
* the big kernel lock held in all filesystems.
|
||||||
*/
|
*/
|
||||||
struct file_operations {
|
struct file_operations {
|
||||||
struct module *owner;
|
struct module *owner;
|
||||||
|
@ -1495,7 +1495,6 @@ struct file_operations {
|
||||||
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
|
||||||
int (*readdir) (struct file *, void *, filldir_t);
|
int (*readdir) (struct file *, void *, filldir_t);
|
||||||
unsigned int (*poll) (struct file *, struct poll_table_struct *);
|
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 (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
|
||||||
int (*mmap) (struct file *, struct vm_area_struct *);
|
int (*mmap) (struct file *, struct vm_area_struct *);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче