static const char * sprint_ioprio(int ioprio) { static char outstr[256]; const char *str; int class, data; class = IOPRIO_PRIO_CLASS(ioprio); data = IOPRIO_PRIO_DATA(ioprio); str = xlookup(ioprio_class, class); if (str) sprintf(outstr, "IOPRIO_PRIO_VALUE(%s,%d)", str, data); else sprintf(outstr, "IOPRIO_PRIO_VALUE(%#x /* %s */,%d)", class, "IOPRIO_CLASS_???", data); return outstr; }
static void ioprio_print(int pid) { int ioprio = ioprio_get(IOPRIO_WHO_PROCESS, pid); if (ioprio == -1) err(EXIT_FAILURE, _("ioprio_get failed")); else { int ioclass = IOPRIO_PRIO_CLASS(ioprio); const char *name = _("unknown"); if (ioclass > 0 && (size_t) ioclass < ARRAY_SIZE(to_prio)) name = to_prio[ioclass]; if (ioclass != IOPRIO_CLASS_IDLE) printf(_("%s: prio %lu\n"), name, IOPRIO_PRIO_DATA(ioprio)); else printf("%s\n", name); } }
SYSCALL_DEFINE3(ioprio_set, int, which, int, who, int, ioprio) { int class = IOPRIO_PRIO_CLASS(ioprio); int data = IOPRIO_PRIO_DATA(ioprio); struct task_struct *p, *g; struct user_struct *user; struct pid *pgrp; int ret; switch (class) { case IOPRIO_CLASS_RT: if (!capable(CAP_SYS_ADMIN)) return -EPERM; /* fall through, rt has prio field too */ case IOPRIO_CLASS_BE: if (data >= IOPRIO_BE_NR || data < 0) return -EINVAL; break; case IOPRIO_CLASS_IDLE: break; case IOPRIO_CLASS_NONE: if (data) return -EINVAL; break; default: return -EINVAL; } ret = -ESRCH; rcu_read_lock(); switch (which) { case IOPRIO_WHO_PROCESS: if (!who) p = current; else p = find_task_by_vpid(who); if (p) ret = set_task_ioprio(p, ioprio); break; case IOPRIO_WHO_PGRP: if (!who) 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; } while_each_pid_thread(pgrp, PIDTYPE_PGID, p); break; case IOPRIO_WHO_USER: if (!who) user = current_user(); else user = find_user(who); if (!user) break; do_each_thread(g, p) { if (__task_cred(p)->uid != who) continue; ret = set_task_ioprio(p, ioprio); if (ret) goto free_uid; } while_each_thread(g, p); free_uid: if (who) free_uid(user); break; default: ret = -EINVAL; }