patch-2.1.23 linux/mm/mremap.c
Next file: linux/mm/page_alloc.c
Previous file: linux/mm/mprotect.c
Back to the patch index
Back to the overall index
- Lines: 109
- Date:
Sun Jan 26 12:07:49 1997
- Orig file:
v2.1.22/linux/mm/mremap.c
- Orig date:
Thu Jan 2 15:55:26 1997
diff -u --recursive --new-file v2.1.22/linux/mm/mremap.c linux/mm/mremap.c
@@ -8,11 +8,13 @@
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
#include <linux/shm.h>
#include <linux/errno.h>
#include <linux/mman.h>
#include <linux/string.h>
-#include <linux/malloc.h>
+#include <linux/slab.h>
#include <linux/swap.h>
#include <asm/uaccess.h>
@@ -129,8 +131,7 @@
{
struct vm_area_struct * new_vma;
- new_vma = (struct vm_area_struct *)
- kmalloc(sizeof(struct vm_area_struct), GFP_KERNEL);
+ new_vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (new_vma) {
unsigned long new_addr = get_unmapped_area(addr, new_len);
@@ -149,7 +150,7 @@
current->mm->total_vm += new_len >> PAGE_SHIFT;
return new_addr;
}
- kfree(new_vma);
+ kmem_cache_free(vm_area_cachep, new_vma);
}
return -ENOMEM;
}
@@ -163,9 +164,11 @@
unsigned long flags)
{
struct vm_area_struct *vma;
+ unsigned long ret = -EINVAL;
+ lock_kernel();
if (addr & ~PAGE_MASK)
- return -EINVAL;
+ goto out;
old_len = PAGE_ALIGN(old_len);
new_len = PAGE_ALIGN(new_len);
@@ -173,29 +176,33 @@
* Always allow a shrinking remap: that just unmaps
* the unnecessary pages..
*/
+ ret = addr;
if (old_len > new_len) {
do_munmap(addr+new_len, old_len - new_len);
- return addr;
+ goto out;
}
/*
* Ok, we need to grow..
*/
+ ret = -EFAULT;
vma = find_vma(current->mm, addr);
if (!vma || vma->vm_start > addr)
- return -EFAULT;
+ goto out;
/* We can't remap across vm area boundaries */
if (old_len > vma->vm_end - addr)
- return -EFAULT;
+ goto out;
if (vma->vm_flags & VM_LOCKED) {
unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
locked += new_len - old_len;
+ ret = -EAGAIN;
if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
- return -EAGAIN;
+ goto out;
}
+ ret = -ENOMEM;
if ((current->mm->total_vm << PAGE_SHIFT) + (new_len - old_len)
> current->rlim[RLIMIT_AS].rlim_cur)
- return -ENOMEM;
+ goto out;
/* old_len exactly to the end of the area.. */
if (old_len == vma->vm_end - addr &&
@@ -210,7 +217,8 @@
current->mm->total_vm += pages;
if (vma->vm_flags & VM_LOCKED)
current->mm->locked_vm += pages;
- return addr;
+ ret = addr;
+ goto out;
}
}
@@ -219,6 +227,10 @@
* we need to create a new one and move it..
*/
if (flags & MREMAP_MAYMOVE)
- return move_vma(vma, addr, old_len, new_len);
- return -ENOMEM;
+ ret = move_vma(vma, addr, old_len, new_len);
+ else
+ ret = -ENOMEM;
+out:
+ unlock_kernel();
+ return ret;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov