mirror of
https://github.com/adulau/aha.git
synced 2024-12-05 00:17:23 +00:00
anonfd: Allow making anon files read-only
It seems a couple places such as arch/ia64/kernel/perfmon.c and drivers/infiniband/core/uverbs_main.c could use anon_inode_getfile() instead of a private pseudo-fs + alloc_file(), if only there were a way to get a read-only file. So provide this by having anon_inode_getfile() create a read-only file if we pass O_RDONLY in flags. Signed-off-by: Roland Dreier <rolandd@cisco.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
ed2617585f
commit
628ff7c1d8
7 changed files with 17 additions and 9 deletions
|
@ -89,11 +89,19 @@ struct file *anon_inode_getfile(const char *name,
|
|||
struct qstr this;
|
||||
struct path path;
|
||||
struct file *file;
|
||||
fmode_t mode;
|
||||
int error;
|
||||
|
||||
if (IS_ERR(anon_inode_inode))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
switch (flags & O_ACCMODE) {
|
||||
case O_RDONLY: mode = FMODE_READ; break;
|
||||
case O_WRONLY: mode = FMODE_WRITE; break;
|
||||
case O_RDWR: mode = FMODE_READ | FMODE_WRITE; break;
|
||||
default: return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (fops->owner && !try_module_get(fops->owner))
|
||||
return ERR_PTR(-ENOENT);
|
||||
|
||||
|
@ -121,13 +129,13 @@ struct file *anon_inode_getfile(const char *name,
|
|||
d_instantiate(path.dentry, anon_inode_inode);
|
||||
|
||||
error = -ENFILE;
|
||||
file = alloc_file(&path, FMODE_READ | FMODE_WRITE, fops);
|
||||
file = alloc_file(&path, mode, fops);
|
||||
if (!file)
|
||||
goto err_dput;
|
||||
file->f_mapping = anon_inode_inode->i_mapping;
|
||||
|
||||
file->f_pos = 0;
|
||||
file->f_flags = O_RDWR | (flags & O_NONBLOCK);
|
||||
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
|
||||
file->f_version = 0;
|
||||
file->private_data = priv;
|
||||
|
||||
|
|
|
@ -339,7 +339,7 @@ struct file *eventfd_file_create(unsigned int count, int flags)
|
|||
ctx->flags = flags;
|
||||
|
||||
file = anon_inode_getfile("[eventfd]", &eventfd_fops, ctx,
|
||||
flags & EFD_SHARED_FCNTL_FLAGS);
|
||||
O_RDWR | (flags & EFD_SHARED_FCNTL_FLAGS));
|
||||
if (IS_ERR(file))
|
||||
eventfd_free_ctx(ctx);
|
||||
|
||||
|
|
|
@ -1206,7 +1206,7 @@ SYSCALL_DEFINE1(epoll_create1, int, flags)
|
|||
* a file structure and a free file descriptor.
|
||||
*/
|
||||
error = anon_inode_getfd("[eventpoll]", &eventpoll_fops, ep,
|
||||
flags & O_CLOEXEC);
|
||||
O_RDWR | (flags & O_CLOEXEC));
|
||||
if (error < 0)
|
||||
ep_free(ep);
|
||||
|
||||
|
|
|
@ -236,7 +236,7 @@ SYSCALL_DEFINE4(signalfd4, int, ufd, sigset_t __user *, user_mask,
|
|||
* anon_inode_getfd() will install the fd.
|
||||
*/
|
||||
ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
|
||||
flags & (O_CLOEXEC | O_NONBLOCK));
|
||||
O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
|
||||
if (ufd < 0)
|
||||
kfree(ctx);
|
||||
} else {
|
||||
|
|
|
@ -200,7 +200,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
|
|||
hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
|
||||
|
||||
ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
|
||||
flags & TFD_SHARED_FCNTL_FLAGS);
|
||||
O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
|
||||
if (ufd < 0)
|
||||
kfree(ctx);
|
||||
|
||||
|
|
|
@ -4724,7 +4724,7 @@ SYSCALL_DEFINE5(perf_event_open,
|
|||
if (IS_ERR(event))
|
||||
goto err_put_context;
|
||||
|
||||
err = anon_inode_getfd("[perf_event]", &perf_fops, event, 0);
|
||||
err = anon_inode_getfd("[perf_event]", &perf_fops, event, O_RDWR);
|
||||
if (err < 0)
|
||||
goto err_free_put_context;
|
||||
|
||||
|
|
|
@ -1177,7 +1177,7 @@ static struct file_operations kvm_vcpu_fops = {
|
|||
*/
|
||||
static int create_vcpu_fd(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, 0);
|
||||
return anon_inode_getfd("kvm-vcpu", &kvm_vcpu_fops, vcpu, O_RDWR);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1638,7 +1638,7 @@ static int kvm_dev_ioctl_create_vm(void)
|
|||
kvm = kvm_create_vm();
|
||||
if (IS_ERR(kvm))
|
||||
return PTR_ERR(kvm);
|
||||
fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, 0);
|
||||
fd = anon_inode_getfd("kvm-vm", &kvm_vm_fops, kvm, O_RDWR);
|
||||
if (fd < 0)
|
||||
kvm_put_kvm(kvm);
|
||||
|
||||
|
|
Loading…
Reference in a new issue