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.19 227 lines 4.7 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 29static int set_task_ioprio(struct task_struct *task, int ioprio) 30{ 31 int err; 32 struct io_context *ioc; 33 34 if (task->uid != current->euid && 35 task->uid != current->uid && !capable(CAP_SYS_NICE)) 36 return -EPERM; 37 38 err = security_task_setioprio(task, ioprio); 39 if (err) 40 return err; 41 42 task_lock(task); 43 44 task->ioprio = ioprio; 45 46 ioc = task->io_context; 47 /* see wmb() in current_io_context() */ 48 smp_read_barrier_depends(); 49 50 if (ioc) 51 ioc->ioprio_changed = 1; 52 53 task_unlock(task); 54 return 0; 55} 56 57asmlinkage long sys_ioprio_set(int which, int who, int ioprio) 58{ 59 int class = IOPRIO_PRIO_CLASS(ioprio); 60 int data = IOPRIO_PRIO_DATA(ioprio); 61 struct task_struct *p, *g; 62 struct user_struct *user; 63 int ret; 64 65 switch (class) { 66 case IOPRIO_CLASS_RT: 67 if (!capable(CAP_SYS_ADMIN)) 68 return -EPERM; 69 /* fall through, rt has prio field too */ 70 case IOPRIO_CLASS_BE: 71 if (data >= IOPRIO_BE_NR || data < 0) 72 return -EINVAL; 73 74 break; 75 case IOPRIO_CLASS_IDLE: 76 if (!capable(CAP_SYS_ADMIN)) 77 return -EPERM; 78 break; 79 default: 80 return -EINVAL; 81 } 82 83 ret = -ESRCH; 84 /* 85 * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic", 86 * so we can't use rcu_read_lock(). See re-copy of ->ioprio 87 * in copy_process(). 88 */ 89 read_lock(&tasklist_lock); 90 switch (which) { 91 case IOPRIO_WHO_PROCESS: 92 if (!who) 93 p = current; 94 else 95 p = find_task_by_pid(who); 96 if (p) 97 ret = set_task_ioprio(p, ioprio); 98 break; 99 case IOPRIO_WHO_PGRP: 100 if (!who) 101 who = process_group(current); 102 do_each_task_pid(who, PIDTYPE_PGID, p) { 103 ret = set_task_ioprio(p, ioprio); 104 if (ret) 105 break; 106 } while_each_task_pid(who, PIDTYPE_PGID, p); 107 break; 108 case IOPRIO_WHO_USER: 109 if (!who) 110 user = current->user; 111 else 112 user = find_user(who); 113 114 if (!user) 115 break; 116 117 do_each_thread(g, p) { 118 if (p->uid != who) 119 continue; 120 ret = set_task_ioprio(p, ioprio); 121 if (ret) 122 goto free_uid; 123 } while_each_thread(g, p); 124free_uid: 125 if (who) 126 free_uid(user); 127 break; 128 default: 129 ret = -EINVAL; 130 } 131 132 read_unlock(&tasklist_lock); 133 return ret; 134} 135 136static int get_task_ioprio(struct task_struct *p) 137{ 138 int ret; 139 140 ret = security_task_getioprio(p); 141 if (ret) 142 goto out; 143 ret = p->ioprio; 144out: 145 return ret; 146} 147 148int ioprio_best(unsigned short aprio, unsigned short bprio) 149{ 150 unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); 151 unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); 152 153 if (aclass == IOPRIO_CLASS_NONE) 154 aclass = IOPRIO_CLASS_BE; 155 if (bclass == IOPRIO_CLASS_NONE) 156 bclass = IOPRIO_CLASS_BE; 157 158 if (aclass == bclass) 159 return min(aprio, bprio); 160 if (aclass > bclass) 161 return bprio; 162 else 163 return aprio; 164} 165 166asmlinkage long sys_ioprio_get(int which, int who) 167{ 168 struct task_struct *g, *p; 169 struct user_struct *user; 170 int ret = -ESRCH; 171 int tmpio; 172 173 read_lock(&tasklist_lock); 174 switch (which) { 175 case IOPRIO_WHO_PROCESS: 176 if (!who) 177 p = current; 178 else 179 p = find_task_by_pid(who); 180 if (p) 181 ret = get_task_ioprio(p); 182 break; 183 case IOPRIO_WHO_PGRP: 184 if (!who) 185 who = process_group(current); 186 do_each_task_pid(who, PIDTYPE_PGID, p) { 187 tmpio = get_task_ioprio(p); 188 if (tmpio < 0) 189 continue; 190 if (ret == -ESRCH) 191 ret = tmpio; 192 else 193 ret = ioprio_best(ret, tmpio); 194 } while_each_task_pid(who, PIDTYPE_PGID, p); 195 break; 196 case IOPRIO_WHO_USER: 197 if (!who) 198 user = current->user; 199 else 200 user = find_user(who); 201 202 if (!user) 203 break; 204 205 do_each_thread(g, p) { 206 if (p->uid != user->uid) 207 continue; 208 tmpio = get_task_ioprio(p); 209 if (tmpio < 0) 210 continue; 211 if (ret == -ESRCH) 212 ret = tmpio; 213 else 214 ret = ioprio_best(ret, tmpio); 215 } while_each_thread(g, p); 216 217 if (who) 218 free_uid(user); 219 break; 220 default: 221 ret = -EINVAL; 222 } 223 224 read_unlock(&tasklist_lock); 225 return ret; 226} 227