Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.24-rc4 238 lines 4.9 kB view raw
1/* 2 * fs/ioprio.c 3 * 4 * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk> 5 * 6 * Helper functions for setting/querying io priorities of processes. The 7 * system calls closely mimmick getpriority/setpriority, see the man page for 8 * those. The prio argument is a composite of prio class and prio data, where 9 * the data argument has meaning within that class. The standard scheduling 10 * classes have 8 distinct prio levels, with 0 being the highest prio and 7 11 * being the lowest. 12 * 13 * IOW, setting BE scheduling class with prio 2 is done ala: 14 * 15 * unsigned int prio = (IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) | 2; 16 * 17 * ioprio_set(PRIO_PROCESS, pid, prio); 18 * 19 * See also Documentation/block/ioprio.txt 20 * 21 */ 22#include <linux/kernel.h> 23#include <linux/ioprio.h> 24#include <linux/blkdev.h> 25#include <linux/capability.h> 26#include <linux/syscalls.h> 27#include <linux/security.h> 28#include <linux/pid_namespace.h> 29 30static int set_task_ioprio(struct task_struct *task, int ioprio) 31{ 32 int err; 33 struct io_context *ioc; 34 35 if (task->uid != current->euid && 36 task->uid != current->uid && !capable(CAP_SYS_NICE)) 37 return -EPERM; 38 39 err = security_task_setioprio(task, ioprio); 40 if (err) 41 return err; 42 43 task_lock(task); 44 45 task->ioprio = ioprio; 46 47 ioc = task->io_context; 48 /* see wmb() in current_io_context() */ 49 smp_read_barrier_depends(); 50 51 if (ioc) 52 ioc->ioprio_changed = 1; 53 54 task_unlock(task); 55 return 0; 56} 57 58asmlinkage long sys_ioprio_set(int which, int who, int ioprio) 59{ 60 int class = IOPRIO_PRIO_CLASS(ioprio); 61 int data = IOPRIO_PRIO_DATA(ioprio); 62 struct task_struct *p, *g; 63 struct user_struct *user; 64 struct pid *pgrp; 65 int ret; 66 67 switch (class) { 68 case IOPRIO_CLASS_RT: 69 if (!capable(CAP_SYS_ADMIN)) 70 return -EPERM; 71 /* fall through, rt has prio field too */ 72 case IOPRIO_CLASS_BE: 73 if (data >= IOPRIO_BE_NR || data < 0) 74 return -EINVAL; 75 76 break; 77 case IOPRIO_CLASS_IDLE: 78 if (!capable(CAP_SYS_ADMIN)) 79 return -EPERM; 80 break; 81 case IOPRIO_CLASS_NONE: 82 if (data) 83 return -EINVAL; 84 break; 85 default: 86 return -EINVAL; 87 } 88 89 ret = -ESRCH; 90 /* 91 * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", 92 * so we can't use rcu_read_lock(). See re-copy of ->ioprio 93 * in copy_process(). 94 */ 95 read_lock(&tasklist_lock); 96 switch (which) { 97 case IOPRIO_WHO_PROCESS: 98 if (!who) 99 p = current; 100 else 101 p = find_task_by_vpid(who); 102 if (p) 103 ret = set_task_ioprio(p, ioprio); 104 break; 105 case IOPRIO_WHO_PGRP: 106 if (!who) 107 pgrp = task_pgrp(current); 108 else 109 pgrp = find_vpid(who); 110 do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 111 ret = set_task_ioprio(p, ioprio); 112 if (ret) 113 break; 114 } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 115 break; 116 case IOPRIO_WHO_USER: 117 if (!who) 118 user = current->user; 119 else 120 user = find_user(who); 121 122 if (!user) 123 break; 124 125 do_each_thread(g, p) { 126 if (p->uid != who) 127 continue; 128 ret = set_task_ioprio(p, ioprio); 129 if (ret) 130 goto free_uid; 131 } while_each_thread(g, p); 132free_uid: 133 if (who) 134 free_uid(user); 135 break; 136 default: 137 ret = -EINVAL; 138 } 139 140 read_unlock(&tasklist_lock); 141 return ret; 142} 143 144static int get_task_ioprio(struct task_struct *p) 145{ 146 int ret; 147 148 ret = security_task_getioprio(p); 149 if (ret) 150 goto out; 151 ret = p->ioprio; 152out: 153 return ret; 154} 155 156int ioprio_best(unsigned short aprio, unsigned short bprio) 157{ 158 unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); 159 unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); 160 161 if (aclass == IOPRIO_CLASS_NONE) 162 aclass = IOPRIO_CLASS_BE; 163 if (bclass == IOPRIO_CLASS_NONE) 164 bclass = IOPRIO_CLASS_BE; 165 166 if (aclass == bclass) 167 return min(aprio, bprio); 168 if (aclass > bclass) 169 return bprio; 170 else 171 return aprio; 172} 173 174asmlinkage long sys_ioprio_get(int which, int who) 175{ 176 struct task_struct *g, *p; 177 struct user_struct *user; 178 struct pid *pgrp; 179 int ret = -ESRCH; 180 int tmpio; 181 182 read_lock(&tasklist_lock); 183 switch (which) { 184 case IOPRIO_WHO_PROCESS: 185 if (!who) 186 p = current; 187 else 188 p = find_task_by_vpid(who); 189 if (p) 190 ret = get_task_ioprio(p); 191 break; 192 case IOPRIO_WHO_PGRP: 193 if (!who) 194 pgrp = task_pgrp(current); 195 else 196 pgrp = find_vpid(who); 197 do_each_pid_task(pgrp, PIDTYPE_PGID, p) { 198 tmpio = get_task_ioprio(p); 199 if (tmpio < 0) 200 continue; 201 if (ret == -ESRCH) 202 ret = tmpio; 203 else 204 ret = ioprio_best(ret, tmpio); 205 } while_each_pid_task(pgrp, PIDTYPE_PGID, p); 206 break; 207 case IOPRIO_WHO_USER: 208 if (!who) 209 user = current->user; 210 else 211 user = find_user(who); 212 213 if (!user) 214 break; 215 216 do_each_thread(g, p) { 217 if (p->uid != user->uid) 218 continue; 219 tmpio = get_task_ioprio(p); 220 if (tmpio < 0) 221 continue; 222 if (ret == -ESRCH) 223 ret = tmpio; 224 else 225 ret = ioprio_best(ret, tmpio); 226 } while_each_thread(g, p); 227 228 if (who) 229 free_uid(user); 230 break; 231 default: 232 ret = -EINVAL; 233 } 234 235 read_unlock(&tasklist_lock); 236 return ret; 237} 238