aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2009-11-30 08:38:43 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2009-12-11 06:34:09 -0500
commitc4caa778157dbbf04116f0ac2111e389b5cd7a29 (patch)
treed8e26c07bacaaa6b1e6b1e57816fd42da94e15f4
parent0ec62d290912bb4b989be7563851bc364ec73b56 (diff)
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>
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c10
-rw-r--r--ipc/shm.c31
2 files changed, 24 insertions, 17 deletions
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index ddda12fcbac2..d498b32c75f6 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -317,10 +317,14 @@ bottomup:
317unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) 317unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags)
318{ 318{
319 unsigned long align_goal, addr = -ENOMEM; 319 unsigned long align_goal, addr = -ENOMEM;
320 unsigned long (*get_area)(struct file *, unsigned long,
321 unsigned long, unsigned long, unsigned long);
322
323 get_area = current->mm->get_unmapped_area;
320 324
321 if (flags & MAP_FIXED) { 325 if (flags & MAP_FIXED) {
322 /* Ok, don't mess with it. */ 326 /* Ok, don't mess with it. */
323 return get_unmapped_area(NULL, orig_addr, len, pgoff, flags); 327 return get_area(NULL, orig_addr, len, pgoff, flags);
324 } 328 }
325 flags &= ~MAP_SHARED; 329 flags &= ~MAP_SHARED;
326 330
@@ -333,7 +337,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
333 align_goal = (64UL * 1024); 337 align_goal = (64UL * 1024);
334 338
335 do { 339 do {
336 addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); 340 addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags);
337 if (!(addr & ~PAGE_MASK)) { 341 if (!(addr & ~PAGE_MASK)) {
338 addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); 342 addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL);
339 break; 343 break;
@@ -351,7 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
351 * be obtained. 355 * be obtained.
352 */ 356 */
353 if (addr & ~PAGE_MASK) 357 if (addr & ~PAGE_MASK)
354 addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); 358 addr = get_area(NULL, orig_addr, len, pgoff, flags);
355 359
356 return addr; 360 return addr;
357} 361}
diff --git a/ipc/shm.c b/ipc/shm.c
index 464694e0aa4a..11bec626c228 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -290,28 +290,28 @@ static unsigned long shm_get_unmapped_area(struct file *file,
290 unsigned long flags) 290 unsigned long flags)
291{ 291{
292 struct shm_file_data *sfd = shm_file_data(file); 292 struct shm_file_data *sfd = shm_file_data(file);
293 return get_unmapped_area(sfd->file, addr, len, pgoff, flags); 293 return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len,
294} 294 pgoff, flags);
295
296int is_file_shm_hugepages(struct file *file)
297{
298 int ret = 0;
299
300 if (file->f_op == &shm_file_operations) {
301 struct shm_file_data *sfd;
302 sfd = shm_file_data(file);
303 ret = is_file_hugepages(sfd->file);
304 }
305 return ret;
306} 295}
307 296
308static const struct file_operations shm_file_operations = { 297static const struct file_operations shm_file_operations = {
309 .mmap = shm_mmap, 298 .mmap = shm_mmap,
310 .fsync = shm_fsync, 299 .fsync = shm_fsync,
311 .release = shm_release, 300 .release = shm_release,
301};
302
303static const struct file_operations shm_file_operations_huge = {
304 .mmap = shm_mmap,
305 .fsync = shm_fsync,
306 .release = shm_release,
312 .get_unmapped_area = shm_get_unmapped_area, 307 .get_unmapped_area = shm_get_unmapped_area,
313}; 308};
314 309
310int is_file_shm_hugepages(struct file *file)
311{
312 return file->f_op == &shm_file_operations_huge;
313}
314
315static const struct vm_operations_struct shm_vm_ops = { 315static const struct vm_operations_struct shm_vm_ops = {
316 .open = shm_open, /* callback for a new vm-area open */ 316 .open = shm_open, /* callback for a new vm-area open */
317 .close = shm_close, /* callback for when the vm-area is released */ 317 .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 if (!sfd) 889 if (!sfd)
890 goto out_put_dentry; 890 goto out_put_dentry;
891 891
892 file = alloc_file(path.mnt, path.dentry, f_mode, &shm_file_operations); 892 file = alloc_file(path.mnt, path.dentry, f_mode,
893 is_file_hugepages(shp->shm_file) ?
894 &shm_file_operations_huge :
895 &shm_file_operations);
893 if (!file) 896 if (!file)
894 goto out_free; 897 goto out_free;
895 ima_counts_get(file); 898 ima_counts_get(file);