aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/ioprio.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/fs/ioprio.c b/fs/ioprio.c
index e4e01bc7f338..c4a1c3c65aac 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -41,18 +41,28 @@ 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 } while (1);
50 58
51 if (ioc) 59 if (!err) {
60 ioc->ioprio = ioprio;
52 ioc->ioprio_changed = 1; 61 ioc->ioprio_changed = 1;
62 }
53 63
54 task_unlock(task); 64 task_unlock(task);
55 return 0; 65 return err;
56} 66}
57 67
58asmlinkage long sys_ioprio_set(int which, int who, int ioprio) 68asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
@@ -75,8 +85,6 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
75 85
76 break; 86 break;
77 case IOPRIO_CLASS_IDLE: 87 case IOPRIO_CLASS_IDLE:
78 if (!capable(CAP_SYS_ADMIN))
79 return -EPERM;
80 break; 88 break;
81 case IOPRIO_CLASS_NONE: 89 case IOPRIO_CLASS_NONE:
82 if (data) 90 if (data)
@@ -148,7 +156,9 @@ static int get_task_ioprio(struct task_struct *p)
148 ret = security_task_getioprio(p); 156 ret = security_task_getioprio(p);
149 if (ret) 157 if (ret)
150 goto out; 158 goto out;
151 ret = p->ioprio; 159 ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
160 if (p->io_context)
161 ret = p->io_context->ioprio;
152out: 162out:
153 return ret; 163 return ret;
154} 164}