patch-2.0.19 linux/mm/mmap.c
Next file: linux/mm/mprotect.c
Previous file: linux/mm/mlock.c
Back to the patch index
Back to the overall index
- Lines: 218
- Date:
Mon Sep 9 21:04:57 1996
- Orig file:
v2.0.18/linux/mm/mmap.c
- Orig date:
Sun Sep 8 19:50:22 1996
diff -u --recursive --new-file v2.0.18/linux/mm/mmap.c linux/mm/mmap.c
@@ -66,19 +66,20 @@
{
unsigned long rlim;
unsigned long newbrk, oldbrk;
+ struct mm_struct *mm = current->mm;
- if (brk < current->mm->end_code)
- return current->mm->brk;
+ if (brk < mm->end_code)
+ return mm->brk;
newbrk = PAGE_ALIGN(brk);
- oldbrk = PAGE_ALIGN(current->mm->brk);
+ oldbrk = PAGE_ALIGN(mm->brk);
if (oldbrk == newbrk)
- return current->mm->brk = brk;
+ return mm->brk = brk;
/*
* Always allow shrinking brk
*/
- if (brk <= current->mm->brk) {
- current->mm->brk = brk;
+ if (brk <= mm->brk) {
+ mm->brk = brk;
do_munmap(newbrk, oldbrk-newbrk);
return brk;
}
@@ -88,25 +89,25 @@
rlim = current->rlim[RLIMIT_DATA].rlim_cur;
if (rlim >= RLIM_INFINITY)
rlim = ~0;
- if (brk - current->mm->end_code > rlim)
- return current->mm->brk;
+ if (brk - mm->end_code > rlim)
+ return mm->brk;
/*
* Check against existing mmap mappings.
*/
- if (find_vma_intersection(current, oldbrk, newbrk+PAGE_SIZE))
- return current->mm->brk;
+ if (find_vma_intersection(mm, oldbrk, newbrk+PAGE_SIZE))
+ return mm->brk;
/*
* Check if we have enough memory..
*/
if (!vm_enough_memory((newbrk-oldbrk) >> PAGE_SHIFT))
- return current->mm->brk;
+ return mm->brk;
/*
* Ok, looks good - let it rip.
*/
- current->mm->brk = brk;
+ mm->brk = brk;
do_mmap(NULL, oldbrk, newbrk-oldbrk,
PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_FIXED|MAP_PRIVATE, 0);
@@ -139,6 +140,7 @@
unsigned long do_mmap(struct file * file, unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long off)
{
+ struct mm_struct * mm = current->mm;
struct vm_area_struct * vma;
if ((len = PAGE_ALIGN(len)) == 0)
@@ -152,8 +154,8 @@
return -EINVAL;
/* mlock MCL_FUTURE? */
- if (current->mm->def_flags & VM_LOCKED) {
- unsigned long locked = current->mm->locked_vm << PAGE_SHIFT;
+ if (mm->def_flags & VM_LOCKED) {
+ unsigned long locked = mm->locked_vm << PAGE_SHIFT;
locked += len;
if (locked > current->rlim[RLIMIT_MEMLOCK].rlim_cur)
return -EAGAIN;
@@ -218,10 +220,10 @@
if (!vma)
return -ENOMEM;
- vma->vm_mm = current->mm;
+ vma->vm_mm = mm;
vma->vm_start = addr;
vma->vm_end = addr + len;
- vma->vm_flags = vm_flags(prot,flags) | current->mm->def_flags;
+ vma->vm_flags = vm_flags(prot,flags) | mm->def_flags;
if (file) {
if (file->f_mode & 1)
@@ -269,14 +271,14 @@
}
flags = vma->vm_flags;
- insert_vm_struct(current, vma);
- merge_segments(current, vma->vm_start, vma->vm_end);
+ insert_vm_struct(mm, vma);
+ merge_segments(mm, vma->vm_start, vma->vm_end);
/* merge_segments might have merged our vma, so we can't use it any more */
- current->mm->total_vm += len >> PAGE_SHIFT;
+ mm->total_vm += len >> PAGE_SHIFT;
if (flags & VM_LOCKED) {
unsigned long start = addr;
- current->mm->locked_vm += len >> PAGE_SHIFT;
+ mm->locked_vm += len >> PAGE_SHIFT;
do {
char c = get_user((char *) start);
len -= PAGE_SIZE;
@@ -302,7 +304,7 @@
addr = TASK_SIZE / 3;
addr = PAGE_ALIGN(addr);
- for (vmm = find_vma(current, addr); ; vmm = vmm->vm_next) {
+ 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;
@@ -752,7 +754,7 @@
if (mpnt->vm_ops && mpnt->vm_ops->open)
mpnt->vm_ops->open(mpnt);
area->vm_end = addr; /* Truncate area */
- insert_vm_struct(current, mpnt);
+ insert_vm_struct(current->mm, mpnt);
}
/* construct whatever mapping is needed */
@@ -766,7 +768,7 @@
area->vm_end = area->vm_start;
area->vm_ops->close(area);
}
- insert_vm_struct(current, mpnt);
+ insert_vm_struct(current->mm, mpnt);
}
asmlinkage int sys_munmap(unsigned long addr, size_t len)
@@ -796,7 +798,7 @@
* every area affected in some way (by any overlap) is put
* on the list. If nothing is put on, nothing is affected.
*/
- mpnt = find_vma(current, addr);
+ mpnt = find_vma(current->mm, addr);
if (!mpnt)
return 0;
avl_neighbours(mpnt, current->mm->mmap_avl, &prev, &next);
@@ -887,7 +889,7 @@
* Insert vm structure into process list sorted by address
* and into the inode's i_mmap ring.
*/
-void insert_vm_struct(struct task_struct *t, struct vm_area_struct *vmp)
+void insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vmp)
{
struct vm_area_struct *share;
struct inode * inode;
@@ -895,7 +897,7 @@
#if 0 /* equivalent, but slow */
struct vm_area_struct **p, *mpnt;
- p = &t->mm->mmap;
+ p = &mm->mmap;
while ((mpnt = *p) != NULL) {
if (mpnt->vm_start > vmp->vm_start)
break;
@@ -908,13 +910,13 @@
#else
struct vm_area_struct * prev, * next;
- avl_insert_neighbours(vmp, &t->mm->mmap_avl, &prev, &next);
- if ((prev ? prev->vm_next : t->mm->mmap) != next)
+ avl_insert_neighbours(vmp, &mm->mmap_avl, &prev, &next);
+ if ((prev ? prev->vm_next : mm->mmap) != next)
printk("insert_vm_struct: tree inconsistent with list\n");
if (prev)
prev->vm_next = vmp;
else
- t->mm->mmap = vmp;
+ mm->mmap = vmp;
vmp->vm_next = next;
#endif
@@ -963,14 +965,16 @@
* We don't need to traverse the entire list, only those segments
* which intersect or are adjacent to a given interval.
*/
-void merge_segments (struct task_struct * task, unsigned long start_addr, unsigned long end_addr)
+void merge_segments (struct mm_struct * mm, unsigned long start_addr, unsigned long end_addr)
{
struct vm_area_struct *prev, *mpnt, *next;
- mpnt = find_vma(task, start_addr);
+ down(&mm->mmap_sem);
+ mpnt = find_vma(mm, start_addr);
if (!mpnt)
- return;
- avl_neighbours(mpnt, task->mm->mmap_avl, &prev, &next);
+ goto no_vma;
+
+ avl_neighbours(mpnt, mm->mmap_avl, &prev, &next);
/* we have prev->vm_next == mpnt && mpnt->vm_next = next */
if (!prev) {
@@ -1014,7 +1018,7 @@
* big segment can possibly merge with the next one.
* The old unused mpnt is freed.
*/
- avl_remove(mpnt, &task->mm->mmap_avl);
+ avl_remove(mpnt, &mm->mmap_avl);
prev->vm_end = mpnt->vm_end;
prev->vm_next = mpnt->vm_next;
if (mpnt->vm_ops && mpnt->vm_ops->close) {
@@ -1028,4 +1032,6 @@
kfree_s(mpnt, sizeof(*mpnt));
mpnt = prev;
}
+no_vma:
+ up(&mm->mmap_sem);
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov