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.18-rc7 227 lines 4.7 kB view raw
1/* 2 * fs/ioprio.c 3 * 4 * Copyright (C) 2004 Jens Axboe <axboe@suse.de> 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 && ioc->set_ioprio) 51 ioc->set_ioprio(ioc, ioprio); 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 read_lock_irq(&tasklist_lock); 85 switch (which) { 86 case IOPRIO_WHO_PROCESS: 87 if (!who) 88 p = current; 89 else 90 p = find_task_by_pid(who); 91 if (p) 92 ret = set_task_ioprio(p, ioprio); 93 break; 94 case IOPRIO_WHO_PGRP: 95 if (!who) 96 who = process_group(current); 97 do_each_task_pid(who, PIDTYPE_PGID, p) { 98 ret = set_task_ioprio(p, ioprio); 99 if (ret) 100 break; 101 } while_each_task_pid(who, PIDTYPE_PGID, p); 102 break; 103 case IOPRIO_WHO_USER: 104 if (!who) 105 user = current->user; 106 else 107 user = find_user(who); 108 109 if (!user) 110 break; 111 112 do_each_thread(g, p) { 113 if (p->uid != who) 114 continue; 115 ret = set_task_ioprio(p, ioprio); 116 if (ret) 117 goto free_uid; 118 } while_each_thread(g, p); 119free_uid: 120 if (who) 121 free_uid(user); 122 break; 123 default: 124 ret = -EINVAL; 125 } 126 127 read_unlock_irq(&tasklist_lock); 128 return ret; 129} 130 131static int get_task_ioprio(struct task_struct *p) 132{ 133 int ret; 134 135 ret = security_task_getioprio(p); 136 if (ret) 137 goto out; 138 ret = p->ioprio; 139out: 140 return ret; 141} 142 143int ioprio_best(unsigned short aprio, unsigned short bprio) 144{ 145 unsigned short aclass = IOPRIO_PRIO_CLASS(aprio); 146 unsigned short bclass = IOPRIO_PRIO_CLASS(bprio); 147 148 if (!ioprio_valid(aprio)) 149 return bprio; 150 if (!ioprio_valid(bprio)) 151 return aprio; 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_irq(&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_irq(&tasklist_lock); 225 return ret; 226} 227