Commit e4eb1ff6 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
Loading
Loading
Loading
Loading
+5 −15
Original line number Diff line number Diff line
@@ -119,9 +119,7 @@ static void set_brk(unsigned long start, unsigned long end)
	end = PAGE_ALIGN(end);
	if (end <= start)
		return;
	down_write(&current->mm->mmap_sem);
	do_brk(start, end - start);
	up_write(&current->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(&current->mm->mmap_sem);
		error = do_brk(text_addr & PAGE_MASK, map_size);
		up_write(&current->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(&current->mm->mmap_sem);
			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
			up_write(&current->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(&current->mm->mmap_sem);
		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
		up_write(&current->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(&current->mm->mmap_sem);
		error = do_brk(start_addr + len, bss - len);
		up_write(&current->mm->mmap_sem);
		error = vm_brk(start_addr + len, bss - len);
		retval = error;
		if (error != start_addr + len)
			goto out;
+5 −15
Original line number Diff line number Diff line
@@ -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(&current->mm->mmap_sem);
		addr = do_brk(start, end - start);
		up_write(&current->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(&current->mm->mmap_sem);
		error = do_brk(text_addr & PAGE_MASK, map_size);
		up_write(&current->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(&current->mm->mmap_sem);
			do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
			up_write(&current->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(&current->mm->mmap_sem);
		do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
		up_write(&current->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(&current->mm->mmap_sem);
		error = do_brk(start_addr + len, bss - len);
		up_write(&current->mm->mmap_sem);
		error = vm_brk(start_addr + len, bss - len);
		retval = error;
		if (error != start_addr + len)
			goto out;
+4 −11
Original line number Diff line number Diff line
@@ -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(&current->mm->mmap_sem);
		addr = do_brk(start, end - start);
		up_write(&current->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(&current->mm->mmap_sem);
		error = do_brk(elf_bss, last_bss - elf_bss);
		up_write(&current->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(&current->mm->mmap_sem);
		do_brk(len, bss - len);
		up_write(&current->mm->mmap_sem);
	}
	if (bss > len)
		vm_brk(len, bss - len);
	error = 0;

out_free_ph:
+2 −1
Original line number Diff line number Diff line
@@ -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);
+14 −2
Original line number Diff line number Diff line
@@ -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)
Loading