Commit e4eb1ff6 authored by Linus Torvalds's avatar Linus Torvalds

VM: add "vm_brk()" helper function

It does the same thing as "do_brk()", except it handles the VM locking
too.

It turns out that all external callers want that anyway, so we can make
do_brk() static to just mm/mmap.c while at it.
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3b422e9c
...@@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end) ...@@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)
end = PAGE_ALIGN(end); end = PAGE_ALIGN(end);
if (end <= start) if (end <= start)
return; return;
down_write(&current->mm->mmap_sem); vm_brk(start, end - start);
do_brk(start, end - start);
up_write(&current->mm->mmap_sem);
} }
#ifdef CORE_DUMP #ifdef CORE_DUMP
...@@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
pos = 32; pos = 32;
map_size = ex.a_text+ex.a_data; map_size = ex.a_text+ex.a_data;
down_write(&current->mm->mmap_sem); error = vm_brk(text_addr & PAGE_MASK, map_size);
error = do_brk(text_addr & PAGE_MASK, map_size);
up_write(&current->mm->mmap_sem);
if (error != (text_addr & PAGE_MASK)) { if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
...@@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs) ...@@ -373,9 +369,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) { if (!bprm->file->f_op->mmap || (fd_offset & ~PAGE_MASK) != 0) {
loff_t pos = fd_offset; loff_t pos = fd_offset;
down_write(&current->mm->mmap_sem); vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex), (char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos); ex.a_text+ex.a_data, &pos);
...@@ -476,9 +470,7 @@ static int load_aout_library(struct file *file) ...@@ -476,9 +470,7 @@ static int load_aout_library(struct file *file)
error_time = jiffies; error_time = jiffies;
} }
#endif #endif
down_write(&current->mm->mmap_sem); vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
up_write(&current->mm->mmap_sem);
file->f_op->read(file, (char __user *)start_addr, file->f_op->read(file, (char __user *)start_addr,
ex.a_text + ex.a_data, &pos); ex.a_text + ex.a_data, &pos);
...@@ -503,9 +495,7 @@ static int load_aout_library(struct file *file) ...@@ -503,9 +495,7 @@ static int load_aout_library(struct file *file)
len = PAGE_ALIGN(ex.a_text + ex.a_data); len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss; bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) { if (bss > len) {
down_write(&current->mm->mmap_sem); error = vm_brk(start_addr + len, bss - len);
error = do_brk(start_addr + len, bss - len);
up_write(&current->mm->mmap_sem);
retval = error; retval = error;
if (error != start_addr + len) if (error != start_addr + len)
goto out; goto out;
......
...@@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end) ...@@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end)
end = PAGE_ALIGN(end); end = PAGE_ALIGN(end);
if (end > start) { if (end > start) {
unsigned long addr; unsigned long addr;
down_write(&current->mm->mmap_sem); addr = vm_brk(start, end - start);
addr = do_brk(start, end - start);
up_write(&current->mm->mmap_sem);
if (BAD_ADDR(addr)) if (BAD_ADDR(addr))
return addr; return addr;
} }
...@@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
pos = 32; pos = 32;
map_size = ex.a_text+ex.a_data; map_size = ex.a_text+ex.a_data;
#endif #endif
down_write(&current->mm->mmap_sem); error = vm_brk(text_addr & PAGE_MASK, map_size);
error = do_brk(text_addr & PAGE_MASK, map_size);
up_write(&current->mm->mmap_sem);
if (error != (text_addr & PAGE_MASK)) { if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0); send_sig(SIGKILL, current, 0);
return error; return error;
...@@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs) ...@@ -313,9 +309,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) { if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
loff_t pos = fd_offset; loff_t pos = fd_offset;
down_write(&current->mm->mmap_sem); vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex), (char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos); ex.a_text+ex.a_data, &pos);
...@@ -412,9 +406,7 @@ static int load_aout_library(struct file *file) ...@@ -412,9 +406,7 @@ static int load_aout_library(struct file *file)
"N_TXTOFF is not page aligned. Please convert library: %s\n", "N_TXTOFF is not page aligned. Please convert library: %s\n",
file->f_path.dentry->d_name.name); file->f_path.dentry->d_name.name);
} }
down_write(&current->mm->mmap_sem); vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
up_write(&current->mm->mmap_sem);
file->f_op->read(file, (char __user *)start_addr, file->f_op->read(file, (char __user *)start_addr,
ex.a_text + ex.a_data, &pos); ex.a_text + ex.a_data, &pos);
...@@ -438,9 +430,7 @@ static int load_aout_library(struct file *file) ...@@ -438,9 +430,7 @@ static int load_aout_library(struct file *file)
len = PAGE_ALIGN(ex.a_text + ex.a_data); len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss; bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) { if (bss > len) {
down_write(&current->mm->mmap_sem); error = vm_brk(start_addr + len, bss - len);
error = do_brk(start_addr + len, bss - len);
up_write(&current->mm->mmap_sem);
retval = error; retval = error;
if (error != start_addr + len) if (error != start_addr + len)
goto out; goto out;
......
...@@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end) ...@@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end)
end = ELF_PAGEALIGN(end); end = ELF_PAGEALIGN(end);
if (end > start) { if (end > start) {
unsigned long addr; unsigned long addr;
down_write(&current->mm->mmap_sem); addr = vm_brk(start, end - start);
addr = do_brk(start, end - start);
up_write(&current->mm->mmap_sem);
if (BAD_ADDR(addr)) if (BAD_ADDR(addr))
return addr; return addr;
} }
...@@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, ...@@ -514,9 +512,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1);
/* Map the last of the bss segment */ /* Map the last of the bss segment */
down_write(&current->mm->mmap_sem); error = vm_brk(elf_bss, last_bss - elf_bss);
error = do_brk(elf_bss, last_bss - elf_bss);
up_write(&current->mm->mmap_sem);
if (BAD_ADDR(error)) if (BAD_ADDR(error))
goto out_close; goto out_close;
} }
...@@ -1072,11 +1068,8 @@ static int load_elf_library(struct file *file) ...@@ -1072,11 +1068,8 @@ static int load_elf_library(struct file *file)
len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr + len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
ELF_MIN_ALIGN - 1); ELF_MIN_ALIGN - 1);
bss = eppnt->p_memsz + eppnt->p_vaddr; bss = eppnt->p_memsz + eppnt->p_vaddr;
if (bss > len) { if (bss > len)
down_write(&current->mm->mmap_sem); vm_brk(len, bss - len);
do_brk(len, bss - len);
up_write(&current->mm->mmap_sem);
}
error = 0; error = 0;
out_free_ph: out_free_ph:
......
...@@ -1415,7 +1415,8 @@ static inline unsigned long do_mmap(struct file *file, unsigned long addr, ...@@ -1415,7 +1415,8 @@ static inline unsigned long do_mmap(struct file *file, unsigned long addr,
extern int do_munmap(struct mm_struct *, unsigned long, size_t); extern int do_munmap(struct mm_struct *, unsigned long, size_t);
extern unsigned long do_brk(unsigned long, unsigned long); /* These take the mm semaphore themselves */
extern unsigned long vm_brk(unsigned long, unsigned long);
/* truncate.c */ /* truncate.c */
extern void truncate_inode_pages(struct address_space *, loff_t); extern void truncate_inode_pages(struct address_space *, loff_t);
......
...@@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) ...@@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
return next; return next;
} }
static unsigned long do_brk(unsigned long addr, unsigned long len);
SYSCALL_DEFINE1(brk, unsigned long, brk) SYSCALL_DEFINE1(brk, unsigned long, brk)
{ {
unsigned long rlim, retval; unsigned long rlim, retval;
...@@ -2136,7 +2138,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm) ...@@ -2136,7 +2138,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
* anonymous maps. eventually we may be able to do some * anonymous maps. eventually we may be able to do some
* brk-specific accounting here. * brk-specific accounting here.
*/ */
unsigned long do_brk(unsigned long addr, unsigned long len) static unsigned long do_brk(unsigned long addr, unsigned long len)
{ {
struct mm_struct * mm = current->mm; struct mm_struct * mm = current->mm;
struct vm_area_struct * vma, * prev; struct vm_area_struct * vma, * prev;
...@@ -2232,7 +2234,17 @@ unsigned long do_brk(unsigned long addr, unsigned long len) ...@@ -2232,7 +2234,17 @@ unsigned long do_brk(unsigned long addr, unsigned long len)
return addr; return addr;
} }
EXPORT_SYMBOL(do_brk); unsigned long vm_brk(unsigned long addr, unsigned long len)
{
struct mm_struct *mm = current->mm;
unsigned long ret;
down_write(&mm->mmap_sem);
ret = do_brk(addr, len);
up_write(&mm->mmap_sem);
return ret;
}
EXPORT_SYMBOL(vm_brk);
/* Release all mmaps. */ /* Release all mmaps. */
void exit_mmap(struct mm_struct *mm) void exit_mmap(struct mm_struct *mm)
......
...@@ -1744,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm) ...@@ -1744,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm)
kleave(""); kleave("");
} }
unsigned long do_brk(unsigned long addr, unsigned long len) unsigned long vm_brk(unsigned long addr, unsigned long len)
{ {
return -ENOMEM; return -ENOMEM;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment