OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [fs/] [ioprio.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
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
 
30
static 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
 
58
asmlinkage 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);
132
free_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
 
144
static 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;
152
out:
153
        return ret;
154
}
155
 
156
int 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
 
174
asmlinkage 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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.