提交 c4caa778 编写于 作者: A Al Viro

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: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 0ec62d29
...@@ -317,10 +317,14 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, ...@@ -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 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 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) { if (flags & MAP_FIXED) {
/* Ok, don't mess with it. */ /* 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; flags &= ~MAP_SHARED;
...@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u ...@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
align_goal = (64UL * 1024); align_goal = (64UL * 1024);
do { 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)) { if (!(addr & ~PAGE_MASK)) {
addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
break; break;
...@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u ...@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
* be obtained. * be obtained.
*/ */
if (addr & ~PAGE_MASK) 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; return addr;
} }
......
...@@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file, ...@@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file,
unsigned long flags) unsigned long flags)
{ {
struct shm_file_data *sfd = shm_file_data(file); struct shm_file_data *sfd = shm_file_data(file);
return get_unmapped_area(sfd->file, addr, len, pgoff, flags); return sfd->file->f_op->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;
} }
static const struct file_operations shm_file_operations = { static const struct file_operations shm_file_operations = {
.mmap = shm_mmap, .mmap = shm_mmap,
.fsync = shm_fsync, .fsync = shm_fsync,
.release = shm_release, .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, .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 = { static const struct vm_operations_struct shm_vm_ops = {
.open = shm_open, /* callback for a new vm-area open */ .open = shm_open, /* callback for a new vm-area open */
.close = shm_close, /* callback for when the vm-area is released */ .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) ...@@ -889,7 +889,10 @@ long do_shmat(int shmid, char __user *shmaddr, int shmflg, ulong *raddr)
if (!sfd) if (!sfd)
goto out_put_dentry; 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) if (!file)
goto out_free; goto out_free;
ima_counts_get(file); ima_counts_get(file);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册