diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ioprio.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/fs/ioprio.c b/fs/ioprio.c index e4e01bc7f338..a7600401ecf7 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -41,18 +41,29 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) | |||
41 | return err; | 41 | return err; |
42 | 42 | ||
43 | task_lock(task); | 43 | task_lock(task); |
44 | do { | ||
45 | ioc = task->io_context; | ||
46 | /* see wmb() in current_io_context() */ | ||
47 | smp_read_barrier_depends(); | ||
48 | if (ioc) | ||
49 | break; | ||
44 | 50 | ||
45 | task->ioprio = ioprio; | 51 | ioc = alloc_io_context(GFP_ATOMIC, -1); |
46 | 52 | if (!ioc) { | |
47 | ioc = task->io_context; | 53 | err = -ENOMEM; |
48 | /* see wmb() in current_io_context() */ | 54 | break; |
49 | smp_read_barrier_depends(); | 55 | } |
56 | task->io_context = ioc; | ||
57 | ioc->task = task; | ||
58 | } while (1); | ||
50 | 59 | ||
51 | if (ioc) | 60 | if (!err) { |
61 | ioc->ioprio = ioprio; | ||
52 | ioc->ioprio_changed = 1; | 62 | ioc->ioprio_changed = 1; |
63 | } | ||
53 | 64 | ||
54 | task_unlock(task); | 65 | task_unlock(task); |
55 | return 0; | 66 | return err; |
56 | } | 67 | } |
57 | 68 | ||
58 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | 69 | asmlinkage long sys_ioprio_set(int which, int who, int ioprio) |
@@ -148,7 +159,9 @@ static int get_task_ioprio(struct task_struct *p) | |||
148 | ret = security_task_getioprio(p); | 159 | ret = security_task_getioprio(p); |
149 | if (ret) | 160 | if (ret) |
150 | goto out; | 161 | goto out; |
151 | ret = p->ioprio; | 162 | ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM); |
163 | if (p->io_context) | ||
164 | ret = p->io_context->ioprio; | ||
152 | out: | 165 | out: |
153 | return ret; | 166 | return ret; |
154 | } | 167 | } |