patch-2.1.61 linux/mm/mmap.c
Next file: linux/mm/swap_state.c
Previous file: linux/include/linux/smb_fs_sb.h
Back to the patch index
Back to the overall index
- Lines: 141
- Date:
Thu Oct 30 10:49:33 1997
- Orig file:
v2.1.60/linux/mm/mmap.c
- Orig date:
Tue Sep 23 16:48:50 1997
diff -u --recursive --new-file v2.1.60/linux/mm/mmap.c linux/mm/mmap.c
@@ -92,25 +92,21 @@
struct mm_struct *mm = current->mm;
lock_kernel();
- retval = mm->brk;
if (brk < mm->end_code)
goto out;
newbrk = PAGE_ALIGN(brk);
oldbrk = PAGE_ALIGN(mm->brk);
- if (oldbrk == newbrk) {
- retval = mm->brk = brk;
- goto out;
- }
+ if (oldbrk == newbrk)
+ goto set_brk;
/* Always allow shrinking brk. */
if (brk <= mm->brk) {
- retval = mm->brk = brk;
- do_munmap(newbrk, oldbrk-newbrk);
+ if (!do_munmap(newbrk, oldbrk-newbrk))
+ goto set_brk;
goto out;
}
/* Check against rlimit and stack.. */
- retval = mm->brk;
rlim = current->rlim[RLIMIT_DATA].rlim_cur;
if (rlim >= RLIM_INFINITY)
rlim = ~0;
@@ -126,12 +122,14 @@
goto out;
/* Ok, looks good - let it rip. */
- if(do_mmap(NULL, oldbrk, newbrk-oldbrk,
+ if (do_mmap(NULL, oldbrk, newbrk-oldbrk,
PROT_READ|PROT_WRITE|PROT_EXEC,
- MAP_FIXED|MAP_PRIVATE, 0) == oldbrk)
- mm->brk = brk;
- retval = mm->brk;
+ MAP_FIXED|MAP_PRIVATE, 0) != oldbrk)
+ goto out;
+set_brk:
+ mm->brk = brk;
out:
+ retval = mm->brk;
unlock_kernel();
return retval;
}
@@ -163,7 +161,7 @@
{
struct mm_struct * mm = current->mm;
struct vm_area_struct * vma;
- int correct_wcount = 0;
+ int correct_wcount = 0, error;
if ((len = PAGE_ALIGN(len)) == 0)
return addr;
@@ -262,26 +260,24 @@
vma->vm_dentry = NULL;
vma->vm_pte = 0;
- do_munmap(addr, len); /* Clear old maps */
+ /* Clear old maps */
+ error = -ENOMEM;
+ if (do_munmap(addr, len))
+ goto free_vma;
/* Check against address space limit. */
if ((mm->total_vm << PAGE_SHIFT) + len
- > current->rlim[RLIMIT_AS].rlim_cur) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
+ > current->rlim[RLIMIT_AS].rlim_cur)
+ goto free_vma;
/* Private writable mapping? Check memory availability.. */
- if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE) {
- if (!(flags & MAP_NORESERVE) &&
- !vm_enough_memory(len >> PAGE_SHIFT)) {
- kmem_cache_free(vm_area_cachep, vma);
- return -ENOMEM;
- }
- }
+ if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == VM_WRITE &&
+ !(flags & MAP_NORESERVE) &&
+ !vm_enough_memory(len >> PAGE_SHIFT))
+ goto free_vma;
+ error = 0;
if (file) {
- int error = 0;
if (vma->vm_flags & VM_DENYWRITE) {
if (file->f_dentry->d_inode->i_writecount > 0)
error = -ETXTBSY;
@@ -298,23 +294,22 @@
if (!error)
error = file->f_op->mmap(file, vma);
- if (error) {
- if (correct_wcount)
- file->f_dentry->d_inode->i_writecount++;
- kmem_cache_free(vm_area_cachep, vma);
- return error;
- }
}
+ /* Fix up the count if necessary, then check for an error */
+ if (correct_wcount)
+ file->f_dentry->d_inode->i_writecount++;
+ if (error)
+ goto free_vma;
+ /*
+ * merge_segments may merge our vma, so we can't refer to it
+ * after the call. Save the values we need now ...
+ */
flags = vma->vm_flags;
+ addr = vma->vm_start; /* can addr have changed?? */
insert_vm_struct(mm, vma);
- if (correct_wcount)
- file->f_dentry->d_inode->i_writecount++;
merge_segments(mm, vma->vm_start, vma->vm_end);
- addr = vma->vm_start;
-
- /* merge_segments might have merged our vma, so we can't use it any more */
mm->total_vm += len >> PAGE_SHIFT;
if ((flags & VM_LOCKED) && !(flags & VM_IO)) {
unsigned long start = addr;
@@ -328,6 +323,10 @@
} while (len > 0);
}
return addr;
+
+free_vma:
+ kmem_cache_free(vm_area_cachep, vma);
+ return error;
}
/* Get an address range which is currently unmapped.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov