summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-12-06 23:51:34 +0000
commit230e5ab6a084ed50470f101934782dbf54b0d06b (patch)
tree5dd821c8d33f450470588e7a543f74bf74306e9e /kernel
parentc9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff)
Merge with Linux 2.1.67.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c7
-rw-r--r--kernel/fork.c29
-rw-r--r--kernel/ksyms.c23
-rw-r--r--kernel/module.c29
-rw-r--r--kernel/printk.c6
-rw-r--r--kernel/sched.c16
-rw-r--r--kernel/sys.c27
-rw-r--r--kernel/sysctl.c37
8 files changed, 127 insertions, 47 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index c99dc8b45..5ed96a90d 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -55,7 +55,7 @@ static inline void generate(unsigned long sig, struct task_struct * p)
spin_lock(&p->sigmask_lock);
p->signal |= mask;
spin_unlock(&p->sigmask_lock);
- if (p->state == TASK_INTERRUPTIBLE && (p->signal & ~p->blocked))
+ if (p->state == TASK_INTERRUPTIBLE && signal_pending(p))
wake_up_process(p);
out:
spin_unlock_irqrestore(&p->sig->siglock, flags);
@@ -349,7 +349,8 @@ 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 = task[smp_num_cpus] ? : task[0]; /* init */
+ if (p->pdeath_signal) send_sig(p->pdeath_signal, p, 0);
}
}
read_unlock(&tasklist_lock);
@@ -659,7 +660,7 @@ repeat:
if (options & WNOHANG)
goto end_wait4;
retval = -ERESTARTSYS;
- if (current->signal & ~current->blocked)
+ if (signal_pending(current))
goto end_wait4;
current->state=TASK_INTERRUPTIBLE;
schedule();
diff --git a/kernel/fork.c b/kernel/fork.c
index 4974d5dac..116e02786 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -208,7 +208,6 @@ static inline int dup_mmap(struct mm_struct * mm)
struct vm_area_struct * mpnt, *tmp, **pprev;
int retval;
- mm->mmap = mm->mmap_cache = NULL;
flush_cache_mm(current->mm);
pprev = &mm->mmap;
for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
@@ -254,8 +253,7 @@ static inline int dup_mmap(struct mm_struct * mm)
if (retval)
goto fail_nomem;
}
- flush_tlb_mm(current->mm);
- return 0;
+ retval = 0;
fail_nomem:
flush_tlb_mm(current->mm);
@@ -276,7 +274,10 @@ struct mm_struct * mm_alloc(void)
mm->count = 1;
mm->def_flags = 0;
mm->mmap_sem = MUTEX;
- mm->pgd = NULL;
+ /*
+ * Leave mm->pgd set to the parent's pgd
+ * so that pgd_offset() is always valid.
+ */
mm->mmap = mm->mmap_cache = NULL;
/* It has not run yet, so cannot be present in anyone's
@@ -324,10 +325,12 @@ static inline int copy_mm(unsigned long clone_flags, struct task_struct * tsk)
goto free_mm;
retval = dup_mmap(mm);
if (retval)
- goto free_mm;
+ goto free_pt;
return 0;
free_mm:
+ mm->pgd = NULL;
+free_pt:
tsk->mm = NULL;
mmput(mm);
fail_nomem:
@@ -376,7 +379,13 @@ static inline int copy_files(unsigned long clone_flags, struct task_struct * tsk
struct files_struct *oldf, *newf;
struct file **old_fds, **new_fds;
+ /*
+ * A background process may not have any files ...
+ */
oldf = current->files;
+ if (!oldf)
+ return 0;
+
if (clone_flags & CLONE_FILES) {
oldf->count++;
return 0;
@@ -497,6 +506,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
/* ok, now we should be set up.. */
p->swappable = 1;
p->exit_signal = clone_flags & CSIGNAL;
+ p->pdeath_signal = 0;
/*
* "share" dynamic priority between parent and child, thus the
@@ -515,7 +525,9 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
}
++total_forks;
error = p->pid;
- goto fork_out;
+bad_fork:
+ unlock_kernel();
+ return error;
bad_fork_cleanup_sighand:
exit_sighand(p);
@@ -535,10 +547,7 @@ bad_fork_cleanup:
nr_tasks--;
bad_fork_free:
free_task_struct(p);
-bad_fork:
-fork_out:
- unlock_kernel();
- return error;
+ goto bad_fork;
}
static void files_ctor(void *fp, kmem_cache_t *cachep, unsigned long flags)
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index cb1f3be8e..c4cbdf56e 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -90,6 +90,10 @@ __attribute__((section("__ksymtab"))) = {
};
#endif
+
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(get_module_symbol);
+#endif
#ifdef CONFIG_KERNELD
EXPORT_SYMBOL(kerneld_send);
#endif
@@ -120,6 +124,7 @@ EXPORT_SYMBOL(exit_files);
/* internal kernel memory management */
EXPORT_SYMBOL(__get_free_pages);
EXPORT_SYMBOL(free_pages);
+EXPORT_SYMBOL(__free_page);
EXPORT_SYMBOL(kmem_find_general_cachep);
EXPORT_SYMBOL(kmem_cache_create);
EXPORT_SYMBOL(kmem_cache_shrink);
@@ -139,6 +144,7 @@ EXPORT_SYMBOL(update_vm_cache);
EXPORT_SYMBOL(vmtruncate);
/* filesystem internal functions */
+EXPORT_SYMBOL(get_super);
EXPORT_SYMBOL(getname);
EXPORT_SYMBOL(putname);
EXPORT_SYMBOL(__fput);
@@ -164,6 +170,7 @@ EXPORT_SYMBOL(check_disk_change);
EXPORT_SYMBOL(invalidate_buffers);
EXPORT_SYMBOL(invalidate_inodes);
EXPORT_SYMBOL(invalidate_inode_pages);
+EXPORT_SYMBOL(truncate_inode_pages);
EXPORT_SYMBOL(fsync_dev);
EXPORT_SYMBOL(permission);
EXPORT_SYMBOL(inode_setattr);
@@ -180,7 +187,6 @@ EXPORT_SYMBOL(__bforget);
EXPORT_SYMBOL(ll_rw_block);
EXPORT_SYMBOL(__wait_on_buffer);
EXPORT_SYMBOL(mark_buffer_uptodate);
-EXPORT_SYMBOL(unlock_buffer);
EXPORT_SYMBOL(add_blkdev_randomness);
EXPORT_SYMBOL(generic_file_read);
EXPORT_SYMBOL(generic_file_write);
@@ -192,6 +198,11 @@ EXPORT_SYMBOL(posix_test_lock);
EXPORT_SYMBOL(posix_block_lock);
EXPORT_SYMBOL(posix_unblock_lock);
EXPORT_SYMBOL(dput);
+EXPORT_SYMBOL(get_cached_page);
+EXPORT_SYMBOL(put_cached_page);
+EXPORT_SYMBOL(prune_dcache);
+EXPORT_SYMBOL(shrink_dcache_sb);
+EXPORT_SYMBOL(shrink_dcache_parent);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl);
@@ -225,12 +236,18 @@ EXPORT_SYMBOL(blkdev_release);
EXPORT_SYMBOL(gendisk_head);
EXPORT_SYMBOL(resetup_one_dev);
EXPORT_SYMBOL(unplug_device);
+EXPORT_SYMBOL(make_request);
+EXPORT_SYMBOL(tq_disk);
+EXPORT_SYMBOL(efind_buffer);
+EXPORT_SYMBOL(init_buffer);
/* tty routines */
EXPORT_SYMBOL(tty_hangup);
EXPORT_SYMBOL(tty_wait_until_sent);
EXPORT_SYMBOL(tty_check_change);
EXPORT_SYMBOL(tty_hung_up_p);
+EXPORT_SYMBOL(tty_flip_buffer_push);
+EXPORT_SYMBOL(tty_get_baud_rate);
EXPORT_SYMBOL(do_SAK);
EXPORT_SYMBOL(console_print);
@@ -351,7 +368,6 @@ EXPORT_SYMBOL(read_exec);
EXPORT_SYMBOL(si_meminfo);
/* Added to make file system as module */
-EXPORT_SYMBOL(get_super);
EXPORT_SYMBOL(set_writetime);
EXPORT_SYMBOL(sys_tz);
EXPORT_SYMBOL(__wait_on_super);
@@ -361,7 +377,6 @@ EXPORT_SYMBOL(refile_buffer);
EXPORT_SYMBOL(nr_async_pages);
EXPORT_SYMBOL(___strtok);
EXPORT_SYMBOL(init_fifo);
-EXPORT_SYMBOL(super_blocks);
EXPORT_SYMBOL(fifo_inode_operations);
EXPORT_SYMBOL(chrdev_inode_operations);
EXPORT_SYMBOL(blkdev_inode_operations);
@@ -369,6 +384,8 @@ EXPORT_SYMBOL(read_ahead);
EXPORT_SYMBOL(get_hash_table);
EXPORT_SYMBOL(get_empty_inode);
EXPORT_SYMBOL(insert_inode_hash);
+EXPORT_SYMBOL(make_bad_inode);
+EXPORT_SYMBOL(is_bad_inode);
EXPORT_SYMBOL(event);
EXPORT_SYMBOL(__down);
EXPORT_SYMBOL(__up);
diff --git a/kernel/module.c b/kernel/module.c
index 41ffd5734..aef180ff4 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -871,7 +871,6 @@ int get_module_list(char *p)
}
safe_copy_cstr("]");
}
-
safe_copy_cstr("\n");
#undef safe_copy_str
@@ -932,6 +931,34 @@ leave_the_loop:
return len;
}
+/*
+ * Gets the address for a symbol in the given module. If modname is
+ * NULL, it looks for the name in any registered symbol table. If the
+ * modname is an empty string, it looks for the symbol in kernel exported
+ * symbol tables.
+ */
+unsigned long
+get_module_symbol(char *modname, char *symname)
+{
+ struct module *mp;
+ struct module_symbol *sym;
+ int i;
+
+ for (mp = module_list; mp; mp = mp->next) {
+ if (((modname == NULL) || (strcmp(mp->name, modname) == 0)) &&
+ (mp->flags == MOD_RUNNING) && (mp->nsyms > 0)) {
+ for (i = mp->nsyms, sym = mp->syms;
+ i > 0; --i, ++sym) {
+
+ if (strcmp(sym->name, symname) == 0) {
+ return sym->value;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
#else /* CONFIG_MODULES */
/* Dummy syscalls for people who don't want modules */
diff --git a/kernel/printk.c b/kernel/printk.c
index 3d409f2d5..1070e5097 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -96,7 +96,7 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
cli();
error = -ERESTARTSYS;
while (!log_size) {
- if (current->signal & ~current->blocked) {
+ if (signal_pending(current)) {
sti();
goto out;
}
@@ -109,7 +109,7 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
log_size--;
log_start &= LOG_BUF_LEN-1;
sti();
- put_user(c,buf);
+ __put_user(c,buf);
buf++;
i++;
cli();
@@ -138,7 +138,7 @@ asmlinkage int sys_syslog(int type, char * buf, int len)
j = log_start + log_size - count;
for (i = 0; i < count; i++) {
c = *((char *) log_buf+(j++ & (LOG_BUF_LEN-1)));
- put_user(c, buf++);
+ __put_user(c, buf++);
}
if (do_clear)
logged_chars = 0;
diff --git a/kernel/sched.c b/kernel/sched.c
index 8b0290518..1d07cbc72 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -104,7 +104,7 @@ struct kernel_stat kstat = { 0 };
static inline void add_to_runqueue(struct task_struct * p)
{
- if (p->counter > current->counter + 3)
+ if (p->policy != SCHED_OTHER || p->counter > current->counter + 3)
need_resched = 1;
nr_running++;
(p->prev_run = init_task.prev_run)->next_run = p;
@@ -400,7 +400,7 @@ asmlinkage void schedule(void)
timeout = 0;
switch (prev->state) {
case TASK_INTERRUPTIBLE:
- if (prev->signal & ~prev->blocked)
+ if (signal_pending(prev))
goto makerunnable;
timeout = prev->timeout;
if (timeout && (timeout <= jiffies)) {
@@ -623,9 +623,7 @@ static inline int __do_down(struct semaphore * sem, int task_state)
if (waking_non_zero(sem)) /* are we waking up? */
break; /* yes, exit loop */
- if ( task_state == TASK_INTERRUPTIBLE
- && (tsk->signal & ~tsk->blocked) /* signalled */
- ) {
+ if (task_state == TASK_INTERRUPTIBLE && signal_pending(tsk)) {
ret = -EINTR; /* interrupted */
atomic_inc(&sem->count); /* give up on down operation */
break;
@@ -651,14 +649,14 @@ int __down_interruptible(struct semaphore * sem)
}
-static inline void __sleep_on(struct wait_queue **p, int state)
+static void FASTCALL(__sleep_on(struct wait_queue **p, int state));
+static void __sleep_on(struct wait_queue **p, int state)
{
unsigned long flags;
- struct wait_queue wait = { current, NULL };
+ struct wait_queue wait;
- if (!p)
- return;
current->state = state;
+ wait.task = current;
write_lock_irqsave(&waitqueue_lock, flags);
__add_wait_queue(p, &wait);
write_unlock(&waitqueue_lock);
diff --git a/kernel/sys.c b/kernel/sys.c
index 9459f9b4e..f28c993a1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -25,6 +25,7 @@
#include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
+#include <linux/prctl.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -357,8 +358,8 @@ int acct_process(long exitcode)
fs = get_fs();
set_fs(KERNEL_DS);
- acct_file.f_op->write(acct_file.f_dentry->d_inode, &acct_file,
- (char *)&ac, sizeof(struct acct));
+ acct_file.f_op->write(&acct_file, (char *)&ac, sizeof(struct acct),
+ &acct_file.f_pos);
set_fs(fs);
}
return 0;
@@ -1005,3 +1006,25 @@ asmlinkage int sys_umask(int mask)
mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
return mask;
}
+
+asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
+ unsigned long arg4, unsigned long arg5)
+{
+ int error = 0;
+ int sig;
+
+ switch (option) {
+ case PR_SET_PDEATHSIG:
+ sig = arg2;
+ if (sig > _NSIG) {
+ error = -EINVAL;
+ break;
+ }
+ current->pdeath_signal = sig;
+ break;
+ default:
+ error = -EINVAL;
+ break;
+ }
+ return error;
+}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 205190e9a..12abcefef 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -69,10 +69,8 @@ static ctl_table dev_table[];
#ifdef CONFIG_PROC_FS
-static long proc_readsys(struct inode * inode, struct file * file,
- char * buf, unsigned long count);
-static long proc_writesys(struct inode * inode, struct file * file,
- const char * buf, unsigned long count);
+static ssize_t proc_readsys(struct file *, char *, size_t, loff_t *);
+static ssize_t proc_writesys(struct file *, const char *, size_t, loff_t *);
static int proc_sys_permission(struct inode *, int);
struct file_operations proc_sys_file_operations =
@@ -113,6 +111,7 @@ struct inode_operations proc_sys_inode_operations =
extern struct proc_dir_entry proc_sys_root;
extern int inodes_stat[];
+extern int dentry_stat[];
static void register_proc_table(ctl_table *, struct proc_dir_entry *);
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
#endif
@@ -147,10 +146,12 @@ static ctl_table kern_table[] = {
0444, NULL, &proc_dointvec},
{KERN_MAXINODE, "inode-max", &max_inodes, sizeof(int),
0644, NULL, &proc_dointvec},
- {KERN_NRFILE, "file-nr", &nr_files, sizeof(int),
+ {KERN_NRFILE, "file-nr", &nr_files, 3*sizeof(int),
0444, NULL, &proc_dointvec},
{KERN_MAXFILE, "file-max", &max_files, sizeof(int),
0644, NULL, &proc_dointvec},
+ {KERN_DENTRY, "dentry-state", &dentry_stat, 6*sizeof(int),
+ 0444, NULL, &proc_dointvec},
{KERN_SECURELVL, "securelevel", &securelevel, sizeof(int),
0444, NULL, &proc_dointvec, (ctl_handler *)&do_securelevel_strategy},
{KERN_PANIC, "panic", &panic_timeout, sizeof(int),
@@ -522,17 +523,16 @@ static void unregister_proc_table(ctl_table * table, struct proc_dir_entry *root
}
}
-
-static long do_rw_proc(int write, struct inode * inode, struct file * file,
- char * buf, unsigned long count)
+static ssize_t do_rw_proc(int write, struct file * file, char * buf,
+ size_t count, loff_t *ppos)
{
int op;
struct proc_dir_entry *de;
struct ctl_table *table;
size_t res;
- long error;
+ ssize_t error;
- de = (struct proc_dir_entry*) inode->u.generic_ip;
+ de = (struct proc_dir_entry*) file->f_dentry->d_inode->u.generic_ip;
if (!de || !de->data)
return -ENOTDIR;
table = (struct ctl_table *) de->data;
@@ -543,22 +543,27 @@ static long do_rw_proc(int write, struct inode * inode, struct file * file,
return -EPERM;
res = count;
+
+ /*
+ * FIXME: we need to pass on ppos to the handler.
+ */
+
error = (*table->proc_handler) (table, write, file, buf, &res);
if (error)
return error;
return res;
}
-static long proc_readsys(struct inode * inode, struct file * file,
- char * buf, unsigned long count)
+static ssize_t proc_readsys(struct file * file, char * buf,
+ size_t count, loff_t *ppos)
{
- return do_rw_proc(0, inode, file, buf, count);
+ return do_rw_proc(0, file, buf, count, ppos);
}
-static long proc_writesys(struct inode * inode, struct file * file,
- const char * buf, unsigned long count)
+static ssize_t proc_writesys(struct file * file, const char * buf,
+ size_t count, loff_t *ppos)
{
- return do_rw_proc(1, inode, file, (char *) buf, count);
+ return do_rw_proc(1, file, (char *) buf, count, ppos);
}
static int proc_sys_permission(struct inode *inode, int op)