mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 05:45:20 +00:00
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);
|
end = PAGE_ALIGN(end);
|
||||||
if (end <= start)
|
if (end <= start)
|
||||||
return;
|
return;
|
||||||
down_write(¤t->mm->mmap_sem);
|
vm_brk(start, end - start);
|
||||||
do_brk(start, end - start);
|
|
||||||
up_write(¤t->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)
|
|||||||
pos = 32;
|
pos = 32;
|
||||||
map_size = ex.a_text+ex.a_data;
|
map_size = ex.a_text+ex.a_data;
|
||||||
|
|
||||||
down_write(¤t->mm->mmap_sem);
|
error = vm_brk(text_addr & PAGE_MASK, map_size);
|
||||||
error = do_brk(text_addr & PAGE_MASK, map_size);
|
|
||||||
up_write(¤t->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)
|
|||||||
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(¤t->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(¤t->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)
|
|||||||
error_time = jiffies;
|
error_time = jiffies;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
down_write(¤t->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(¤t->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)
|
|||||||
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(¤t->mm->mmap_sem);
|
error = vm_brk(start_addr + len, bss - len);
|
||||||
error = do_brk(start_addr + len, bss - len);
|
|
||||||
up_write(¤t->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)
|
|||||||
end = PAGE_ALIGN(end);
|
end = PAGE_ALIGN(end);
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
down_write(¤t->mm->mmap_sem);
|
addr = vm_brk(start, end - start);
|
||||||
addr = do_brk(start, end - start);
|
|
||||||
up_write(¤t->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)
|
|||||||
pos = 32;
|
pos = 32;
|
||||||
map_size = ex.a_text+ex.a_data;
|
map_size = ex.a_text+ex.a_data;
|
||||||
#endif
|
#endif
|
||||||
down_write(¤t->mm->mmap_sem);
|
error = vm_brk(text_addr & PAGE_MASK, map_size);
|
||||||
error = do_brk(text_addr & PAGE_MASK, map_size);
|
|
||||||
up_write(¤t->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)
|
|||||||
|
|
||||||
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(¤t->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(¤t->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)
|
|||||||
"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(¤t->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(¤t->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)
|
|||||||
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(¤t->mm->mmap_sem);
|
error = vm_brk(start_addr + len, bss - len);
|
||||||
error = do_brk(start_addr + len, bss - len);
|
|
||||||
up_write(¤t->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)
|
|||||||
end = ELF_PAGEALIGN(end);
|
end = ELF_PAGEALIGN(end);
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
down_write(¤t->mm->mmap_sem);
|
addr = vm_brk(start, end - start);
|
||||||
addr = do_brk(start, end - start);
|
|
||||||
up_write(¤t->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,
|
|||||||
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(¤t->mm->mmap_sem);
|
error = vm_brk(elf_bss, last_bss - elf_bss);
|
||||||
error = do_brk(elf_bss, last_bss - elf_bss);
|
|
||||||
up_write(¤t->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)
|
|||||||
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(¤t->mm->mmap_sem);
|
vm_brk(len, bss - len);
|
||||||
do_brk(len, bss - len);
|
|
||||||
up_write(¤t->mm->mmap_sem);
|
|
||||||
}
|
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
||||||
out_free_ph:
|
out_free_ph:
|
||||||
|
@ -1415,7 +1415,8 @@ out:
|
|||||||
|
|
||||||
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);
|
||||||
|
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;
|
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)
|
|||||||
* 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 @@ out:
|
|||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user