diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-12-06 23:51:34 +0000 |
commit | 230e5ab6a084ed50470f101934782dbf54b0d06b (patch) | |
tree | 5dd821c8d33f450470588e7a543f74bf74306e9e /kernel | |
parent | c9b1c8a64c6444d189856f1e26bdcb8b4cd0113a (diff) |
Merge with Linux 2.1.67.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 7 | ||||
-rw-r--r-- | kernel/fork.c | 29 | ||||
-rw-r--r-- | kernel/ksyms.c | 23 | ||||
-rw-r--r-- | kernel/module.c | 29 | ||||
-rw-r--r-- | kernel/printk.c | 6 | ||||
-rw-r--r-- | kernel/sched.c | 16 | ||||
-rw-r--r-- | kernel/sys.c | 27 | ||||
-rw-r--r-- | kernel/sysctl.c | 37 |
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(¤t->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) |