[PATCH] V850: user ARRAY_SIZE macro when appropriate
[sfrench/cifs-2.6.git] / fs / ioprio.c
index 93aa5715f224cd5163e070473dc04e6d76409667..89e8da112a75e46cfa6aa6bef831266b07edf835 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * fs/ioprio.c
  *
- * Copyright (C) 2004 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 2004 Jens Axboe <axboe@kernel.dk>
  *
  * Helper functions for setting/querying io priorities of processes. The
  * system calls closely mimmick getpriority/setpriority, see the man page for
@@ -44,8 +44,11 @@ static int set_task_ioprio(struct task_struct *task, int ioprio)
        task->ioprio = ioprio;
 
        ioc = task->io_context;
-       if (ioc && ioc->set_ioprio)
-               ioc->set_ioprio(ioc, ioprio);
+       /* see wmb() in current_io_context() */
+       smp_read_barrier_depends();
+
+       if (ioc)
+               ioc->ioprio_changed = 1;
 
        task_unlock(task);
        return 0;
@@ -78,7 +81,12 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
        }
 
        ret = -ESRCH;
-       read_lock_irq(&tasklist_lock);
+       /*
+        * We want IOPRIO_WHO_PGRP/IOPRIO_WHO_USER to be "atomic",
+        * so we can't use rcu_read_lock(). See re-copy of ->ioprio
+        * in copy_process().
+        */
+       read_lock(&tasklist_lock);
        switch (which) {
                case IOPRIO_WHO_PROCESS:
                        if (!who)
@@ -111,9 +119,9 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                                        continue;
                                ret = set_task_ioprio(p, ioprio);
                                if (ret)
-                                       break;
+                                       goto free_uid;
                        } while_each_thread(g, p);
-
+free_uid:
                        if (who)
                                free_uid(user);
                        break;
@@ -121,7 +129,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
                        ret = -EINVAL;
        }
 
-       read_unlock_irq(&tasklist_lock);
+       read_unlock(&tasklist_lock);
        return ret;
 }
 
@@ -137,6 +145,24 @@ out:
        return ret;
 }
 
+int ioprio_best(unsigned short aprio, unsigned short bprio)
+{
+       unsigned short aclass = IOPRIO_PRIO_CLASS(aprio);
+       unsigned short bclass = IOPRIO_PRIO_CLASS(bprio);
+
+       if (aclass == IOPRIO_CLASS_NONE)
+               aclass = IOPRIO_CLASS_BE;
+       if (bclass == IOPRIO_CLASS_NONE)
+               bclass = IOPRIO_CLASS_BE;
+
+       if (aclass == bclass)
+               return min(aprio, bprio);
+       if (aclass > bclass)
+               return bprio;
+       else
+               return aprio;
+}
+
 asmlinkage long sys_ioprio_get(int which, int who)
 {
        struct task_struct *g, *p;
@@ -144,7 +170,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
        int ret = -ESRCH;
        int tmpio;
 
-       read_lock_irq(&tasklist_lock);
+       read_lock(&tasklist_lock);
        switch (which) {
                case IOPRIO_WHO_PROCESS:
                        if (!who)
@@ -195,7 +221,7 @@ asmlinkage long sys_ioprio_get(int which, int who)
                        ret = -EINVAL;
        }
 
-       read_unlock_irq(&tasklist_lock);
+       read_unlock(&tasklist_lock);
        return ret;
 }