On Wed, 28 Mar 2001, Carsten Langgaard wrote: > Have the kernel fix made it into the CVS. > If not, could you please resent it. I do not consider it clean enough for inclusion into the official kernel at this stage. It works, though. When appropriately cleaned up, I'll submit it to Linus as it's not MIPS-specific and affects all systems -- mmap() fails equally badly on an i386, for example. No time to work on the patch at the moment, sorry. -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + patch-2.4.0-test4-mmap-3 diff -u --recursive --new-file linux-2.4.0-test4.macro/mm/mmap.c linux-2.4.0-test4/mm/mmap.c --- linux-2.4.0-test4.macro/mm/mmap.c Sun Jul 16 22:27:29 2000 +++ linux-2.4.0-test4/mm/mmap.c Tue Jul 25 05:06:21 2000 @@ -175,7 +175,7 @@ if ((len = PAGE_ALIGN(len)) == 0) return addr; - if (len > TASK_SIZE || addr > TASK_SIZE-len) + if (len > TASK_SIZE || ((flags & MAP_FIXED) && (addr > TASK_SIZE - len))) return -EINVAL; /* offset overflow? */ @@ -356,20 +356,31 @@ unsigned long get_unmapped_area(unsigned long addr, unsigned long len) { struct vm_area_struct * vmm; + int pass = 0; if (len > TASK_SIZE) return 0; - if (!addr) - addr = TASK_UNMAPPED_BASE; - addr = PAGE_ALIGN(addr); - - for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { - /* At this point: (!vmm || addr < vmm->vm_end). */ - if (TASK_SIZE - len < addr) - return 0; - if (!vmm || addr + len <= vmm->vm_start) - return addr; - addr = vmm->vm_end; + + while (1) { + if (!addr) + addr = TASK_UNMAPPED_BASE; + addr = PAGE_ALIGN(addr); + + for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { + /* At this point: (!vmm || addr < vmm->vm_end). */ + if (TASK_SIZE - len < addr) { + if (pass > 0) + return 0; + else { + pass = 1; + addr = 0; + break; + } + } + if (!vmm || addr + len <= vmm->vm_start) + return addr; + addr = vmm->vm_end; + } } } #endif