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: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
3b422e9c2c
commit
e4eb1ff61b
@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)
|
||||
end = PAGE_ALIGN(end);
|
||||
if (end <= start)
|
||||
return;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(start, end - start);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
vm_brk(start, end - start);
|
||||
}
|
||||
|
||||
#ifdef CORE_DUMP
|
||||
@ -332,9 +330,7 @@ static int load_aout_binary(struct linux_binprm *bprm, struct pt_regs *regs)
|
||||
pos = 32;
|
||||
map_size = ex.a_text+ex.a_data;
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_brk(text_addr & PAGE_MASK, map_size);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
error = vm_brk(text_addr & PAGE_MASK, map_size);
|
||||
|
||||
if (error != (text_addr & PAGE_MASK)) {
|
||||
send_sig(SIGKILL, current, 0);
|
||||
@ -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) {
|
||||
loff_t pos = fd_offset;
|
||||
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
|
||||
bprm->file->f_op->read(bprm->file,
|
||||
(char __user *)N_TXTADDR(ex),
|
||||
ex.a_text+ex.a_data, &pos);
|
||||
@ -476,9 +470,7 @@ static int load_aout_library(struct file *file)
|
||||
error_time = jiffies;
|
||||
}
|
||||
#endif
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
|
||||
|
||||
file->f_op->read(file, (char __user *)start_addr,
|
||||
ex.a_text + ex.a_data, &pos);
|
||||
@ -503,9 +495,7 @@ static int load_aout_library(struct file *file)
|
||||
len = PAGE_ALIGN(ex.a_text + ex.a_data);
|
||||
bss = ex.a_text + ex.a_data + ex.a_bss;
|
||||
if (bss > len) {
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_brk(start_addr + len, bss - len);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
error = vm_brk(start_addr + len, bss - len);
|
||||
retval = error;
|
||||
if (error != start_addr + len)
|
||||
goto out;
|
||||
|
@ -50,9 +50,7 @@ static int set_brk(unsigned long start, unsigned long end)
|
||||
end = PAGE_ALIGN(end);
|
||||
if (end > start) {
|
||||
unsigned long addr;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
addr = do_brk(start, end - start);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
addr = vm_brk(start, end - start);
|
||||
if (BAD_ADDR(addr))
|
||||
return addr;
|
||||
}
|
||||
@ -280,9 +278,7 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
|
||||
pos = 32;
|
||||
map_size = ex.a_text+ex.a_data;
|
||||
#endif
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_brk(text_addr & PAGE_MASK, map_size);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
error = vm_brk(text_addr & PAGE_MASK, map_size);
|
||||
if (error != (text_addr & PAGE_MASK)) {
|
||||
send_sig(SIGKILL, current, 0);
|
||||
return error;
|
||||
@ -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)) {
|
||||
loff_t pos = fd_offset;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
vm_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
|
||||
bprm->file->f_op->read(bprm->file,
|
||||
(char __user *)N_TXTADDR(ex),
|
||||
ex.a_text+ex.a_data, &pos);
|
||||
@ -412,9 +406,7 @@ static int load_aout_library(struct file *file)
|
||||
"N_TXTOFF is not page aligned. Please convert library: %s\n",
|
||||
file->f_path.dentry->d_name.name);
|
||||
}
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
vm_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
|
||||
|
||||
file->f_op->read(file, (char __user *)start_addr,
|
||||
ex.a_text + ex.a_data, &pos);
|
||||
@ -438,9 +430,7 @@ static int load_aout_library(struct file *file)
|
||||
len = PAGE_ALIGN(ex.a_text + ex.a_data);
|
||||
bss = ex.a_text + ex.a_data + ex.a_bss;
|
||||
if (bss > len) {
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_brk(start_addr + len, bss - len);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
error = vm_brk(start_addr + len, bss - len);
|
||||
retval = error;
|
||||
if (error != start_addr + len)
|
||||
goto out;
|
||||
|
@ -82,9 +82,7 @@ static int set_brk(unsigned long start, unsigned long end)
|
||||
end = ELF_PAGEALIGN(end);
|
||||
if (end > start) {
|
||||
unsigned long addr;
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
addr = do_brk(start, end - start);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
addr = vm_brk(start, end - start);
|
||||
if (BAD_ADDR(addr))
|
||||
return addr;
|
||||
}
|
||||
@ -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);
|
||||
|
||||
/* Map the last of the bss segment */
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
error = do_brk(elf_bss, last_bss - elf_bss);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
error = vm_brk(elf_bss, last_bss - elf_bss);
|
||||
if (BAD_ADDR(error))
|
||||
goto out_close;
|
||||
}
|
||||
@ -1072,11 +1068,8 @@ static int load_elf_library(struct file *file)
|
||||
len = ELF_PAGESTART(eppnt->p_filesz + eppnt->p_vaddr +
|
||||
ELF_MIN_ALIGN - 1);
|
||||
bss = eppnt->p_memsz + eppnt->p_vaddr;
|
||||
if (bss > len) {
|
||||
down_write(¤t->mm->mmap_sem);
|
||||
do_brk(len, bss - len);
|
||||
up_write(¤t->mm->mmap_sem);
|
||||
}
|
||||
if (bss > len)
|
||||
vm_brk(len, bss - len);
|
||||
error = 0;
|
||||
|
||||
out_free_ph:
|
||||
|
@ -1415,7 +1415,8 @@ out:
|
||||
|
||||
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 */
|
||||
extern void truncate_inode_pages(struct address_space *, loff_t);
|
||||
|
16
mm/mmap.c
16
mm/mmap.c
@ -240,6 +240,8 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma)
|
||||
return next;
|
||||
}
|
||||
|
||||
static unsigned long do_brk(unsigned long addr, unsigned long len);
|
||||
|
||||
SYSCALL_DEFINE1(brk, unsigned long, brk)
|
||||
{
|
||||
unsigned long rlim, retval;
|
||||
@ -2136,7 +2138,7 @@ static inline void verify_mm_writelocked(struct mm_struct *mm)
|
||||
* anonymous maps. eventually we may be able to do some
|
||||
* 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 vm_area_struct * vma, * prev;
|
||||
@ -2232,7 +2234,17 @@ out:
|
||||
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. */
|
||||
void exit_mmap(struct mm_struct *mm)
|
||||
|
@ -1744,7 +1744,7 @@ void exit_mmap(struct mm_struct *mm)
|
||||
kleave("");
|
||||
}
|
||||
|
||||
unsigned long do_brk(unsigned long addr, unsigned long len)
|
||||
unsigned long vm_brk(unsigned long addr, unsigned long len)
|
||||
{
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user