diff -urNp --exclude CVS --exclude BitKeeper --exclude {arch} --exclude .arch-ids x-ref/mm/mremap.c x/mm/mremap.c --- x-ref/mm/mremap.c 2004-02-21 18:12:06.723850824 +0100 +++ x/mm/mremap.c 2004-02-21 18:12:50.319223320 +0100 @@ -279,6 +279,13 @@ unsigned long do_mremap(unsigned long ad if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len) goto out; + /* + * Allow new_len == 0 only if new_addr == addr + * to preserve truncation in place (that was working + * safe and some app may depend on it). + */ + if (unlikely(!new_len && new_addr != addr)) + goto out; /* Check if the location we're moving into overlaps the * old location at all, and fail if it does. @@ -289,7 +296,9 @@ unsigned long do_mremap(unsigned long ad if ((addr <= new_addr) && (addr+old_len) > new_addr) goto out; - do_munmap(current->mm, new_addr, new_len); + ret = do_munmap(current->mm, new_addr, new_len); + if (ret && new_len) + goto out; } /* @@ -298,7 +307,10 @@ unsigned long do_mremap(unsigned long ad */ ret = addr; if (old_len >= new_len) { - do_munmap(current->mm, addr+new_len, old_len - new_len); + ret = do_munmap(current->mm, addr+new_len, old_len - new_len); + if (ret && old_len != new_len) + goto out; + ret = addr; if (!(flags & MREMAP_FIXED) || (new_addr == addr)) goto out; }