summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /kernel
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'kernel')
-rw-r--r--kernel/acct.c231
-rw-r--r--kernel/capability.c12
-rw-r--r--kernel/dma.c3
-rw-r--r--kernel/exec_domain.c4
-rw-r--r--kernel/exit.c51
-rw-r--r--kernel/fork.c14
-rw-r--r--kernel/info.c6
-rw-r--r--kernel/itimer.c36
-rw-r--r--kernel/kmod.c25
-rw-r--r--kernel/ksyms.c42
-rw-r--r--kernel/module.c9
-rw-r--r--kernel/panic.c4
-rw-r--r--kernel/printk.c22
-rw-r--r--kernel/resource.c2
-rw-r--r--kernel/sched.c180
-rw-r--r--kernel/signal.c104
-rw-r--r--kernel/softirq.c11
-rw-r--r--kernel/sys.c21
-rw-r--r--kernel/sysctl.c24
-rw-r--r--kernel/time.c6
20 files changed, 406 insertions, 401 deletions
diff --git a/kernel/acct.c b/kernel/acct.c
index c5b161ae0..110296bca 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -16,6 +16,28 @@
*
* (C) Copyright 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
*
+ * Plugged two leaks. 1) It didn't return acct_file into the free_filps if
+ * the file happened to be read-only. 2) If the accounting was suspended
+ * due to the lack of space it happily allowed to reopen it and completely
+ * lost the old acct_file. 3/10/98, Al Viro.
+ *
+ * Now we silently close acct_file on attempt to reopen. Cleaned sys_acct().
+ * XTerms and EMACS are manifestations of pure evil. 21/10/98, AV.
+ *
+ * Fixed a nasty interaction with with sys_umount(). If the accointing
+ * was suspeneded we failed to stop it on umount(). Messy.
+ * Another one: remount to readonly didn't stop accounting.
+ * Question: what should we do if we have CAP_SYS_ADMIN but not
+ * CAP_SYS_PACCT? Current code does the following: umount returns -EBUSY
+ * unless we are messing with the root. In that case we are getting a
+ * real mess with do_remount_sb(). 9/11/98, AV.
+ *
+ * Fixed a bunch of races (and pair of leaks). Probably not the best way,
+ * but this one obviously doesn't introduce deadlocks. Later. BTW, found
+ * one race (and leak) in BSD implementation.
+ * OK, that's better. ANOTHER race and leak in BSD variant. There always
+ * is one more bug... TODO: move filp_open into open.c and make
+ * parameters sysctl-controllable. 10/11/98, AV.
*/
#include <linux/config.h>
@@ -23,18 +45,8 @@
#include <linux/kernel.h>
#ifdef CONFIG_BSD_PROCESS_ACCT
-#include <linux/fs.h>
-#include <linux/vfs.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/stat.h>
-#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/timer.h>
-#include <linux/tty.h>
#include <linux/acct.h>
-#include <linux/major.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/file.h>
@@ -44,11 +56,13 @@
* These constants control the amount of freespace that suspend and
* resume the process accounting system, and the time delay between
* each check.
+ * Turned into sysctl-controllable parameters. AV, 12/11/98
*/
-#define RESUME (4) /* More than 4% free space will resume */
-#define SUSPEND (2) /* Less than 2% free space will suspend */
-#define ACCT_TIMEOUT (30 * HZ) /* 30 second timeout between checks */
+int acct_parm[3] = {4, 2, 30};
+#define RESUME (acct_parm[0]) /* >foo% free space - resume */
+#define SUSPEND (acct_parm[1]) /* <foo% free space - suspend */
+#define ACCT_TIMEOUT (acct_parm[2]) /* foo second timeout between checks */
/*
* External references and all of the globals.
@@ -59,6 +73,7 @@ static volatile int acct_active = 0;
static volatile int acct_needcheck = 0;
static struct file *acct_file = NULL;
static struct timer_list acct_timer = { NULL, NULL, 0, 0, acct_timeout };
+static int do_acct_process(long, struct file *);
/*
* Called whenever the timer says to check the free space.
@@ -71,38 +86,58 @@ void acct_timeout(unsigned long unused)
/*
* Check the amount of free space and suspend/resume accordingly.
*/
-static void check_free_space(void)
+static int check_free_space(struct file *file)
{
mm_segment_t fs;
struct statfs sbuf;
+ struct super_block *sb;
+ int res = acct_active;
+ int act;
- if (!acct_file || !acct_needcheck)
- return;
+ if (!file || !acct_needcheck)
+ return res;
- if (!acct_file->f_dentry->d_inode->i_sb->s_op ||
- !acct_file->f_dentry->d_inode->i_sb->s_op->statfs)
- return;
+ sb = file->f_dentry->d_inode->i_sb;
+ if (!sb->s_op || !sb->s_op->statfs)
+ return res;
fs = get_fs();
set_fs(KERNEL_DS);
- acct_file->f_dentry->d_inode->i_sb->s_op->statfs(acct_file->f_dentry->d_inode->i_sb, &sbuf, sizeof(struct statfs));
+ /* May block */
+ sb->s_op->statfs(sb, &sbuf, sizeof(struct statfs));
set_fs(fs);
+ if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
+ act = -1;
+ else if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100)
+ act = 1;
+ else
+ act = 0;
+
+ /*
+ * If some joker switched acct_file under us we'ld better be
+ * silent and _not_ touch anything.
+ */
+ if (file != acct_file)
+ return act ? (act>0) : res;
+
if (acct_active) {
- if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100) {
+ if (act < 0) {
acct_active = 0;
printk(KERN_INFO "Process accounting paused\r\n");
}
} else {
- if (sbuf.f_bavail >= RESUME * sbuf.f_blocks / 100) {
+ if (act > 0) {
acct_active = 1;
printk(KERN_INFO "Process accounting resumed\r\n");
}
}
+
del_timer(&acct_timer);
acct_needcheck = 0;
- acct_timer.expires = jiffies + ACCT_TIMEOUT;
+ acct_timer.expires = jiffies + ACCT_TIMEOUT*HZ;
add_timer(&acct_timer);
+ return acct_active;
}
/*
@@ -113,8 +148,7 @@ static void check_free_space(void)
*/
asmlinkage int sys_acct(const char *name)
{
- struct dentry *dentry;
- struct inode *inode;
+ struct file *file = NULL, *old_acct = NULL;
char *tmp;
int error = -EPERM;
@@ -122,80 +156,57 @@ asmlinkage int sys_acct(const char *name)
if (!capable(CAP_SYS_PACCT))
goto out;
- if (name == (char *)NULL) {
- if (acct_active) {
- acct_process(0);
- del_timer(&acct_timer);
- acct_active = 0;
- acct_needcheck = 0;
- fput(acct_file);
+ if (name) {
+ tmp = getname(name);
+ error = PTR_ERR(tmp);
+ if (IS_ERR(tmp))
+ goto out;
+ /* Difference from BSD - they don't do O_APPEND */
+ file = filp_open(tmp, O_WRONLY|O_APPEND, 0);
+ putname(tmp);
+ if (IS_ERR(file)) {
+ error = PTR_ERR(file);
+ goto out;
}
- error = 0;
- goto out;
- } else {
- if (!acct_active) {
- tmp = getname(name);
- error = PTR_ERR(tmp);
- if (IS_ERR(tmp))
- goto out;
-
- dentry = open_namei(tmp, O_RDWR, 0600);
- putname(tmp);
-
- error = PTR_ERR(dentry);
- if (IS_ERR(dentry))
- goto out;
-
- inode = dentry->d_inode;
-
- if (!S_ISREG(inode->i_mode)) {
- dput(dentry);
- error = -EACCES;
- goto out;
- }
-
- if (!inode->i_op || !inode->i_op->default_file_ops ||
- !inode->i_op->default_file_ops->write) {
- dput(dentry);
- error = -EIO;
- goto out;
- }
-
- if ((acct_file = get_empty_filp()) != (struct file *)NULL) {
- acct_file->f_mode = (O_WRONLY + 1) & O_ACCMODE;
- acct_file->f_flags = O_WRONLY;
- acct_file->f_dentry = dentry;
- acct_file->f_pos = inode->i_size;
- acct_file->f_reada = 0;
- acct_file->f_op = inode->i_op->default_file_ops;
- if ((error = get_write_access(acct_file->f_dentry->d_inode)) == 0) {
- if (acct_file->f_op && acct_file->f_op->open)
- error = acct_file->f_op->open(inode, acct_file);
- if (error == 0) {
- acct_needcheck = 0;
- acct_active = 1;
- acct_timer.expires = jiffies + ACCT_TIMEOUT;
- add_timer(&acct_timer);
- error = 0;
- goto out;
- }
- put_write_access(acct_file->f_dentry->d_inode);
- }
- acct_file->f_count--;
- } else
- error = -EUSERS;
- dput(dentry);
- } else
- error = -EBUSY;
+ error = -EACCES;
+ if (!S_ISREG(file->f_dentry->d_inode->i_mode))
+ goto out_err;
+
+ error = -EIO;
+ if (!file->f_op->write)
+ goto out_err;
+ }
+
+ error = 0;
+ if (acct_file) {
+ old_acct = acct_file;
+ del_timer(&acct_timer);
+ acct_active = 0;
+ acct_needcheck = 0;
+ acct_file = NULL;
+ }
+ if (name) {
+ acct_file = file;
+ acct_needcheck = 0;
+ acct_active = 1;
+ acct_timer.expires = jiffies + ACCT_TIMEOUT*HZ;
+ add_timer(&acct_timer);
+ }
+ if (old_acct) {
+ do_acct_process(0,old_acct);
+ fput(old_acct);
}
out:
unlock_kernel();
return error;
+out_err:
+ fput(file);
+ goto out;
}
void acct_auto_close(kdev_t dev)
{
- if (acct_active && acct_file && acct_file->f_dentry->d_inode->i_dev == dev)
+ if (acct_file && acct_file->f_dentry->d_inode->i_dev == dev)
sys_acct((char *)NULL);
}
@@ -249,22 +260,27 @@ static comp_t encode_comp_t(unsigned long value)
#define KSTK_EIP(stack) (((unsigned long *)(stack))[1019])
#define KSTK_ESP(stack) (((unsigned long *)(stack))[1022])
-int acct_process(long exitcode)
+/*
+ * do_acct_process does all actual work.
+ */
+static int do_acct_process(long exitcode, struct file *file)
{
struct acct ac;
mm_segment_t fs;
unsigned long vsize;
+ struct inode *inode;
/*
- * First check to see if there is enough free_space to continue the process
- * accounting system. Check_free_space toggles the acct_active flag so we
- * need to check that after check_free_space.
+ * First check to see if there is enough free_space to continue
+ * the process accounting system.
*/
- check_free_space();
-
- if (!acct_active)
+ if (!file)
return 0;
-
+ file->f_count++;
+ if (!check_free_space(file)) {
+ fput(file);
+ return 0;
+ }
/*
* Fill the accounting struct with the needed info as recorded
@@ -311,16 +327,29 @@ int acct_process(long exitcode)
ac.ac_exitcode = exitcode;
/*
- * Kernel segment override to datasegment and write it to the accounting file.
+ * Kernel segment override to datasegment and write it
+ * to the accounting file.
*/
fs = get_fs();
set_fs(KERNEL_DS);
- acct_file->f_op->write(acct_file, (char *)&ac,
- sizeof(struct acct), &acct_file->f_pos);
+ inode = file->f_dentry->d_inode;
+ down(&inode->i_sem);
+ file->f_op->write(file, (char *)&ac,
+ sizeof(struct acct), &file->f_pos);
+ up(&inode->i_sem);
set_fs(fs);
+ fput(file);
return 0;
}
+/*
+ * acct_process - now just a wrapper around do_acct_process
+ */
+int acct_process(long exitcode)
+{
+ return do_acct_process(exitcode, acct_file);
+}
+
#else
/*
* Dummy system call when BSD process accounting is not configured
diff --git a/kernel/capability.c b/kernel/capability.c
index b2a8d43a1..a4a1a3d03 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -5,13 +5,7 @@
* Integrated into 2.1.97+, Andrew G. Morgan <morgan@transmeta.com>
*/
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/capability.h>
#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-
#include <asm/uaccess.h>
/* Note: never hold tasklist_lock while spinning for this one */
@@ -61,9 +55,9 @@ asmlinkage int sys_capget(cap_user_header_t header, cap_user_data_t dataptr)
}
if (!error) {
- data.permitted = target->cap_permitted.cap;
- data.inheritable = target->cap_inheritable.cap;
- data.effective = target->cap_effective.cap;
+ data.permitted = cap_t(target->cap_permitted);
+ data.inheritable = cap_t(target->cap_inheritable);
+ data.effective = cap_t(target->cap_effective);
}
if (target != current)
diff --git a/kernel/dma.c b/kernel/dma.c
index 0f13e6627..4ae38f4e5 100644
--- a/kernel/dma.c
+++ b/kernel/dma.c
@@ -14,6 +14,7 @@
#include <linux/errno.h>
#include <asm/dma.h>
#include <asm/system.h>
+#include <asm/spinlock.h>
/* A note on resource allocation:
@@ -32,6 +33,8 @@
*/
+spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
+
/* Channel n is busy iff dma_chan_busy[n].lock != 0.
* DMA0 used to be reserved for DRAM refresh, but apparently not any more...
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 5d7e2f056..3c5881ee2 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -1,8 +1,4 @@
-#include <linux/personality.h>
-#include <linux/ptrace.h>
-#include <linux/sched.h>
#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
diff --git a/kernel/exit.c b/kernel/exit.c
index 49e0294db..f0a22099e 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -5,21 +5,10 @@
*/
#include <linux/config.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/resource.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/malloc.h>
-#include <linux/slab.h>
#include <linux/interrupt.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
-#include <linux/slab.h>
#ifdef CONFIG_BSD_PROCESS_ACCT
#include <linux/acct.h>
#endif
@@ -29,6 +18,7 @@
#include <asm/mmu_context.h>
extern void sem_exit (void);
+extern struct task_struct *child_reaper;
int getrusage(struct task_struct *, int, struct rusage *);
@@ -156,7 +146,7 @@ static inline void forget_original_parent(struct task_struct * father)
for_each_task(p) {
if (p->p_opptr == father) {
p->exit_signal = SIGCHLD;
- p->p_opptr = task[smp_num_cpus] ? : task[0]; /* init */
+ p->p_opptr = child_reaper; /* init */
if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
}
}
@@ -239,7 +229,11 @@ static inline void __exit_sighand(struct task_struct *tsk)
struct signal_struct * sig = tsk->sig;
if (sig) {
+ unsigned long flags;
+
+ spin_lock_irqsave(&tsk->sigmask_lock, flags);
tsk->sig = NULL;
+ spin_unlock_irqrestore(&tsk->sigmask_lock, flags);
if (atomic_dec_and_test(&sig->count))
kfree(sig);
}
@@ -357,7 +351,9 @@ NORET_TYPE void do_exit(long code)
if (!tsk->pid)
panic("Attempted to kill the idle task!");
tsk->flags |= PF_EXITING;
+ start_bh_atomic();
del_timer(&tsk->real_timer);
+ end_bh_atomic();
lock_kernel();
fake_volatile:
@@ -411,15 +407,6 @@ asmlinkage int sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct
struct wait_queue wait = { current, NULL };
struct task_struct *p;
- if (stat_addr) {
- if(verify_area(VERIFY_WRITE, stat_addr, sizeof(*stat_addr)))
- return -EFAULT;
- }
- if (ru) {
- if(verify_area(VERIFY_WRITE, ru, sizeof(*ru)))
- return -EFAULT;
- }
-
if (options & ~(WNOHANG|WUNTRACED|__WCLONE))
return -EINVAL;
@@ -449,21 +436,23 @@ repeat:
if (!(options & WUNTRACED) && !(p->flags & PF_PTRACED))
continue;
read_unlock(&tasklist_lock);
- if (ru != NULL)
- getrusage(p, RUSAGE_BOTH, ru);
- if (stat_addr)
- __put_user((p->exit_code << 8) | 0x7f, stat_addr);
- p->exit_code = 0;
- retval = p->pid;
+ retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+ if (!retval && stat_addr)
+ retval = put_user((p->exit_code << 8) | 0x7f, stat_addr);
+ if (!retval) {
+ p->exit_code = 0;
+ retval = p->pid;
+ }
goto end_wait4;
case TASK_ZOMBIE:
current->times.tms_cutime += p->times.tms_utime + p->times.tms_cutime;
current->times.tms_cstime += p->times.tms_stime + p->times.tms_cstime;
read_unlock(&tasklist_lock);
- if (ru != NULL)
- getrusage(p, RUSAGE_BOTH, ru);
- if (stat_addr)
- __put_user(p->exit_code, stat_addr);
+ retval = ru ? getrusage(p, RUSAGE_BOTH, ru) : 0;
+ if (!retval && stat_addr)
+ retval = put_user(p->exit_code, stat_addr);
+ if (retval)
+ goto end_wait4;
retval = p->pid;
if (p->p_opptr != p->p_pptr) {
write_lock_irq(&tasklist_lock);
diff --git a/kernel/fork.c b/kernel/fork.c
index 856934441..a625aaba3 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -11,20 +11,12 @@
* management can be a bitch. See 'mm/mm.c': 'copy_page_tables()'
*/
+#include <linux/malloc.h>
#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/malloc.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/module.h>
-#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
#include <asm/uaccess.h>
@@ -145,7 +137,7 @@ static inline struct task_struct ** find_empty_process(void)
{
struct task_struct **tslot = NULL;
- if (!current->uid || (nr_tasks < NR_TASKS - MIN_TASKS_LEFT_FOR_ROOT))
+ if ((nr_tasks < NR_TASKS - MIN_TASKS_LEFT_FOR_ROOT) || !current->uid)
tslot = get_free_taskslot();
return tslot;
}
@@ -461,7 +453,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
{
unsigned long new_flags = p->flags;
- new_flags &= ~PF_SUPERPRIV;
+ new_flags &= ~(PF_SUPERPRIV | PF_USEDFPU);
new_flags |= PF_FORKNOEXEC;
if (!(clone_flags & CLONE_PTRACE))
new_flags &= ~(PF_PTRACED|PF_TRACESYS);
diff --git a/kernel/info.c b/kernel/info.c
index ffaec7140..1dffddc7b 100644
--- a/kernel/info.c
+++ b/kernel/info.c
@@ -6,13 +6,9 @@
/* This implements the sysinfo() system call */
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/unistd.h>
-#include <linux/types.h>
#include <linux/mm.h>
+#include <linux/unistd.h>
#include <linux/swap.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
diff --git a/kernel/itimer.c b/kernel/itimer.c
index d4bbf7851..1b4661c39 100644
--- a/kernel/itimer.c
+++ b/kernel/itimer.c
@@ -6,14 +6,9 @@
/* These are all the functions necessary to implement itimers */
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/time.h>
#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
#include <asm/uaccess.h>
@@ -53,15 +48,15 @@ int do_getitimer(int which, struct itimerval *value)
case ITIMER_REAL:
interval = current->it_real_incr;
val = 0;
- if (del_timer(&current->real_timer)) {
- unsigned long now = jiffies;
- val = current->real_timer.expires;
- add_timer(&current->real_timer);
+ start_bh_atomic();
+ if (timer_pending(&current->real_timer)) {
+ val = current->real_timer.expires - jiffies;
+
/* look out for negative/zero itimer.. */
- if (val <= now)
- val = now+1;
- val -= now;
+ if ((long) val <= 0)
+ val = 1;
}
+ end_bh_atomic();
break;
case ITIMER_VIRTUAL:
val = current->it_virt_value;
@@ -102,11 +97,9 @@ void it_real_fn(unsigned long __data)
send_sig(SIGALRM, p, 1);
interval = p->it_real_incr;
if (interval) {
- unsigned long timeout = jiffies + interval;
- /* check for overflow */
- if (timeout < interval)
- timeout = ULONG_MAX;
- p->real_timer.expires = timeout;
+ if (interval > (unsigned long) LONG_MAX)
+ interval = LONG_MAX;
+ p->real_timer.expires = jiffies + interval;
add_timer(&p->real_timer);
}
}
@@ -122,15 +115,16 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue)
return k;
switch (which) {
case ITIMER_REAL:
+ start_bh_atomic();
del_timer(&current->real_timer);
+ end_bh_atomic();
current->it_real_value = j;
current->it_real_incr = i;
if (!j)
break;
+ if (j > (unsigned long) LONG_MAX)
+ j = LONG_MAX;
i = j + jiffies;
- /* check for overflow.. */
- if (i < j)
- i = ULONG_MAX;
current->real_timer.expires = i;
add_timer(&current->real_timer);
break;
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 4a7e3ebda..8b19e2415 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -12,10 +12,8 @@
#define __KERNEL_SYSCALLS__
#include <linux/sched.h>
-#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/smp_lock.h>
-#include <linux/signal.h>
#include <asm/uaccess.h>
@@ -24,24 +22,23 @@
*/
char modprobe_path[256] = "/sbin/modprobe";
-/*
- exec_modprobe is spawned from a kernel-mode user process,
- then changes its state to behave _as_if_ it was spawned
- from the kernel's init process
- (ppid and {e,}gid are not adjusted, but that shouldn't
- be a problem since we trust modprobe)
-*/
-#define task_init task[smp_num_cpus]
-
static inline void
use_init_file_context(void)
{
+ struct fs_struct * fs;
+
lock_kernel();
- /* don't use the user's root, use init's root instead */
+ /*
+ * Don't use the user's root, use init's root instead.
+ * Note that we can use "init_task" (which is not actually
+ * the same as the user-level "init" process) because we
+ * started "init" with a CLONE_FS
+ */
exit_fs(current); /* current->fs->count--; */
- current->fs = task_init->fs;
- atomic_inc(&current->fs->count);
+ fs = init_task.fs;
+ current->fs = fs;
+ atomic_inc(&fs->count);
unlock_kernel();
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index e9cb2ea70..d567240e6 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -10,38 +10,23 @@
*/
#include <linux/config.h>
+#include <linux/malloc.h>
#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/fs.h>
#include <linux/blkdev.h>
#include <linux/cdrom.h>
-#include <linux/sched.h>
#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/malloc.h>
-#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <linux/ptrace.h>
#include <linux/sys.h>
#include <linux/utsname.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/timer.h>
-#include <linux/binfmts.h>
-#include <linux/personality.h>
-#include <linux/termios.h>
-#include <linux/tqueue.h>
-#include <linux/tty.h>
#include <linux/serial.h>
#include <linux/locks.h>
-#include <linux/string.h>
#include <linux/delay.h>
-#include <linux/sem.h>
#include <linux/minix_fs.h>
#include <linux/ext2_fs.h>
#include <linux/random.h>
#include <linux/reboot.h>
-#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/sysctl.h>
#include <linux/hdreg.h>
@@ -51,9 +36,6 @@
#include <linux/ctype.h>
#include <linux/file.h>
#include <linux/console.h>
-#include <linux/time.h>
-
-extern unsigned char aux_device_present, pckbd_read_mask;
#if defined(CONFIG_PROC_FS)
#include <linux/proc_fs.h>
@@ -61,10 +43,6 @@ extern unsigned char aux_device_present, pckbd_read_mask;
#ifdef CONFIG_KMOD
#include <linux/kmod.h>
#endif
-#include <asm/irq.h>
-#ifdef __SMP__
-#include <linux/smp.h>
-#endif
extern char *get_options(char *str, int *ints);
extern void set_device_ro(kdev_t dev,int flag);
@@ -79,6 +57,7 @@ extern void *sys_call_table;
extern int sys_tz;
extern int request_dma(unsigned int dmanr, char * deviceID);
extern void free_dma(unsigned int dmanr);
+extern spinlock_t dma_spin_lock;
#ifdef MODVERSIONS
const struct module_symbol __export_Using_Versions
@@ -146,6 +125,7 @@ EXPORT_SYMBOL(d_move);
EXPORT_SYMBOL(d_instantiate);
EXPORT_SYMBOL(d_alloc);
EXPORT_SYMBOL(d_lookup);
+EXPORT_SYMBOL(d_path);
EXPORT_SYMBOL(__mark_inode_dirty);
EXPORT_SYMBOL(get_empty_filp);
EXPORT_SYMBOL(init_private_file);
@@ -191,6 +171,7 @@ EXPORT_SYMBOL(shrink_dcache_sb);
EXPORT_SYMBOL(shrink_dcache_parent);
EXPORT_SYMBOL(find_inode_number);
EXPORT_SYMBOL(is_subdir);
+EXPORT_SYMBOL(get_unused_fd);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl);
@@ -299,6 +280,7 @@ EXPORT_SYMBOL(autoirq_report);
/* dma handling */
EXPORT_SYMBOL(request_dma);
EXPORT_SYMBOL(free_dma);
+EXPORT_SYMBOL(dma_spin_lock);
#ifdef HAVE_DISABLE_HLT
EXPORT_SYMBOL(disable_hlt);
EXPORT_SYMBOL(enable_hlt);
@@ -313,7 +295,9 @@ EXPORT_SYMBOL(release_region);
EXPORT_SYMBOL(__wake_up);
EXPORT_SYMBOL(sleep_on);
EXPORT_SYMBOL(interruptible_sleep_on);
+EXPORT_SYMBOL(interruptible_sleep_on_timeout);
EXPORT_SYMBOL(schedule);
+EXPORT_SYMBOL(schedule_timeout);
EXPORT_SYMBOL(jiffies);
EXPORT_SYMBOL(xtime);
EXPORT_SYMBOL(do_gettimeofday);
@@ -373,20 +357,13 @@ EXPORT_SYMBOL(make_bad_inode);
EXPORT_SYMBOL(is_bad_inode);
EXPORT_SYMBOL(event);
EXPORT_SYMBOL(__down);
+EXPORT_SYMBOL(__down_interruptible);
EXPORT_SYMBOL(__up);
/* all busmice */
EXPORT_SYMBOL(add_mouse_randomness);
EXPORT_SYMBOL(fasync_helper);
-#ifdef CONFIG_PSMOUSE_MODULE
-/* psaux mouse */
-EXPORT_SYMBOL(aux_device_present);
-#ifdef CONFIG_VT
-EXPORT_SYMBOL(pckbd_read_mask);
-#endif
-#endif
-
#ifdef CONFIG_BLK_DEV_MD
EXPORT_SYMBOL(disk_name); /* for md.c */
#endif
@@ -401,3 +378,6 @@ EXPORT_SYMBOL(unregister_console);
/* time */
EXPORT_SYMBOL(get_fast_time);
+
+/* library functions */
+EXPORT_SYMBOL(strnicmp);
diff --git a/kernel/module.c b/kernel/module.c
index e367a747c..59884d8e2 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1,13 +1,8 @@
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/mm.h> /* defines GFP_KERNEL */
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <asm/pgtable.h>
diff --git a/kernel/panic.c b/kernel/panic.c
index 140c6bad2..87a0cb4b3 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -8,12 +8,8 @@
* This function is used through-out the kernel (including mm and fs)
* to indicate a major problem.
*/
-#include <stdarg.h>
-
-#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/delay.h>
-#include <linux/smp.h>
#include <linux/reboot.h>
#include <linux/notifier.h>
#include <linux/init.h>
diff --git a/kernel/printk.c b/kernel/printk.c
index 0d8287fef..a333fe18e 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -12,20 +12,12 @@
* Modified for sysctl support, 1/8/97, Chris Horn.
*/
-#include <stdarg.h>
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/tty.h>
#include <linux/tty_driver.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/console.h>
#include <linux/init.h>
-#include <asm/system.h>
#include <asm/uaccess.h>
#define LOG_BUF_LEN (16384)
@@ -109,7 +101,7 @@ void __init console_setup(char *str, int *ints)
/*
- * Commands to sys_syslog:
+ * Commands to do_syslog:
*
* 0 -- Close the log. Currently a NOP.
* 1 -- Open the log. Currently a NOP.
@@ -121,7 +113,7 @@ void __init console_setup(char *str, int *ints)
* 7 -- Enable printk's to console
* 8 -- Set level of messages printed to console
*/
-asmlinkage int sys_syslog(int type, char * buf, int len)
+int do_syslog(int type, char * buf, int len)
{
unsigned long i, j, count, flags;
int do_clear = 0;
@@ -129,8 +121,6 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
int error = -EPERM;
lock_kernel();
- if ((type != 3) && !capable(CAP_SYS_ADMIN))
- goto out;
error = 0;
switch (type) {
case 0: /* Close log */
@@ -232,6 +222,14 @@ out:
return error;
}
+asmlinkage int sys_syslog(int type, char * buf, int len)
+{
+ if ((type != 3) && !capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ return do_syslog(type, buf, len);
+}
+
+
spinlock_t console_lock;
asmlinkage int printk(const char *fmt, ...)
diff --git a/kernel/resource.c b/kernel/resource.c
index 2d6b56eb0..fa607edf8 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -8,9 +8,7 @@
*/
#include <linux/sched.h>
-#include <linux/kernel.h>
#include <linux/errno.h>
-#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/init.h>
diff --git a/kernel/sched.c b/kernel/sched.c
index a9a7a6b64..c8c297180 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -16,30 +16,18 @@
* current-task
*/
-#include <linux/signal.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/kernel.h>
+#include <linux/mm.h>
#include <linux/kernel_stat.h>
#include <linux/fdreg.h>
-#include <linux/errno.h>
-#include <linux/time.h>
-#include <linux/ptrace.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
-#include <linux/tqueue.h>
-#include <linux/resource.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
-#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
-#include <asm/spinlock.h>
#include <linux/timex.h>
@@ -230,7 +218,7 @@ rwlock_t tasklist_lock = RW_LOCK_UNLOCKED; /* third */
* "current->state = TASK_RUNNING" to mark yourself runnable
* without the overhead of this.
*/
-inline void wake_up_process(struct task_struct * p)
+void wake_up_process(struct task_struct * p)
{
unsigned long flags;
@@ -248,7 +236,6 @@ static void process_timeout(unsigned long __data)
{
struct task_struct * p = (struct task_struct *) __data;
- p->timeout = 0;
wake_up_process(p);
}
@@ -372,12 +359,12 @@ static inline void internal_add_timer(struct timer_list *timer)
} else if (idx < 1 << (TVR_BITS + 3 * TVN_BITS)) {
int i = (expires >> (TVR_BITS + 2 * TVN_BITS)) & TVN_MASK;
insert_timer(timer, tv4.vec, i);
- } else if (expires < timer_jiffies) {
+ } else if ((signed long) idx < 0) {
/* can happen if you add a timer with expires == jiffies,
* or you set a timer to go off in the past
*/
insert_timer(timer, tv1.vec, tv1.index);
- } else if (idx < 0xffffffffUL) {
+ } else if (idx <= 0xffffffffUL) {
int i = (expires >> (TVR_BITS + 3 * TVN_BITS)) & TVN_MASK;
insert_timer(timer, tv5.vec, i);
} else {
@@ -445,6 +432,74 @@ int del_timer(struct timer_list * timer)
#endif
+signed long schedule_timeout(signed long timeout)
+{
+ struct timer_list timer;
+ unsigned long expire;
+
+ /*
+ * PARANOID.
+ */
+ if (current->state == TASK_UNINTERRUPTIBLE)
+ {
+ printk(KERN_WARNING "schedule_timeout: task not interrutible "
+ "from %p\n", __builtin_return_address(0));
+ /*
+ * We don' t want to interrupt a not interruptible task
+ * risking to cause corruption. Better a a deadlock ;-).
+ */
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ }
+
+ /*
+ * Here we start for real.
+ */
+ switch (timeout)
+ {
+ case MAX_SCHEDULE_TIMEOUT:
+ /*
+ * These two special cases are useful to be comfortable
+ * in the caller. Nothing more. We could take
+ * MAX_SCHEDULE_TIMEOUT from one of the negative value
+ * but I' d like to return a valid offset (>=0) to allow
+ * the caller to do everything it want with the retval.
+ */
+ schedule();
+ goto out;
+ default:
+ /*
+ * Another bit of PARANOID. Note that the retval will be
+ * 0 since no piece of kernel is supposed to do a check
+ * for a negative retval of schedule_timeout() (since it
+ * should never happens anyway). You just have the printk()
+ * that will tell you if something is gone wrong and where.
+ */
+ if (timeout < 0)
+ {
+ printk(KERN_ERR "schedule_timeout: wrong timeout "
+ "value %lx from %p\n", timeout,
+ __builtin_return_address(0));
+ goto out;
+ }
+ }
+
+ expire = timeout + jiffies;
+
+ init_timer(&timer);
+ timer.expires = expire;
+ timer.data = (unsigned long) current;
+ timer.function = process_timeout;
+
+ add_timer(&timer);
+ schedule();
+ del_timer(&timer);
+
+ timeout = expire - jiffies;
+
+ out:
+ return timeout < 0 ? 0 : timeout;
+}
+
/*
* 'schedule()' is the scheduler function. It's a very simple and nice
* scheduler: it's not perfect, but certainly works for most things.
@@ -458,7 +513,6 @@ int del_timer(struct timer_list * timer)
asmlinkage void schedule(void)
{
struct task_struct * prev, * next;
- unsigned long timeout;
int this_cpu;
prev = current;
@@ -481,16 +535,10 @@ asmlinkage void schedule(void)
prev->counter = prev->priority;
move_last_runqueue(prev);
}
- timeout = 0;
+
switch (prev->state) {
case TASK_INTERRUPTIBLE:
- if (signal_pending(prev))
- goto makerunnable;
- timeout = prev->timeout;
- if (timeout && (timeout <= jiffies)) {
- prev->timeout = 0;
- timeout = 0;
- makerunnable:
+ if (signal_pending(prev)) {
prev->state = TASK_RUNNING;
break;
}
@@ -550,21 +598,9 @@ asmlinkage void schedule(void)
#endif
if (prev != next) {
- struct timer_list timer;
-
kstat.context_swtch++;
- if (timeout) {
- init_timer(&timer);
- timer.expires = timeout;
- timer.data = (unsigned long) prev;
- timer.function = process_timeout;
- add_timer(&timer);
- }
get_mmu_context(next);
switch_to(prev,next);
-
- if (timeout)
- del_timer(&timer);
}
spin_unlock(&scheduler_lock);
@@ -702,7 +738,6 @@ static inline int __do_down(struct semaphore * sem, int task_state)
schedule();
tsk->state = task_state;
}
-
tsk->state = TASK_RUNNING;
remove_wait_queue(&sem->wait, &wait);
return ret;
@@ -718,32 +753,54 @@ int __down_interruptible(struct semaphore * sem)
return __do_down(sem,TASK_INTERRUPTIBLE);
}
-
-static void FASTCALL(__sleep_on(struct wait_queue **p, int state));
-static void __sleep_on(struct wait_queue **p, int state)
-{
- unsigned long flags;
+#define SLEEP_ON_VAR \
+ unsigned long flags; \
struct wait_queue wait;
- current->state = state;
- wait.task = current;
- write_lock_irqsave(&waitqueue_lock, flags);
- __add_wait_queue(p, &wait);
+#define SLEEP_ON_HEAD \
+ wait.task = current; \
+ write_lock_irqsave(&waitqueue_lock, flags); \
+ __add_wait_queue(p, &wait); \
write_unlock(&waitqueue_lock);
- schedule();
- write_lock_irq(&waitqueue_lock);
- __remove_wait_queue(p, &wait);
+
+#define SLEEP_ON_TAIL \
+ write_lock_irq(&waitqueue_lock); \
+ __remove_wait_queue(p, &wait); \
write_unlock_irqrestore(&waitqueue_lock, flags);
-}
void interruptible_sleep_on(struct wait_queue **p)
{
- __sleep_on(p,TASK_INTERRUPTIBLE);
+ SLEEP_ON_VAR
+
+ current->state = TASK_INTERRUPTIBLE;
+
+ SLEEP_ON_HEAD
+ schedule();
+ SLEEP_ON_TAIL
+}
+
+long interruptible_sleep_on_timeout(struct wait_queue **p, long timeout)
+{
+ SLEEP_ON_VAR
+
+ current->state = TASK_INTERRUPTIBLE;
+
+ SLEEP_ON_HEAD
+ timeout = schedule_timeout(timeout);
+ SLEEP_ON_TAIL
+
+ return timeout;
}
void sleep_on(struct wait_queue **p)
{
- __sleep_on(p,TASK_UNINTERRUPTIBLE);
+ SLEEP_ON_VAR
+
+ current->state = TASK_UNINTERRUPTIBLE;
+
+ SLEEP_ON_HEAD
+ schedule();
+ SLEEP_ON_TAIL
}
void scheduling_functions_end_here(void) { }
@@ -803,7 +860,7 @@ static inline void run_old_timers(void)
break;
if (!(mask & timer_active))
continue;
- if (tp->expires > jiffies)
+ if (time_after(tp->expires, jiffies))
continue;
timer_active &= ~mask;
tp->fn();
@@ -1488,7 +1545,8 @@ asmlinkage int sys_sched_yield(void)
{
spin_lock(&scheduler_lock);
spin_lock_irq(&runqueue_lock);
- current->policy |= SCHED_YIELD;
+ if (current->policy == SCHED_OTHER)
+ current->policy |= SCHED_YIELD;
current->need_resched = 1;
move_last_runqueue(current);
spin_unlock_irq(&runqueue_lock);
@@ -1563,16 +1621,14 @@ asmlinkage int sys_nanosleep(struct timespec *rqtp, struct timespec *rmtp)
return 0;
}
- expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec) + jiffies;
+ expire = timespec_to_jiffies(&t) + (t.tv_sec || t.tv_nsec);
- current->timeout = expire;
current->state = TASK_INTERRUPTIBLE;
- schedule();
+ expire = schedule_timeout(expire);
- if (expire > jiffies) {
+ if (expire) {
if (rmtp) {
- jiffies_to_timespec(expire - jiffies -
- (expire > jiffies + 1), &t);
+ jiffies_to_timespec(expire, &t);
if (copy_to_user(rmtp, &t, sizeof(struct timespec)))
return -EFAULT;
}
diff --git a/kernel/signal.c b/kernel/signal.c
index 1aded9117..b10f59516 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -6,18 +6,10 @@
* 1997-11-02 Modified for POSIX.1b signals by Richard Henderson
*/
+#include <linux/slab.h>
#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/signal.h>
-#include <linux/errno.h>
-#include <linux/wait.h>
-#include <linux/ptrace.h>
#include <linux/unistd.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
-#include <linux/slab.h>
#include <linux/init.h>
#include <asm/uaccess.h>
@@ -213,10 +205,50 @@ printk(" %d -> %d\n", signal_pending(current), sig);
return sig;
}
+/*
+ * Determine whether a signal should be posted or not.
+ *
+ * Signals with SIG_IGN can be ignored, except for the
+ * special case of a SIGCHLD.
+ *
+ * Some signals with SIG_DFL default to a non-action.
+ */
+static int ignored_signal(int sig, struct task_struct *t)
+{
+ struct signal_struct *signals;
+ struct k_sigaction *ka;
+
+ /* Don't ignore traced or blocked signals */
+ if ((t->flags & PF_PTRACED) || sigismember(&t->blocked, sig))
+ return 0;
+
+ signals = t->sig;
+ if (!signals)
+ return 1;
+
+ ka = &signals->action[sig-1];
+ switch ((unsigned long) ka->sa.sa_handler) {
+ case (unsigned long) SIG_DFL:
+ if (sig == SIGCONT ||
+ sig == SIGWINCH ||
+ sig == SIGCHLD ||
+ sig == SIGURG)
+ break;
+ return 0;
+
+ case (unsigned long) SIG_IGN:
+ if (sig != SIGCHLD)
+ break;
+ /* fallthrough */
+ default:
+ return 0;
+ }
+ return 1;
+}
+
int
send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
- struct k_sigaction *ka;
unsigned long flags;
int ret;
@@ -227,13 +259,6 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
ret = -EINVAL;
if (sig < 0 || sig > _NSIG)
goto out_nolock;
-
- /* If t->sig is gone, we must be trying to kill the task. So
- pretend that it doesn't exist anymore. */
- ret = -ESRCH;
- if (t->sig == NULL)
- goto out_nolock;
-
/* The somewhat baroque permissions check... */
ret = -EPERM;
if ((!info || ((unsigned long)info != 1 && SI_FROMUSER(info)))
@@ -244,14 +269,12 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
goto out_nolock;
/* The null signal is a permissions and process existance probe.
- No signal is actually delivered. */
+ No signal is actually delivered. Same goes for zombies. */
ret = 0;
- if (!sig)
+ if (!sig || !t->sig)
goto out_nolock;
- ka = &t->sig->action[sig-1];
spin_lock_irqsave(&t->sigmask_lock, flags);
-
switch (sig) {
case SIGKILL: case SIGCONT:
/* Wake up the process if stopped. */
@@ -277,16 +300,8 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
handled immediately (ie non-blocked and untraced) and
that is ignored (either explicitly or by default). */
- if (!(t->flags & PF_PTRACED) && !sigismember(&t->blocked, sig)
- /* Don't bother with ignored sigs (SIGCHLD is special) */
- && ((ka->sa.sa_handler == SIG_IGN && sig != SIGCHLD)
- /* Some signals are ignored by default.. (but SIGCONT
- already did its deed) */
- || (ka->sa.sa_handler == SIG_DFL
- && (sig == SIGCONT || sig == SIGCHLD
- || sig == SIGWINCH || sig == SIGURG)))) {
+ if (ignored_signal(sig, t))
goto out;
- }
if (sig < SIGRTMIN) {
/* Non-real-time signals are not queued. */
@@ -310,10 +325,10 @@ printk("SIG queue (%s:%d): %d ", t->comm, t->pid, sig);
if (nr_queued_signals < max_queued_signals) {
q = (struct signal_queue *)
kmem_cache_alloc(signal_queue_cachep, GFP_KERNEL);
- nr_queued_signals++;
}
if (q) {
+ nr_queued_signals++;
q->next = NULL;
*t->sigqueue_tail = q;
t->sigqueue_tail = &q->next;
@@ -372,12 +387,18 @@ printk(" %d -> %d\n", signal_pending(t), ret);
int
force_sig_info(int sig, struct siginfo *info, struct task_struct *t)
{
- if (t->sig == NULL)
+ unsigned long int flags;
+
+ spin_lock_irqsave(&t->sigmask_lock, flags);
+ if (t->sig == NULL) {
+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
return -ESRCH;
+ }
if (t->sig->action[sig-1].sa.sa_handler == SIG_IGN)
t->sig->action[sig-1].sa.sa_handler = SIG_DFL;
sigdelset(&t->blocked, sig);
+ spin_unlock_irqrestore(&t->sigmask_lock, flags);
return send_sig_info(sig, info, t);
}
@@ -683,6 +704,7 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
sigset_t these;
struct timespec ts;
siginfo_t info;
+ long timeout = 0;
/* XXX: Don't preclude handling different sized sigset_t's. */
if (sigsetsize != sizeof(sigset_t))
@@ -709,22 +731,18 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
if (!sig) {
/* None ready -- temporarily unblock those we're interested
in so that we'll be awakened when they arrive. */
- unsigned long expire;
sigset_t oldblocked = current->blocked;
sigandsets(&current->blocked, &current->blocked, &these);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
- expire = ~0UL;
- if (uts) {
- expire = (timespec_to_jiffies(&ts)
- + (ts.tv_sec || ts.tv_nsec));
- expire += jiffies;
- }
- current->timeout = expire;
+ timeout = MAX_SCHEDULE_TIMEOUT;
+ if (uts)
+ timeout = (timespec_to_jiffies(&ts)
+ + (ts.tv_sec || ts.tv_nsec));
current->state = TASK_INTERRUPTIBLE;
- schedule();
+ timeout = schedule_timeout(timeout);
spin_lock_irq(&current->sigmask_lock);
sig = dequeue_signal(&these, &info);
@@ -741,10 +759,8 @@ sys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,
}
} else {
ret = -EAGAIN;
- if (current->timeout != 0) {
- current->timeout = 0;
+ if (timeout)
ret = -EINTR;
- }
}
return ret;
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 4bc5ee4b6..e76820457 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -8,21 +8,12 @@
* bottom_half handler need not be re-entrant.
*/
-#include <linux/ptrace.h>
-#include <linux/errno.h>
+#include <linux/mm.h>
#include <linux/kernel_stat.h>
-#include <linux/signal.h>
-#include <linux/sched.h>
#include <linux/interrupt.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
-#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/bitops.h>
-#include <asm/atomic.h>
/* intr_count died a painless death... -DaveM */
diff --git a/kernel/sys.c b/kernel/sys.c
index 1b4c6df40..2ce90cc58 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -4,22 +4,9 @@
* Copyright (C) 1991, 1992 Linus Torvalds
*/
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/times.h>
+#include <linux/mm.h>
#include <linux/utsname.h>
-#include <linux/param.h>
-#include <linux/resource.h>
-#include <linux/signal.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/stat.h>
#include <linux/mman.h>
-#include <linux/mm.h>
-#include <linux/fcntl.h>
-#include <linux/tty.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
@@ -586,11 +573,11 @@ asmlinkage int sys_setfsuid(uid_t uid)
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
if (old_fsuid == 0 && current->fsuid != 0) {
- current->cap_effective.cap &= ~CAP_FS_MASK;
+ cap_t(current->cap_effective) &= ~CAP_FS_MASK;
}
if (old_fsuid != 0 && current->fsuid == 0) {
- current->cap_effective.cap |=
- (current->cap_permitted.cap & CAP_FS_MASK);
+ cap_t(current->cap_effective) |=
+ (cap_t(current->cap_permitted) & CAP_FS_MASK);
}
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 132739310..12455ee07 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -12,22 +12,16 @@
*/
#include <linux/config.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
+#include <linux/malloc.h>
#include <linux/sysctl.h>
#include <linux/swapctl.h>
#include <linux/proc_fs.h>
-#include <linux/malloc.h>
-#include <linux/stat.h>
#include <linux/ctype.h>
#include <linux/utsname.h>
#include <linux/swapctl.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/init.h>
-#include <linux/fs.h>
-#include <asm/bitops.h>
#include <asm/uaccess.h>
#ifdef CONFIG_ROOT_NFS
@@ -38,7 +32,7 @@
/* External variables not in a header file. */
extern int panic_timeout;
-extern int console_loglevel, C_A_D, swapout_interval;
+extern int console_loglevel, C_A_D;
extern int bdf_prm[], bdflush_min[], bdflush_max[];
extern char binfmt_java_interpreter[], binfmt_java_appletviewer[];
extern int sysctl_overcommit_memory;
@@ -54,6 +48,12 @@ extern char reboot_command [];
#endif
#ifdef __powerpc__
extern unsigned long htab_reclaim_on, zero_paged_on, powersave_nap;
+int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+#endif
+
+#ifdef CONFIG_BSD_PROCESS_ACCT
+extern int acct_parm[];
#endif
extern int pgt_cache_water[];
@@ -176,6 +176,8 @@ static ctl_table kern_table[] = {
0644, NULL, &proc_dointvec},
{KERN_PPC_POWERSAVE_NAP, "powersave-nap", &powersave_nap, sizeof(int),
0644, NULL, &proc_dointvec},
+ {KERN_PPC_L2CR, "l2cr", NULL, 0,
+ 0644, NULL, &proc_dol2crvec},
#endif
{KERN_CTLALTDEL, "ctrl-alt-del", &C_A_D, sizeof(int),
0644, NULL, &proc_dointvec},
@@ -189,14 +191,16 @@ static ctl_table kern_table[] = {
{KERN_SG_BIG_BUFF, "sg-big-buff", &sg_big_buff, sizeof (int),
0444, NULL, &proc_dointvec},
#endif
+#ifdef CONFIG_BSD_PROCESS_ACCT
+ {KERN_ACCT, "acct", &acct_parm, 3*sizeof(int),
+ 0644, NULL, &proc_dointvec},
+#endif
{0}
};
static ctl_table vm_table[] = {
{VM_SWAPCTL, "swapctl",
&swap_control, sizeof(swap_control_t), 0644, NULL, &proc_dointvec},
- {VM_SWAPOUT, "swapout_interval",
- &swapout_interval, sizeof(int), 0644, NULL, &proc_dointvec},
{VM_FREEPG, "freepages",
&freepages, sizeof(freepages_t), 0644, NULL, &proc_dointvec},
{VM_BDFLUSH, "bdflush", &bdf_prm, 9*sizeof(int), 0600, NULL,
diff --git a/kernel/time.c b/kernel/time.c
index 0f1094655..9b476ece2 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -18,14 +18,8 @@
* kernel PLL updated to 1994-12-13 specs (rfc-1589)
*/
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
#include <linux/mm.h>
#include <linux/timex.h>
-#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>