Merge tag 'printk-for-5.20-sane' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / block / ioprio.c
index 2fe068f..32a456b 100644 (file)
@@ -138,6 +138,32 @@ out:
        return ret;
 }
 
+/*
+ * If the task has set an I/O priority, use that. Otherwise, return
+ * the default I/O priority.
+ *
+ * Expected to be called for current task or with task_lock() held to keep
+ * io_context stable.
+ */
+int __get_task_ioprio(struct task_struct *p)
+{
+       struct io_context *ioc = p->io_context;
+       int prio;
+
+       if (p != current)
+               lockdep_assert_held(&p->alloc_lock);
+       if (ioc)
+               prio = ioc->ioprio;
+       else
+               prio = IOPRIO_DEFAULT;
+
+       if (IOPRIO_PRIO_CLASS(prio) == IOPRIO_CLASS_NONE)
+               prio = IOPRIO_PRIO_VALUE(task_nice_ioclass(p),
+                                        task_nice_ioprio(p));
+       return prio;
+}
+EXPORT_SYMBOL_GPL(__get_task_ioprio);
+
 static int get_task_ioprio(struct task_struct *p)
 {
        int ret;
@@ -145,22 +171,38 @@ static int get_task_ioprio(struct task_struct *p)
        ret = security_task_getioprio(p);
        if (ret)
                goto out;
-       ret = IOPRIO_DEFAULT;
+       task_lock(p);
+       ret = __get_task_ioprio(p);
+       task_unlock(p);
+out:
+       return ret;
+}
+
+/*
+ * Return raw IO priority value as set by userspace. We use this for
+ * ioprio_get(pid, IOPRIO_WHO_PROCESS) so that we keep historical behavior and
+ * also so that userspace can distinguish unset IO priority (which just gets
+ * overriden based on task's nice value) from IO priority set to some value.
+ */
+static int get_task_raw_ioprio(struct task_struct *p)
+{
+       int ret;
+
+       ret = security_task_getioprio(p);
+       if (ret)
+               goto out;
        task_lock(p);
        if (p->io_context)
                ret = p->io_context->ioprio;
+       else
+               ret = IOPRIO_DEFAULT;
        task_unlock(p);
 out:
        return ret;
 }
 
-int ioprio_best(unsigned short aprio, unsigned short bprio)
+static int ioprio_best(unsigned short aprio, unsigned short bprio)
 {
-       if (!ioprio_valid(aprio))
-               aprio = IOPRIO_DEFAULT;
-       if (!ioprio_valid(bprio))
-               bprio = IOPRIO_DEFAULT;
-
        return min(aprio, bprio);
 }
 
@@ -181,7 +223,7 @@ SYSCALL_DEFINE2(ioprio_get, int, which, int, who)
                        else
                                p = find_task_by_vpid(who);
                        if (p)
-                               ret = get_task_ioprio(p);
+                               ret = get_task_raw_ioprio(p);
                        break;
                case IOPRIO_WHO_PGRP:
                        if (!who)