From 05bca1c0842ecd3168657ba1a8fe0d3e3f794811 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 May 2005 22:43:37 -0700 Subject: [PATCH] --- yaml --- r: 1275 b: refs/heads/master c: 07ab67c8d0d7c1021343b7d5c045033d6bf7be69 h: refs/heads/master i: 1273: 844ce8fe91d31d2e9f7656ba11ce78ef578235e4 1271: 79ed23a41b1e39518563e64835cf2b4e0cb26c11 v: v3 --- [refs] | 2 +- trunk/include/linux/err.h | 4 ++- trunk/mm/mmap.c | 59 ++++++++++++++++++++------------------- 3 files changed, 35 insertions(+), 30 deletions(-) diff --git a/[refs] b/[refs] index 947d34330840..e85ab324cd6d 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 66e60f92518268f4d2a702a1c4ffbe1caacd6290 +refs/heads/master: 07ab67c8d0d7c1021343b7d5c045033d6bf7be69 diff --git a/trunk/include/linux/err.h b/trunk/include/linux/err.h index 17c55df13615..ff71d2af5da3 100644 --- a/trunk/include/linux/err.h +++ b/trunk/include/linux/err.h @@ -13,6 +13,8 @@ * This should be a per-architecture thing, to allow different * error and pointer decisions. */ +#define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L) + static inline void *ERR_PTR(long error) { return (void *) error; @@ -25,7 +27,7 @@ static inline long PTR_ERR(const void *ptr) static inline long IS_ERR(const void *ptr) { - return unlikely((unsigned long)ptr > (unsigned long)-1000L); + return IS_ERR_VALUE((unsigned long)ptr); } #endif /* _LINUX_ERR_H */ diff --git a/trunk/mm/mmap.c b/trunk/mm/mmap.c index 63df2d698414..de54acd9942f 100644 --- a/trunk/mm/mmap.c +++ b/trunk/mm/mmap.c @@ -1302,37 +1302,40 @@ unsigned long get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { - if (flags & MAP_FIXED) { - unsigned long ret; + unsigned long ret; - if (addr > TASK_SIZE - len) - return -ENOMEM; - if (addr & ~PAGE_MASK) - return -EINVAL; - if (file && is_file_hugepages(file)) { - /* - * Check if the given range is hugepage aligned, and - * can be made suitable for hugepages. - */ - ret = prepare_hugepage_range(addr, len); - } else { - /* - * Ensure that a normal request is not falling in a - * reserved hugepage range. For some archs like IA-64, - * there is a separate region for hugepages. - */ - ret = is_hugepage_only_range(current->mm, addr, len); - } - if (ret) - return -EINVAL; - return addr; - } + if (!(flags & MAP_FIXED)) { + unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - if (file && file->f_op && file->f_op->get_unmapped_area) - return file->f_op->get_unmapped_area(file, addr, len, - pgoff, flags); + get_area = current->mm->get_unmapped_area; + if (file && file->f_op && file->f_op->get_unmapped_area) + get_area = file->f_op->get_unmapped_area; + addr = get_area(file, addr, len, pgoff, flags); + if (IS_ERR_VALUE(addr)) + return addr; + } - return current->mm->get_unmapped_area(file, addr, len, pgoff, flags); + if (addr > TASK_SIZE - len) + return -ENOMEM; + if (addr & ~PAGE_MASK) + return -EINVAL; + if (file && is_file_hugepages(file)) { + /* + * Check if the given range is hugepage aligned, and + * can be made suitable for hugepages. + */ + ret = prepare_hugepage_range(addr, len); + } else { + /* + * Ensure that a normal request is not falling in a + * reserved hugepage range. For some archs like IA-64, + * there is a separate region for hugepages. + */ + ret = is_hugepage_only_range(current->mm, addr, len); + } + if (ret) + return -EINVAL; + return addr; } EXPORT_SYMBOL(get_unmapped_area);