file ->get_unmapped_area() shouldn't duplicate work of get_unmapped_area()
... we should call mm ->get_unmapped_area() instead and let our caller do the final checks. Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
0ec62d2909
commit
c4caa77815
2 changed files with 24 additions and 17 deletions
|
@ -317,10 +317,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
|
|||
unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
|
||||
{
|
||||
unsigned long align_goal, addr = -ENOMEM;
|
||||
unsigned long (*get_area)(struct file *, unsigned long,
|
||||
unsigned long, unsigned long, unsigned long);
|
||||
|
||||
get_area = current->mm->get_unmapped_area;
|
||||
|
||||
if (flags & MAP_FIXED) {
|
||||
/* Ok, don't mess with it. */
|
||||
return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
|
||||
return get_area(NULL, orig_addr, len, pgoff, flags);
|
||||
}
|
||||
flags &= ~MAP_SHARED;
|
||||
|
||||
|
@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
|
|||
align_goal = (64UL * 1024);
|
||||
|
||||
do {
|
||||
addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
|
||||
addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
|
||||
if (!(addr & ~PAGE_MASK)) {
|
||||
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
|
||||
break;
|
||||
|
@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
|
|||
* be obtained.
|
||||
*/
|
||||
if (addr & ~PAGE_MASK)
|
||||
addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
|
||||
addr = get_area(NULL, orig_addr, len, pgoff, flags);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
|
31
ipc/shm.c
31
ipc/shm.c
|
@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file,
|
|||
unsigned long flags)
|
||||
{
|
||||
struct shm_file_data *sfd = shm_file_data(file);
|
||||
return get_unmapped_area(sfd->file, addr, len, pgoff, flags);
|
||||
}
|
||||
|
||||
int is_file_shm_hugepages(struct file *file)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (file->f_op == &shm_file_operations) {
|
||||
struct shm_file_data *sfd;
|
||||
sfd = shm_file_data(file);
|
||||
ret = is_file_hugepages(sfd->file);
|
||||
}
|
||||
return ret;
|
||||
return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
|
||||
pgoff, flags);
|
||||
}
|
||||
|
||||
static const struct file_operations shm_file_operations = {
|
||||
.mmap = shm_mmap,
|
||||
.fsync = shm_fsync,
|
||||
.release = shm_release,
|
||||
};
|
||||
|
||||
static const struct file_operations shm_file_operations_huge = {
|
||||
.mmap = shm_mmap,
|
||||
.fsync = shm_fsync,
|
||||
.release = shm_release,
|
||||
.get_unmapped_area = shm_get_unmapped_area,
|
||||
};
|
||||
|
||||
int is_file_shm_hugepages(struct file *file)
|
||||
{
|
||||
return file->f_op == &shm_file_operations_huge;
|
||||
}
|
||||
|
||||
static const struct vm_operations_struct shm_vm_ops = {
|
||||
.open = shm_open, /* callback for a new vm-area open */
|
||||
.close = shm_close, /* callback for when the vm-area is released */
|
||||
|
@ -889,7 +889,10 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
|
|||
if (!sfd)
|
||||
goto out_put_dentry;
|
||||
|
||||
file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations);
|
||||
file = alloc_file(path.mnt, path.dentry, f_mode,
|
||||
is_file_hugepages(shp->shm_file) ?
|
||||
&shm_file_operations_huge :
|
||||
&shm_file_operations);
|
||||
if (!file)
|
||||
goto out_free;
|
||||
ima_counts_get(file);
|
||||
|
|
Loading…
Reference in a new issue