Merge branch 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs open-related updates from Al Viro: - "do we need fput() or put_filp()" rules are gone - it's always fput() now. We keep track of that state where it belongs - in ->f_mode. - int *opened mess killed - in finish_open(), in ->atomic_open() instances and in fs/namei.c code around do_last()/lookup_open()/atomic_open(). - alloc_file() wrappers with saner calling conventions are introduced (alloc_file_clone() and alloc_file_pseudo()); callers converted, with much simplification. - while we are at it, saner calling conventions for path_init() and link_path_walk(), simplifying things inside fs/namei.c (both on open-related paths and elsewhere). * 'work.open3' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits) few more cleanups of link_path_walk() callers allow link_path_walk() to take ERR_PTR() make path_init() unconditionally paired with terminate_walk() document alloc_file() changes make alloc_file() static do_shmat(): grab shp->shm_file earlier, switch to alloc_file_clone() new helper: alloc_file_clone() create_pipe_files(): switch the first allocation to alloc_file_pseudo() anon_inode_getfile(): switch to alloc_file_pseudo() hugetlb_file_setup(): switch to alloc_file_pseudo() ocxlflash_getfile(): switch to alloc_file_pseudo() cxl_getfile(): switch to alloc_file_pseudo() ... and switch shmem_file_setup() to alloc_file_pseudo() __shmem_file_setup(): reorder allocations new wrapper: alloc_file_pseudo() kill FILE_{CREATED,OPENED} switch atomic_open() and lookup_open() to returning 0 in all success cases document ->atomic_open() changes ->atomic_open(): return 0 in all success cases get rid of 'opened' in path_openat() and the helpers downstream ...
This commit is contained in:
67
ipc/shm.c
67
ipc/shm.c
@@ -1366,15 +1366,14 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
|
||||
struct shmid_kernel *shp;
|
||||
unsigned long addr = (unsigned long)shmaddr;
|
||||
unsigned long size;
|
||||
struct file *file;
|
||||
struct file *file, *base;
|
||||
int err;
|
||||
unsigned long flags = MAP_SHARED;
|
||||
unsigned long prot;
|
||||
int acc_mode;
|
||||
struct ipc_namespace *ns;
|
||||
struct shm_file_data *sfd;
|
||||
struct path path;
|
||||
fmode_t f_mode;
|
||||
int f_flags;
|
||||
unsigned long populate = 0;
|
||||
|
||||
err = -EINVAL;
|
||||
@@ -1407,11 +1406,11 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
|
||||
if (shmflg & SHM_RDONLY) {
|
||||
prot = PROT_READ;
|
||||
acc_mode = S_IRUGO;
|
||||
f_mode = FMODE_READ;
|
||||
f_flags = O_RDONLY;
|
||||
} else {
|
||||
prot = PROT_READ | PROT_WRITE;
|
||||
acc_mode = S_IRUGO | S_IWUGO;
|
||||
f_mode = FMODE_READ | FMODE_WRITE;
|
||||
f_flags = O_RDWR;
|
||||
}
|
||||
if (shmflg & SHM_EXEC) {
|
||||
prot |= PROT_EXEC;
|
||||
@@ -1447,35 +1446,6 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
path = shp->shm_file->f_path;
|
||||
path_get(&path);
|
||||
shp->shm_nattch++;
|
||||
size = i_size_read(d_inode(path.dentry));
|
||||
ipc_unlock_object(&shp->shm_perm);
|
||||
rcu_read_unlock();
|
||||
|
||||
err = -ENOMEM;
|
||||
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
|
||||
if (!sfd) {
|
||||
path_put(&path);
|
||||
goto out_nattch;
|
||||
}
|
||||
|
||||
file = alloc_file(&path, f_mode,
|
||||
is_file_hugepages(shp->shm_file) ?
|
||||
&shm_file_operations_huge :
|
||||
&shm_file_operations);
|
||||
err = PTR_ERR(file);
|
||||
if (IS_ERR(file)) {
|
||||
kfree(sfd);
|
||||
path_put(&path);
|
||||
goto out_nattch;
|
||||
}
|
||||
|
||||
file->private_data = sfd;
|
||||
file->f_mapping = shp->shm_file->f_mapping;
|
||||
sfd->id = shp->shm_perm.id;
|
||||
sfd->ns = get_ipc_ns(ns);
|
||||
/*
|
||||
* We need to take a reference to the real shm file to prevent the
|
||||
* pointer from becoming stale in cases where the lifetime of the outer
|
||||
@@ -1485,8 +1455,35 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg,
|
||||
* We'll deny the ->mmap() if the shm segment was since removed, but to
|
||||
* detect shm ID reuse we need to compare the file pointers.
|
||||
*/
|
||||
sfd->file = get_file(shp->shm_file);
|
||||
base = get_file(shp->shm_file);
|
||||
shp->shm_nattch++;
|
||||
size = i_size_read(file_inode(base));
|
||||
ipc_unlock_object(&shp->shm_perm);
|
||||
rcu_read_unlock();
|
||||
|
||||
err = -ENOMEM;
|
||||
sfd = kzalloc(sizeof(*sfd), GFP_KERNEL);
|
||||
if (!sfd) {
|
||||
fput(base);
|
||||
goto out_nattch;
|
||||
}
|
||||
|
||||
file = alloc_file_clone(base, f_flags,
|
||||
is_file_hugepages(base) ?
|
||||
&shm_file_operations_huge :
|
||||
&shm_file_operations);
|
||||
err = PTR_ERR(file);
|
||||
if (IS_ERR(file)) {
|
||||
kfree(sfd);
|
||||
fput(base);
|
||||
goto out_nattch;
|
||||
}
|
||||
|
||||
sfd->id = shp->shm_perm.id;
|
||||
sfd->ns = get_ipc_ns(ns);
|
||||
sfd->file = base;
|
||||
sfd->vm_ops = NULL;
|
||||
file->private_data = sfd;
|
||||
|
||||
err = security_mmap_file(file, prot, flags);
|
||||
if (err)
|
||||
|
Reference in New Issue
Block a user