git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
HID: add dynids facility
[safe/jmp/linux-2.6]
/
fs
/
ioprio.c
diff --git
a/fs/ioprio.c
b/fs/ioprio.c
index
78b1dea
..
3569e0a
100644
(file)
--- a/
fs/ioprio.c
+++ b/
fs/ioprio.c
@@
-1,7
+1,7
@@
/*
* fs/ioprio.c
*
/*
* fs/ioprio.c
*
- * Copyright (C) 2004 Jens Axboe <axboe@
suse.de
>
+ * Copyright (C) 2004 Jens Axboe <axboe@
kernel.dk
>
*
* Helper functions for setting/querying io priorities of processes. The
* system calls closely mimmick getpriority/setpriority, see the man page for
*
* Helper functions for setting/querying io priorities of processes. The
* system calls closely mimmick getpriority/setpriority, see the man page for
@@
-25,33
+25,50
@@
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/security.h>
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/security.h>
+#include <linux/pid_namespace.h>
static int set_task_ioprio(struct task_struct *task, int ioprio)
{
int err;
struct io_context *ioc;
static int set_task_ioprio(struct task_struct *task, int ioprio)
{
int err;
struct io_context *ioc;
+ const struct cred *cred = current_cred(), *tcred;
- if (task->uid != current->euid &&
- task->uid != current->uid && !capable(CAP_SYS_NICE))
+ rcu_read_lock();
+ tcred = __task_cred(task);
+ if (tcred->uid != cred->euid &&
+ tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) {
+ rcu_read_unlock();
return -EPERM;
return -EPERM;
+ }
+ rcu_read_unlock();
err = security_task_setioprio(task, ioprio);
if (err)
return err;
task_lock(task);
err = security_task_setioprio(task, ioprio);
if (err)
return err;
task_lock(task);
+ do {
+ ioc = task->io_context;
+ /* see wmb() in current_io_context() */
+ smp_read_barrier_depends();
+ if (ioc)
+ break;
- task->ioprio = ioprio;
-
- ioc = task->io_context;
- /* see wmb() in current_io_context() */
- smp_read_barrier_depends();
+ ioc = alloc_io_context(GFP_ATOMIC, -1);
+ if (!ioc) {
+ err = -ENOMEM;
+ break;
+ }
+ task->io_context = ioc;
+ } while (1);
- if (ioc && ioc->set_ioprio)
- ioc->set_ioprio(ioc, ioprio);
+ if (!err) {
+ ioc->ioprio = ioprio;
+ ioc->ioprio_changed = 1;
+ }
task_unlock(task);
task_unlock(task);
- return
0
;
+ return
err
;
}
asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
}
asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
@@
-60,6
+77,7
@@
asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
int data = IOPRIO_PRIO_DATA(ioprio);
struct task_struct *p, *g;
struct user_struct *user;
int data = IOPRIO_PRIO_DATA(ioprio);
struct task_struct *p, *g;
struct user_struct *user;
+ struct pid *pgrp;
int ret;
switch (class) {
int ret;
switch (class) {
@@
-73,36
+91,45
@@
asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
break;
case IOPRIO_CLASS_IDLE:
break;
case IOPRIO_CLASS_IDLE:
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
+ break;
+ case IOPRIO_CLASS_NONE:
+ if (data)
+ return -EINVAL;
break;
default:
return -EINVAL;
}
ret = -ESRCH;
break;
default:
return -EINVAL;
}
ret = -ESRCH;
- read_lock_irq(&tasklist_lock);
+ /*
+ * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic",
+ * so we can't use rcu_read_lock(). See re-copy of ->ioprio
+ * in copy_process().
+ */
+ read_lock(&tasklist_lock);
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
p = current;
else
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
p = current;
else
- p = find_task_by_pid(who);
+ p = find_task_by_
v
pid(who);
if (p)
ret = set_task_ioprio(p, ioprio);
break;
case IOPRIO_WHO_PGRP:
if (!who)
if (p)
ret = set_task_ioprio(p, ioprio);
break;
case IOPRIO_WHO_PGRP:
if (!who)
- who = process_group(current);
- do_each_task_pid(who, PIDTYPE_PGID, p) {
+ pgrp = task_pgrp(current);
+ else
+ pgrp = find_vpid(who);
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
ret = set_task_ioprio(p, ioprio);
if (ret)
break;
ret = set_task_ioprio(p, ioprio);
if (ret)
break;
- } while_each_
task_pid(who
, PIDTYPE_PGID, p);
+ } while_each_
pid_thread(pgrp
, PIDTYPE_PGID, p);
break;
case IOPRIO_WHO_USER:
if (!who)
break;
case IOPRIO_WHO_USER:
if (!who)
- user = current
->user
;
+ user = current
_user()
;
else
user = find_user(who);
else
user = find_user(who);
@@
-110,7
+137,7
@@
asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
break;
do_each_thread(g, p) {
break;
do_each_thread(g, p) {
- if (
p
->uid != who)
+ if (
__task_cred(p)
->uid != who)
continue;
ret = set_task_ioprio(p, ioprio);
if (ret)
continue;
ret = set_task_ioprio(p, ioprio);
if (ret)
@@
-124,7
+151,7
@@
free_uid:
ret = -EINVAL;
}
ret = -EINVAL;
}
- read_unlock
_irq
(&tasklist_lock);
+ read_unlock(&tasklist_lock);
return ret;
}
return ret;
}
@@
-135,7
+162,9
@@
static int get_task_ioprio(struct task_struct *p)
ret = security_task_getioprio(p);
if (ret)
goto out;
ret = security_task_getioprio(p);
if (ret)
goto out;
- ret = p->ioprio;
+ ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
+ if (p->io_context)
+ ret = p->io_context->ioprio;
out:
return ret;
}
out:
return ret;
}
@@
-145,11
+174,6
@@
int ioprio_best(unsigned short aprio, unsigned short bprio)
unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
- if (!ioprio_valid(aprio))
- return bprio;
- if (!ioprio_valid(bprio))
- return aprio;
-
if (aclass == IOPRIO_CLASS_NONE)
aclass = IOPRIO_CLASS_BE;
if (bclass == IOPRIO_CLASS_NONE)
if (aclass == IOPRIO_CLASS_NONE)
aclass = IOPRIO_CLASS_BE;
if (bclass == IOPRIO_CLASS_NONE)
@@
-167,23
+191,26
@@
asmlinkage long sys_ioprio_get(int which, int who)
{
struct task_struct *g, *p;
struct user_struct *user;
{
struct task_struct *g, *p;
struct user_struct *user;
+ struct pid *pgrp;
int ret = -ESRCH;
int tmpio;
int ret = -ESRCH;
int tmpio;
- read_lock
_irq
(&tasklist_lock);
+ read_lock(&tasklist_lock);
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
p = current;
else
switch (which) {
case IOPRIO_WHO_PROCESS:
if (!who)
p = current;
else
- p = find_task_by_pid(who);
+ p = find_task_by_
v
pid(who);
if (p)
ret = get_task_ioprio(p);
break;
case IOPRIO_WHO_PGRP:
if (!who)
if (p)
ret = get_task_ioprio(p);
break;
case IOPRIO_WHO_PGRP:
if (!who)
- who = process_group(current);
- do_each_task_pid(who, PIDTYPE_PGID, p) {
+ pgrp = task_pgrp(current);
+ else
+ pgrp = find_vpid(who);
+ do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
tmpio = get_task_ioprio(p);
if (tmpio < 0)
continue;
tmpio = get_task_ioprio(p);
if (tmpio < 0)
continue;
@@
-191,11
+218,11
@@
asmlinkage long sys_ioprio_get(int which, int who)
ret = tmpio;
else
ret = ioprio_best(ret, tmpio);
ret = tmpio;
else
ret = ioprio_best(ret, tmpio);
- } while_each_
task_pid(who
, PIDTYPE_PGID, p);
+ } while_each_
pid_thread(pgrp
, PIDTYPE_PGID, p);
break;
case IOPRIO_WHO_USER:
if (!who)
break;
case IOPRIO_WHO_USER:
if (!who)
- user = current
->user
;
+ user = current
_user()
;
else
user = find_user(who);
else
user = find_user(who);
@@
-203,7
+230,7
@@
asmlinkage long sys_ioprio_get(int which, int who)
break;
do_each_thread(g, p) {
break;
do_each_thread(g, p) {
- if (
p
->uid != user->uid)
+ if (
__task_cred(p)
->uid != user->uid)
continue;
tmpio = get_task_ioprio(p);
if (tmpio < 0)
continue;
tmpio = get_task_ioprio(p);
if (tmpio < 0)
@@
-221,7
+248,7
@@
asmlinkage long sys_ioprio_get(int which, int who)
ret = -EINVAL;
}
ret = -EINVAL;
}
- read_unlock
_irq
(&tasklist_lock);
+ read_unlock(&tasklist_lock);
return ret;
}
return ret;
}