X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=kernel%2Ffork.c;h=fa3f82802cfc91762169666927cb084fed2f3fd2;hb=e812ccbe0c915857ebea6a632bfadc631f7504a9;hp=68597bc347f234220c85c097cc343cbe2860de4c;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/kernel/fork.c b/kernel/fork.c index 68597bc34..fa3f82802 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #include @@ -75,6 +77,9 @@ static kmem_cache_t *task_struct_cachep; static void free_task(struct task_struct *tsk) { free_thread_info(tsk->thread_info); + vxdprintk("freeing up task %p\n", tsk); + clr_vx_info(&tsk->vx_info); + clr_nx_info(&tsk->nx_info); free_task_struct(tsk); } @@ -405,6 +410,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm) if (likely(!mm_alloc_pgd(mm))) { mm->def_flags = 0; + set_vx_info(&mm->mm_vx_info, current->vx_info); return mm; } free_mm(mm); @@ -436,6 +442,7 @@ void fastcall __mmdrop(struct mm_struct *mm) BUG_ON(mm == &init_mm); mm_free_pgd(mm); destroy_context(mm); + clr_vx_info(&mm->mm_vx_info); free_mm(mm); } @@ -550,6 +557,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) /* Copy the current MM stuff.. */ memcpy(mm, oldmm, sizeof(*mm)); + mm->mm_vx_info = NULL; if (!mm_init(mm)) goto fail_nomem; @@ -861,6 +869,7 @@ struct task_struct *copy_process(unsigned long clone_flags, { int retval; struct task_struct *p = NULL; + struct vx_info *vxi; if ((clone_flags & (CLONE_NEWNS|CLONE_FS)) == (CLONE_NEWNS|CLONE_FS)) return ERR_PTR(-EINVAL); @@ -885,11 +894,34 @@ struct task_struct *copy_process(unsigned long clone_flags, goto fork_out; retval = -ENOMEM; + p = dup_task_struct(current); if (!p) goto fork_out; + p->vx_info = NULL; + set_vx_info(&p->vx_info, current->vx_info); + p->nx_info = NULL; + set_nx_info(&p->nx_info, current->nx_info); + + /* check vserver memory */ + if (p->mm && !(clone_flags & CLONE_VM)) { + if (vx_vmpages_avail(p->mm, p->mm->total_vm)) + vx_pages_add(p->mm->mm_vx_info, RLIMIT_AS, p->mm->total_vm); + else + goto bad_fork_free; + } + if (p->mm && vx_flags(VXF_FORK_RSS, 0)) { + if (!vx_rsspages_avail(p->mm, p->mm->rss)) + goto bad_fork_free; + } + retval = -EAGAIN; + vxi = current->vx_info; + if (vxi && (atomic_read(&vxi->limit.res[RLIMIT_NPROC]) + >= vxi->limit.rlim[RLIMIT_NPROC])) + goto bad_fork_free; + if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur) { if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && @@ -1074,6 +1106,10 @@ struct task_struct *copy_process(unsigned long clone_flags, link_pid(p, p->pids + PIDTYPE_TGID, &p->group_leader->pids[PIDTYPE_TGID].pid); nr_threads++; + if (vxi) { + atomic_inc(&vxi->cacct.nr_threads); + atomic_inc(&vxi->limit.res[RLIMIT_NPROC]); + } write_unlock_irq(&tasklist_lock); retval = 0;