1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * fs/ioprio.c 4 * 5 * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk> 6 * 7 * Helper functions for setting/querying io priorities of processes. The 8 * system calls closely mimmick getpriority/setpriority, see the man page for 9 * those. The prio argument is a composite of prio class and prio data, where 10 * the data argument has meaning within that class. The standard scheduling 11 * classes have 8 distinct prio levels, with 0 being the highest prio and 7 12 * being the lowest. 13 * 14 * IOW, setting BE scheduling class with prio 2 is done ala: 15 * 16 * unsigned int prio = (IOPRIO_CLASS_BE << IOPRIO_CLASS_SHIFT) | 2; 17 * 18 * ioprio_set(PRIO_PROCESS, pid, prio); 19 * 20 * See also Documentation/block/ioprio.rst 21 * 22 */ 23 #include <linux/gfp.h> 24 #include <linux/kernel.h> 25 #include <linux/export.h> 26 #include <linux/ioprio.h> 27 #include <linux/cred.h> 28 #include <linux/blkdev.h> 29 #include <linux/capability.h> 30 #include <linux/sched/user.h> 31 #include <linux/sched/task.h> 32 #include <linux/syscalls.h> 33 #include <linux/security.h> 34 #include <linux/pid_namespace.h> 35 36 int set_task_ioprio(struct task_struct *task, int ioprio) 37 { 38 int err; 39 struct io_context *ioc; 40 const struct cred *cred = current_cred(), *tcred; 41 42 rcu_read_lock(); 43 tcred = __task_cred(task); 44 if (!uid_eq(tcred->uid, cred->euid) && 45 !uid_eq(tcred->uid, cred->uid) && !capable(CAP_SYS_NICE)) { 46 rcu_read_unlock(); 47 return -EPERM; 48 } 49 rcu_read_unlock(); 50 51 err = security_task_setioprio(task, ioprio); 52 if (err) 53 return err; 54 55 ioc = get_task_io_context(task, GFP_ATOMIC, NUMA_NO_NODE); 56 if (ioc) { 57 ioc->ioprio = ioprio; 58 put_io_context(ioc); 59 } 60 61 return err; 62 } 63 EXPORT_SYMBOL_GPL(set_task_ioprio); 64 65 int ioprio_check_cap(int ioprio) 66 { 67 int class = IOPRIO_PRIO_CLASS(ioprio); 68 int data = IOPRIO_PRIO_DATA(ioprio); 69 70 switch (class) { 71 case IOPRIO_CLASS_RT: 72 if (!capable(CAP_SYS_NICE) && !capable(CAP_SYS_ADMIN)) 73 return -EPERM; 74 fallthrough; 75 /* rt has prio field too */ 76 case IOPRIO_CLASS_BE: 77 if (data >= IOPRIO_NR_LEVELS || data < 0) 78 return -EINVAL; 79 break; 80 case IOPRIO_CLASS_IDLE: 81 break; 82 case IOPRIO_CLASS_NONE: 83 if (data) 84 return -EINVAL; 85 break; 86 default: 87 return -EINVAL; 88 } 89 90 return 0; 91 } 92 93 SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) 94 { 95 struct task_struct *p, *g; 96 struct user_struct *user; 97 struct pid *pgrp; 98 kuid_t uid; 99 int ret; 100 101 ret = ioprio_check_cap(ioprio); 102 if (ret) 103 return ret; 104 105 ret = -ESRCH; 106 rcu_read_lock(); 107 switch (which) { 108 case IOPRIO_WHO_PROCESS: 109 if (!who) 110 p = current; 111 else 112 p = find_task_by_vpid(who); 113 if (p) 114 ret = set_task_ioprio(p, ioprio); 115 break; 116 case IOPRIO_WHO_PGRP: 117 if (!who) 118 pgrp = task_pgrp(current); 119 else 120 pgrp = find_vpid(who); 121 122 read_lock(&tasklist_lock); 123 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 124 ret = set_task_ioprio(p, ioprio); 125 if (ret) { 126 read_unlock(&tasklist_lock); 127 goto out; 128 } 129 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 130 read_unlock(&tasklist_lock); 131 132 break; 133 case IOPRIO_WHO_USER: 134 uid = make_kuid(current_user_ns(), who); 135 if (!uid_valid(uid)) 136 break; 137 if (!who) 138 user = current_user(); 139 else 140 user = find_user(uid); 141 142 if (!user) 143 break; 144 145 for_each_process_thread(g, p) { 146 if (!uid_eq(task_uid(p), uid) || 147 !task_pid_vnr(p)) 148 continue; 149 ret = set_task_ioprio(p, ioprio); 150 if (ret) 151 goto free_uid; 152 } 153 free_uid: 154 if (who) 155 free_uid(user); 156 break; 157 default: 158 ret = -EINVAL; 159 } 160 161 out: 162 rcu_read_unlock(); 163 return ret; 164 } 165 166 static int get_task_ioprio(struct task_struct *p) 167 { 168 int ret; 169 170 ret = security_task_getioprio(p); 171 if (ret) 172 goto out; 173 ret = IOPRIO_DEFAULT; 174 task_lock(p); 175 if (p->io_context) 176 ret = p->io_context->ioprio; 177 task_unlock(p); 178 out: 179 return ret; 180 } 181 182 int ioprio_best(unsigned short aprio, unsigned short bprio) 183 { 184 if (!ioprio_valid(aprio)) 185 aprio = IOPRIO_DEFAULT; 186 if (!ioprio_valid(bprio)) 187 bprio = IOPRIO_DEFAULT; 188 189 return min(aprio, bprio); 190 } 191 192 SYSCALL_DEFINE2(ioprio_get, int, which, int, who) 193 { 194 struct task_struct *g, *p; 195 struct user_struct *user; 196 struct pid *pgrp; 197 kuid_t uid; 198 int ret = -ESRCH; 199 int tmpio; 200 201 rcu_read_lock(); 202 switch (which) { 203 case IOPRIO_WHO_PROCESS: 204 if (!who) 205 p = current; 206 else 207 p = find_task_by_vpid(who); 208 if (p) 209 ret = get_task_ioprio(p); 210 break; 211 case IOPRIO_WHO_PGRP: 212 if (!who) 213 pgrp = task_pgrp(current); 214 else 215 pgrp = find_vpid(who); 216 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) { 217 tmpio = get_task_ioprio(p); 218 if (tmpio < 0) 219 continue; 220 if (ret == -ESRCH) 221 ret = tmpio; 222 else 223 ret = ioprio_best(ret, tmpio); 224 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); 225 break; 226 case IOPRIO_WHO_USER: 227 uid = make_kuid(current_user_ns(), who); 228 if (!who) 229 user = current_user(); 230 else 231 user = find_user(uid); 232 233 if (!user) 234 break; 235 236 for_each_process_thread(g, p) { 237 if (!uid_eq(task_uid(p), user->uid) || 238 !task_pid_vnr(p)) 239 continue; 240 tmpio = get_task_ioprio(p); 241 if (tmpio < 0) 242 continue; 243 if (ret == -ESRCH) 244 ret = tmpio; 245 else 246 ret = ioprio_best(ret, tmpio); 247 } 248 249 if (who) 250 free_uid(user); 251 break; 252 default: 253 ret = -EINVAL; 254 } 255 256 rcu_read_unlock(); 257 return ret; 258 } 259