[RFC][PATCH][3/3] restructure sys_setrlimit

From: Hirofumi Nakagawa
Date: Wed Jul 23 2008 - 08:34:45 EST


Signed-off-by: Hirofumi Nakagawa <hnakagawa@xxxxxxxxxxxxxxxx>
---
include/linux/resource.h | 2 +
kernel/sys.c | 56 ++++++++++++++++++++++++++---------------------
2 files changed, 34 insertions(+), 24 deletions(-)

--- linux-2.6.26-rc8-mm1.orig/kernel/sys.c 2008-07-22 21:22:30.000000000 +0900
+++ linux-2.6.26-rc8-mm1/kernel/sys.c 2008-07-22 21:23:00.000000000 +0900
@@ -1457,42 +1457,37 @@ asmlinkage long sys_old_getrlimit(unsign

#endif

-asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
+long __setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim)
{
- struct rlimit new_rlim, *old_rlim;
+ struct rlimit *old_rlim;
unsigned long it_prof_secs;
int retval;

- if (resource >= RLIM_NLIMITS)
- return -EINVAL;
- if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
- return -EFAULT;
- if (new_rlim.rlim_cur > new_rlim.rlim_max)
- return -EINVAL;
- old_rlim = current->signal->rlim + resource;
- if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
+ old_rlim = tsk->signal->rlim + resource;
+ if ((new_rlim->rlim_max > old_rlim->rlim_max) &&
!capable(CAP_SYS_RESOURCE))
return -EPERM;
- if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
+ if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
return -EPERM;

- retval = security_task_setrlimit(resource, &new_rlim);
+ retval = security_task_setrlimit(resource, new_rlim);
if (retval)
return retval;

- if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
+ if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
/*
* The caller is asking for an immediate RLIMIT_CPU
* expiry. But we use the zero value to mean "it was
* never set". So let's cheat and make it one second
* instead
*/
- new_rlim.rlim_cur = 1;
+ new_rlim->rlim_cur = 1;
}

- task_lock(current->group_leader);
- *old_rlim = new_rlim;
- task_unlock(current->group_leader);
+ task_lock(tsk->group_leader);
+ *old_rlim = *new_rlim;
+ task_unlock(tsk->group_leader);

if (resource != RLIMIT_CPU)
goto out;
@@ -1503,25 +1498,38 @@ asmlinkage long sys_setrlimit(unsigned i
* very long-standing error, and fixing it now risks breakage of
* applications, so we live with it
*/
- if (new_rlim.rlim_cur == RLIM_INFINITY)
+ if (new_rlim->rlim_cur == RLIM_INFINITY)
goto out;

- it_prof_secs = cputime_to_secs(current->signal->it_prof_expires);
- if (it_prof_secs == 0 || new_rlim.rlim_cur <= it_prof_secs) {
- unsigned long rlim_cur = new_rlim.rlim_cur;
+ it_prof_secs = cputime_to_secs(tsk->signal->it_prof_expires);
+ if (it_prof_secs == 0 || new_rlim->rlim_cur <= it_prof_secs) {
+ unsigned long rlim_cur = new_rlim->rlim_cur;
cputime_t cputime;

cputime = secs_to_cputime(rlim_cur);
read_lock(&tasklist_lock);
- spin_lock_irq(&current->sighand->siglock);
- set_process_cpu_timer(current, CPUCLOCK_PROF, &cputime, NULL);
- spin_unlock_irq(&current->sighand->siglock);
+ spin_lock_irq(&tsk->sighand->siglock);
+ set_process_cpu_timer(tsk, CPUCLOCK_PROF, &cputime, NULL);
+ spin_unlock_irq(&tsk->sighand->siglock);
read_unlock(&tasklist_lock);
}
out:
return 0;
}

+asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
+{
+ struct rlimit new_rlim;
+
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
+ if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
+ return -EFAULT;
+ if (new_rlim.rlim_cur > new_rlim.rlim_max)
+ return -EINVAL;
+ return __setrlimit(current, resource, &new_rlim);
+}
+
/*
* It would make sense to put struct rusage in the task_struct,
* except that would make the task_struct be *really big*. After
--- linux-2.6.26-rc8-mm1.orig/include/linux/resource.h 2008-07-22 21:23:59.000000000 +0900
+++ linux-2.6.26-rc8-mm1/include/linux/resource.h 2008-07-22 21:24:02.000000000 +0900
@@ -96,4 +96,6 @@ static const struct limit_names lnames[R

int getrusage(struct task_struct *p, int who, struct rusage __user *ru);

+long __setrlimit(struct task_struct *tsk, unsigned int resource,
+ struct rlimit *new_rlim);
#endif


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/