# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/12/13 08:49:27-05:00 jeffpc@optonline.net 
#   cfq-iosched.c:
#     Fixup
# 
# drivers/block/cfq-iosched.c
#   2004/12/13 08:48:39-05:00 jeffpc@optonline.net +2 -0
#   Fixup
# 
# ChangeSet
#   2004/12/12 23:54:22-05:00 jeffpc@optonline.net 
#   cfq-iosched.c:
#     Changed slice lengths and scaling factors
# 
# drivers/block/cfq-iosched.c
#   2004/12/12 23:53:11-05:00 jeffpc@optonline.net +11 -11
#   Changed slice lengths and scaling factors
# 
# ChangeSet
#   2004/12/12 22:17:02-05:00 jeffpc@optonline.net 
#   Use iosched neutral defines
# 
# init/main.c
#   2004/12/12 22:16:50-05:00 jeffpc@optonline.net +1 -0
#   Set current->io_prio to the default value
# 
# include/linux/resource.h
#   2004/12/12 22:16:50-05:00 jeffpc@optonline.net +4 -0
#   IOscheduler neutral priority defines
# 
# drivers/block/cfq-iosched.c
#   2004/12/12 22:16:50-05:00 jeffpc@optonline.net +2 -2
#   Use the iosched neutral defines
# 
# ChangeSet
#   2004/12/12 16:34:13-05:00 jeffpc@optonline.net 
#   Fix
# 
# kernel/sys.c
#   2004/12/12 16:34:01-05:00 jeffpc@optonline.net +1 -1
#   Fix
# 
# kernel/sched.c
#   2004/12/12 16:34:01-05:00 jeffpc@optonline.net +0 -9
#   Remove ioprio from renicing-code
# 
# ChangeSet
#   2004/12/12 14:00:43-05:00 jeffpc@optonline.net 
#   Clean up from a merge
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# drivers/block/cfq-iosched.c
#   2004/12/12 14:00:30-05:00 jeffpc@optonline.net +0 -3
#   Cleanup
# 
# ChangeSet
#   2004/12/12 13:54:13-05:00 jeffpc@optonline.net 
#   Make io priorities 0..39 instead of a nice-like -20..19
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sys.c
#   2004/12/12 13:54:00-05:00 jeffpc@optonline.net +7 -13
#   Make io priorities 0..39 instead of a nice-like -20..19
# 
# kernel/sched.c
#   2004/12/12 13:54:00-05:00 jeffpc@optonline.net +15 -16
#   Make io priorities 0..39 instead of a nice-like -20..19
# 
# ChangeSet
#   2004/12/12 11:52:09-05:00 jeffpc@optonline.net 
#   Clean up unused variables
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# drivers/block/ll_rw_blk.c
#   2004/12/12 11:51:57-05:00 jeffpc@optonline.net +0 -1
#   Clean up unused variables
# 
# drivers/block/cfq-iosched.c
#   2004/12/12 11:51:57-05:00 jeffpc@optonline.net +0 -1
#   Clean up unused variables
# 
# ChangeSet
#   2004/12/12 10:45:22-05:00 jeffpc@optonline.net 
#   Manual/Auto merge
# 
# drivers/block/cfq-iosched.c
#   2004/12/12 10:45:13-05:00 jeffpc@optonline.net +0 -132
#   Manual merge
# 
# kernel/sched.c
#   2004/12/12 10:34:17-05:00 jeffpc@optonline.net +0 -35
#   Auto merged
# 
# include/linux/sched.h
#   2004/12/12 10:34:17-05:00 jeffpc@optonline.net +0 -1
#   Auto merged
# 
# include/linux/blkdev.h
#   2004/12/12 10:34:17-05:00 jeffpc@optonline.net +0 -7
#   Auto merged
# 
# drivers/block/ll_rw_blk.c
#   2004/12/12 10:34:17-05:00 jeffpc@optonline.net +0 -2
#   Auto merged
# 
# ChangeSet
#   2004/12/11 12:42:25-05:00 jeffpc@optonline.net 
#   Update to Jens Axboe's #4 version
# 
# kernel/sched.c
#   2004/12/11 11:55:49-05:00 jeffpc@optonline.net +35 -0
#   Import patch n4-3
# 
# include/linux/sched.h
#   2004/12/11 11:55:48-05:00 jeffpc@optonline.net +1 -0
#   Import patch n4-3
# 
# include/linux/blkdev.h
#   2004/12/11 11:55:49-05:00 jeffpc@optonline.net +7 -8
#   Import patch n4-3
# 
# drivers/block/ll_rw_blk.c
#   2004/12/11 11:55:49-05:00 jeffpc@optonline.net +3 -2
#   Import patch n4-3
# 
# drivers/block/cfq-iosched.c
#   2004/12/11 12:33:15-05:00 jeffpc@optonline.net +137 -74
#   Import patch n4-3
# 
# ChangeSet
#   2004/12/10 20:38:05-05:00 jeffpc@optonline.net 
#   Added 2 syscalls sys_{get,set}iopriority(). Both 99% compied
#   from sys_{get,set}priority()
#   Added task_ioprio()
#   Little cleanup
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sys.c
#   2004/12/10 20:37:47-05:00 jeffpc@optonline.net +121 -10
#   Little clean up
#   Added sys_{set,get}iopriority()
# 
# kernel/sched.c
#   2004/12/10 20:37:47-05:00 jeffpc@optonline.net +9 -1
#   Tiny clean up
#   Added task_ioprio()
# 
# include/linux/sched.h
#   2004/12/10 20:37:47-05:00 jeffpc@optonline.net +1 -0
#   Added prototype for task_ioprio()
# 
# include/asm-i386/unistd.h
#   2004/12/10 20:37:47-05:00 jeffpc@optonline.net +3 -1
#   Added 2 syscalls sys_{get,set}iopriority(). Both 99% compied
#   from sys_{get,set}priority()
# 
# arch/i386/kernel/entry.S
#   2004/12/10 20:37:47-05:00 jeffpc@optonline.net +2 -0
#   Added 2 syscalls sys_{get,set}iopriority(). Both 99% compied
#   from sys_{get,set}priority()
# 
# ChangeSet
#   2004/12/08 18:07:26-05:00 jeffpc@optonline.net 
#   Changed sys_setpriority()
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sys.c
#   2004/12/08 18:07:11-05:00 jeffpc@optonline.net +26 -2
#   Added set_one_ioprio()
#   Changed sys_setpriority() to modify io_prio as well
# 
# kernel/sched.c
#   2004/12/08 18:07:11-05:00 jeffpc@optonline.net +1 -1
#   Display NICE-level ioprio
# 
# include/linux/sched.h
#   2004/12/08 18:07:11-05:00 jeffpc@optonline.net +1 -0
#   Added set_user_ioprio() prototype
# 
# ChangeSet
#   2004/12/08 17:00:00-05:00 jeffpc@optonline.net 
#   Added sys_io_prio() syscall
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sched.c
#   2004/12/08 16:59:46-05:00 jeffpc@optonline.net +37 -21
#   Cleaned up set_user_ioprio()
#   Added sys_io_prio()
# 
# include/asm-i386/unistd.h
#   2004/12/08 16:59:45-05:00 jeffpc@optonline.net +2 -1
#   Added sys_io_prio syscall number
# 
# arch/i386/kernel/entry.S
#   2004/12/08 16:59:45-05:00 jeffpc@optonline.net +1 -0
#   Added sys_io_prio to sys_call_table
# 
# ChangeSet
#   2004/12/06 10:10:15-05:00 jeffpc@optonline.net 
#   Fix compilation
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sched.c
#   2004/12/06 10:09:58-05:00 jeffpc@optonline.net +1 -3
#   Fix compilation
# 
# drivers/block/cfq-iosched.c
#   2004/12/06 10:09:58-05:00 jeffpc@optonline.net +1 -0
#   Fix compilation
# 
# ChangeSet
#   2004/12/05 22:11:23-05:00 jeffpc@optonline.net 
#   Changed default sync and async cfq slice times
#   Added prio table to cfq
#   Added io_prio to task_struct
#   Added security_task_setioprio()
#   Added set_user_ioprio(), NICE_TO_IOPRIO(), IOPRIO_TO_NICE(),
#   TASK_IOPRIO(). Additionally, sys_nice() now changes io_prio
#   by the same increment as the nice value.
#   
#   Signed-off-by: Josef "Jeff" Sipek <jeffpc@optonline.net>
# 
# kernel/sched.c
#   2004/12/05 22:11:13-05:00 jeffpc@optonline.net +40 -0
#   Added set_user_ioprio(), NICE_TO_IOPRIO(), IOPRIO_TO_NICE(),
#   TASK_IOPRIO(). Additionally, sys_nice() now changes io_prio
#   by the same increment as the nice value.
# 
# include/linux/security.h
#   2004/12/05 22:11:13-05:00 jeffpc@optonline.net +12 -0
#   Added security_task_setioprio
# 
# include/linux/sched.h
#   2004/12/05 22:11:13-05:00 jeffpc@optonline.net +3 -0
#   Added io_prio to task_struct
# 
# drivers/block/cfq-iosched.c
#   2004/12/05 22:11:13-05:00 jeffpc@optonline.net +19 -3
#   Changed the default sync and async slice time
#   Added prio/slice-scaling table
# 
diff -Nru a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S	2004-12-13 08:49:48 -05:00
+++ b/arch/i386/kernel/entry.S	2004-12-13 08:49:48 -05:00
@@ -864,5 +864,8 @@
 	.long sys_add_key
 	.long sys_request_key
 	.long sys_keyctl
+	.long sys_io_prio
+	.long sys_getiopriority		/* 290 */
+	.long sys_setiopriority
 
 syscall_table_size=(.-sys_call_table)
diff -Nru a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c
--- a/drivers/block/cfq-iosched.c	2004-12-13 08:49:48 -05:00
+++ b/drivers/block/cfq-iosched.c	2004-12-13 08:49:48 -05:00
@@ -33,10 +33,20 @@
 static int cfq_back_max = 16 * 1024;	/* maximum backwards seek, in KiB */
 static int cfq_back_penalty = 2;	/* penalty of a backwards seek */
 
-static int cfq_slice_sync = HZ / 10;
-static int cfq_slice_async = HZ / 25;
+static int cfq_slice_sync = HZ / 1000;
+static int cfq_slice_async = HZ / 1000;
 static int cfq_slice_async_rq = 16;
-static int cfq_slice_idle = HZ / 249;
+static int cfq_slice_idle = HZ / 1000;
+
+/* the slice scaling factors */
+static int cfq_prio_scale[] = {223, 194, 169, 147, 128,		/* 0..4 */
+			       111,  97,  84,  73,  64,		/* 5..9 */
+			        56,  49,  42,  36,  32,		/* 10..14 */
+			        28,  24,  21,  18,  16,		/* 15..19 */
+			        14,  12,  11,   9,   8,		/* 20..24 */
+			         7,   6,   5,   5,   4,		/* 25..29 */
+			         3,   3,   2,   2,   2,		/* 30..34 */
+			         1,   1,   1,   1,   1};	/* 35..39 */
 
 static int cfq_max_depth = 4;
 
@@ -98,6 +108,9 @@
  */
 #define CFQ_KEY_SPARE		(~0UL)
 
+#define CFQ_MIN_IO_PRIO		IOPRIO_MIN
+#define CFQ_MAX_IO_PRIO		IOPRIO_MAX
+
 static kmem_cache_t *crq_pool;
 static kmem_cache_t *cfq_pool;
 static kmem_cache_t *cfq_ioc_pool;
@@ -133,6 +146,7 @@
 	struct work_struct unplug_work;
 	struct cfq_queue *active_queue;
 	unsigned int dispatch_slice;
+	unsigned int cfq_prio_scale[(CFQ_MAX_IO_PRIO - CFQ_MIN_IO_PRIO) + 1];
 
 	/*
 	 * tunables, see top of file
@@ -176,6 +190,7 @@
 	unsigned long last_fifo_expire;
 
 	int key_type;
+	int io_prio;
 
 	unsigned long slice_start;
 	unsigned long slice_end;
@@ -912,7 +927,7 @@
 	 * sync, use the sync time slice value
 	 */
 	if (!cfqq->slice_end)
-		cfqq->slice_end = cfqd->cfq_slice[!!sync] + jiffies;
+		cfqq->slice_end = cfqd->cfq_prio_scale[cfqq->io_prio]*cfqd->cfq_slice[!!sync] + jiffies;
 
 	/*
 	 * expire an async queue immediately if it has used up its slice
@@ -946,7 +961,6 @@
 {
 	struct cfq_queue *cfqq = crq->cfq_queue;
 	struct cfq_data *cfqd = cfqq->cfqd;
-	unsigned long now, elapsed;
 
 	if (unlikely(!blk_fs_request(crq->request)))
 		return;
@@ -972,13 +986,13 @@
 		WARN_ON(!cfqd->rq_in_driver);
 		cfqd->rq_in_driver--;
 	}
-
+  
 	/*
 	 * queue was preempted while this request was servicing
 	 */
 	if (cfqd->active_queue != cfqq)
 		return;
-
+  
 	/*
 	 * this is still the active queue. if we have nothing to do and no
 	 * more pending requests in flight, wait for a new sync request if
@@ -1093,6 +1107,7 @@
 		*cfqq = __cfqq;
 	}
 
+	__cfqq->io_prio = current->io_prio;
 	cic->cfqq = __cfqq;
 	spin_unlock_irqrestore(cfqd->queue->queue_lock, flags);
 }
@@ -1744,6 +1759,7 @@
 	cfqd->cfq_slice_async_rq = cfq_slice_async_rq;
 	cfqd->cfq_slice_idle = cfq_slice_idle;
 	cfqd->cfq_max_depth = cfq_max_depth;
+	memcpy(cfqd->cfq_prio_scale, cfq_prio_scale, sizeof(cfq_prio_scale));
 
 	return 0;
 out_spare:
diff -Nru a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h
--- a/include/asm-i386/unistd.h	2004-12-13 08:49:48 -05:00
+++ b/include/asm-i386/unistd.h	2004-12-13 08:49:48 -05:00
@@ -294,8 +294,11 @@
 #define __NR_add_key		286
 #define __NR_request_key	287
 #define __NR_keyctl		288
+#define __NR_io_prio		289
+#define __NR_getiopriority	290
+#define __NR_setiopriority	291
 
-#define NR_syscalls 289
+#define NR_syscalls 292
 
 /*
  * user-visible error numbers are in the range -1 - -128: see
diff -Nru a/include/linux/resource.h b/include/linux/resource.h
--- a/include/linux/resource.h	2004-12-13 08:49:48 -05:00
+++ b/include/linux/resource.h	2004-12-13 08:49:48 -05:00
@@ -42,6 +42,10 @@
 	unsigned long	rlim_max;
 };
 
+#define IOPRIO_MIN	0
+#define IOPRIO_MAX	39
+#define IOPRIO_DEFAULT	20
+
 #define	PRIO_MIN	(-20)
 #define	PRIO_MAX	20
 
diff -Nru a/include/linux/sched.h b/include/linux/sched.h
--- a/include/linux/sched.h	2004-12-13 08:49:48 -05:00
+++ b/include/linux/sched.h	2004-12-13 08:49:48 -05:00
@@ -664,6 +664,9 @@
   	struct mempolicy *mempolicy;
   	short il_next;		/* could be shared with used_math */
 #endif
+
+/* io priority */
+	short io_prio;
 };
 
 static inline pid_t process_group(struct task_struct *tsk)
@@ -723,8 +726,10 @@
 
 extern void sched_idle_next(void);
 extern void set_user_nice(task_t *p, long nice);
+extern void set_user_ioprio(task_t *p, long ioprio);
 extern int task_prio(const task_t *p);
 extern int task_nice(const task_t *p);
+extern int task_ioprio(const task_t *p);
 extern int task_curr(const task_t *p);
 extern int idle_cpu(int cpu);
 extern unsigned long task_will_schedule_at(const task_t *p);
diff -Nru a/include/linux/security.h b/include/linux/security.h
--- a/include/linux/security.h	2004-12-13 08:49:48 -05:00
+++ b/include/linux/security.h	2004-12-13 08:49:48 -05:00
@@ -1717,6 +1717,13 @@
 	return security_ops->task_setnice (p, nice);
 }
 
+static inline int security_task_setioprio (struct task_struct *p, int prio)
+{
+	#warn "Fixme! Add security_ops->task_setprio"
+	return 1;
+	//return security_ops->task_setioprio (p, prio);
+}
+
 static inline int security_task_setrlimit (unsigned int resource,
 					   struct rlimit *new_rlim)
 {
@@ -2353,6 +2360,11 @@
 }
 
 static inline int security_task_setnice (struct task_struct *p, int nice)
+{
+	return 0;
+}
+
+static inline int security_task_setioprio (struct task_struct *p, int prio)
 {
 	return 0;
 }
diff -Nru a/init/main.c b/init/main.c
--- a/init/main.c	2004-12-13 08:49:48 -05:00
+++ b/init/main.c	2004-12-13 08:49:48 -05:00
@@ -443,6 +443,7 @@
 static void noinline rest_init(void)
 	__releases(kernel_lock)
 {
+	current->io_prio = IOPRIO_DEFAULT;
 	kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
 	numa_default_policy();
 	unlock_kernel();
diff -Nru a/kernel/sched.c b/kernel/sched.c
--- a/kernel/sched.c	2004-12-13 08:49:48 -05:00
+++ b/kernel/sched.c	2004-12-13 08:49:48 -05:00
@@ -16,6 +16,7 @@
  *		by Davide Libenzi, preemptible kernel bits by Robert Love.
  *  2003-09-03	Interactivity tuning by Con Kolivas.
  *  2004-04-02	Scheduler domains code by Nick Piggin
+ *  2004-12-07	IO Priorities
  */
 
 #include <linux/mm.h>
@@ -63,6 +64,8 @@
 #define PRIO_TO_NICE(prio)	((prio) - MAX_RT_PRIO - 20)
 #define TASK_NICE(p)		PRIO_TO_NICE((p)->static_prio)
 
+#define TASK_IOPRIO(p)		((p)->io_prio)
+
 /*
  * 'User priority' is the nice value converted to something we
  * can work with better when scaling various scheduler parameters,
@@ -3024,6 +3027,17 @@
 
 EXPORT_SYMBOL(set_user_nice);
 
+void set_user_ioprio(task_t *p, long ioprio)
+{
+	if (TASK_IOPRIO(p) == ioprio || ioprio < 0 || ioprio > 39)
+		return;
+	
+	p->io_prio = ioprio;
+	printk(KERN_ERR "task %d now has io_prio = %d\n", p->pid, p->io_prio);
+}
+
+EXPORT_SYMBOL(set_user_ioprio);
+
 #ifdef __ARCH_WANT_SYS_NICE
 
 /*
@@ -3068,6 +3082,35 @@
 
 #endif
 
+/*
+ * sys_ioprio - change the io priority of the current process.
+ * @increment: priority increment
+ */
+asmlinkage long sys_io_prio(int increment)
+{
+	long io_prio;
+
+	if (increment < 0) {
+		if (!capable(CAP_SYS_NICE))
+			return -EPERM;
+		if (increment < -40)
+			increment = -40;
+	}
+	if (increment > 40)
+		increment = 40;
+
+	io_prio = current->io_prio + increment;
+	if (io_prio < 0)
+		io_prio = 0;
+	if (io_prio > 39)
+		io_prio = 39;
+
+#warning "Fixme: add call to security_task_setioprio()"
+
+	set_user_ioprio(current, io_prio);
+	return 0;
+}
+
 /**
  * task_prio - return the priority value of a given task.
  * @p: the task in question.
@@ -3088,6 +3131,15 @@
 int task_nice(const task_t *p)
 {
 	return TASK_NICE(p);
+}
+
+/**
+ * task_ioprio - return the ioprio value of a given task.
+ * @p: the task in question.
+ */
+int task_ioprio(const task_t *p)
+{
+	return TASK_IOPRIO(p);
 }
 
 /**
diff -Nru a/kernel/sys.c b/kernel/sys.c
--- a/kernel/sys.c	2004-12-13 08:49:48 -05:00
+++ b/kernel/sys.c	2004-12-13 08:49:48 -05:00
@@ -240,6 +240,23 @@
 	return error;
 }
 
+static int set_one_ioprio(struct task_struct *p, int prioval, int error)
+{
+	if (p->uid != current->euid &&
+		p->uid != current->uid && !capable(CAP_SYS_NICE)) {
+		error = -EPERM;
+		goto out;
+	}
+	if (prioval < task_ioprio(p) && !capable(CAP_SYS_NICE)) {
+		error = -EACCES;
+		goto out;
+	}
+	#warning "FIXME: call security_task_setioprio(p, prioval);"
+	set_user_ioprio(p, prioval);
+out:
+	return error;
+}
+
 asmlinkage long sys_setpriority(int which, int who, int niceval)
 {
 	struct task_struct *g, *p;
@@ -357,6 +374,118 @@
 	return retval;
 }
 
+asmlinkage long sys_setiopriority(int which, int who, int prioval)
+{
+	struct task_struct *g, *p;
+	struct user_struct *user;
+	int error = -EINVAL;
+
+	if (which > 2 || which < 0)
+		goto out;
+
+	/* normalize: avoid signed division (rounding problems) */
+	error = -ESRCH;
+	if (prioval < 0)
+		prioval = 0;
+	if (prioval > 39)
+		prioval = 39;
+
+	read_lock(&tasklist_lock);
+	switch (which) {
+		case PRIO_PROCESS:
+			if (!who)
+				who = current->pid;
+			p = find_task_by_pid(who);
+			if (p) {
+				error = set_one_ioprio(p, prioval, error);
+			}
+			break;
+		case PRIO_PGRP:
+			if (!who)
+				who = process_group(current);
+			do_each_task_pid(who, PIDTYPE_PGID, p) {
+				error = set_one_ioprio(p, prioval, error);
+			} while_each_task_pid(who, PIDTYPE_PGID, p);
+			break;
+		case PRIO_USER:
+			if (!who)
+				user = current->user;
+			else
+				user = find_user(who);
+
+			if (!user)
+				goto out_unlock;
+
+			do_each_thread(g, p)
+				if (p->uid == who) {
+					error = set_one_ioprio(p, prioval, error);
+				}
+			while_each_thread(g, p);
+			if (who)
+				free_uid(user);		/* For find_user() */
+			break;
+	}
+out_unlock:
+	read_unlock(&tasklist_lock);
+out:
+	return error;
+}
+
+asmlinkage long sys_getiopriority(int which, int who)
+{
+	struct task_struct *g, *p;
+	struct user_struct *user;
+	long prioval, retval = -ESRCH;
+
+	if (which > 2 || which < 0)
+		return -EINVAL;
+
+	read_lock(&tasklist_lock);
+	switch (which) {
+		case PRIO_PROCESS:
+			if (!who)
+				who = current->pid;
+			p = find_task_by_pid(who);
+			if (p) {
+				prioval = task_ioprio(p);
+				if (prioval > retval)
+					retval = prioval;
+			}
+			break;
+		case PRIO_PGRP:
+			if (!who)
+				who = process_group(current);
+			do_each_task_pid(who, PIDTYPE_PGID, p) {
+				prioval = task_ioprio(p);
+				if (prioval > retval)
+					retval = prioval;
+			} while_each_task_pid(who, PIDTYPE_PGID, p);
+			break;
+		case PRIO_USER:
+			if (!who)
+				user = current->user;
+			else
+				user = find_user(who);
+
+			if (!user)
+				goto out_unlock;
+
+			do_each_thread(g, p)
+				if (p->uid == who) {
+					prioval = task_ioprio(p);
+					if (prioval > retval)
+						retval = prioval;
+				}
+			while_each_thread(g, p);
+			if (who)
+				free_uid(user);		/* for find_user() */
+			break;
+	}
+out_unlock:
+	read_unlock(&tasklist_lock);
+
+	return retval;
+}
 
 /*
  * Reboot system call: for obvious reasons only root may call it,
