Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

Al Viro c4caa778 0ec62d29

+24 -17
+7 -3
arch/sparc/kernel/sys_sparc_64.c
··· 317 317 unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, unsigned long len, unsigned long pgoff, unsigned long flags) 318 318 { 319 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 325 if (flags & MAP_FIXED) { 322 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 329 flags &= ~MAP_SHARED; 326 330 ··· 337 333 align_goal = (64UL * 1024); 338 334 339 335 do { 340 - addr = get_unmapped_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); 336 + addr = get_area(NULL, orig_addr, len + (align_goal - PAGE_SIZE), pgoff, flags); 341 337 if (!(addr & ~PAGE_MASK)) { 342 338 addr = (addr + (align_goal - 1UL)) & ~(align_goal - 1UL); 343 339 break; ··· 355 351 * be obtained. 356 352 */ 357 353 if (addr & ~PAGE_MASK) 358 - addr = get_unmapped_area(NULL, orig_addr, len, pgoff, flags); 354 + addr = get_area(NULL, orig_addr, len, pgoff, flags); 359 355 360 356 return addr; 361 357 }
+17 -14
ipc/shm.c
··· 290 290 unsigned long flags) 291 291 { 292 292 struct shm_file_data *sfd = shm_file_data(file); 293 - return get_unmapped_area(sfd->file, addr, len, pgoff, flags); 294 - } 295 - 296 - int 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; 293 + return sfd->file->f_op->get_unmapped_area(sfd->file, addr, len, 294 + pgoff, flags); 306 295 } 307 296 308 297 static const struct file_operations shm_file_operations = { 309 298 .mmap = shm_mmap, 310 299 .fsync = shm_fsync, 311 300 .release = shm_release, 301 + }; 302 + 303 + static const struct file_operations shm_file_operations_huge = { 304 + .mmap = shm_mmap, 305 + .fsync = shm_fsync, 306 + .release = shm_release, 312 307 .get_unmapped_area = shm_get_unmapped_area, 313 308 }; 309 + 310 + int is_file_shm_hugepages(struct file *file) 311 + { 312 + return file->f_op == &shm_file_operations_huge; 313 + } 314 314 315 315 static const struct vm_operations_struct shm_vm_ops = { 316 316 .open = shm_open, /* callback for a new vm-area open */ ··· 889 889 if (!sfd) 890 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 896 if (!file) 894 897 goto out_free; 895 898 ima_counts_get(file);