summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-29 01:41:54 +0000
commitf969d69ba9f952e5bdd38278e25e26a3e4a61a70 (patch)
treeb3530d803df59d726afaabebc6626987dee1ca05 /kernel
parenta10ce7ef2066b455d69187643ddf2073bfc4db24 (diff)
Merge with 2.3.27.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exec_domain.c12
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/kmod.c49
-rw-r--r--kernel/ksyms.c2
-rw-r--r--kernel/ptrace.c8
-rw-r--r--kernel/resource.c2
-rw-r--r--kernel/sys.c19
-rw-r--r--kernel/sysctl.c36
9 files changed, 105 insertions, 29 deletions
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index 4aa968ee1..c31678a4e 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -125,3 +125,15 @@ out:
unlock_kernel();
return ret;
}
+
+int get_exec_domain_list(char * page)
+{
+ int len = 0;
+ struct exec_domain * e;
+
+ for (e=exec_domains; e && len < PAGE_SIZE - 80; e=e->next)
+ len += sprintf(page+len, "%d-%d\t%-16s\t[%s]\n",
+ e->pers_low, e->pers_high, e->name,
+ e->module ? e->module->name : "kernel");
+ return len;
+}
diff --git a/kernel/exit.c b/kernel/exit.c
index 2ca64035c..374241c67 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -402,6 +402,7 @@ fake_volatile:
#ifdef CONFIG_BSD_PROCESS_ACCT
acct_process(code);
#endif
+ task_lock(tsk);
sem_exit();
__exit_mm(tsk);
#if CONFIG_AP1000
@@ -414,6 +415,7 @@ fake_volatile:
tsk->state = TASK_ZOMBIE;
tsk->exit_code = code;
exit_notify();
+ task_unlock(tsk);
#ifdef DEBUG_PROC_TREE
audit_ptree();
#endif
@@ -455,6 +457,7 @@ asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struc
add_wait_queue(&current->wait_chldexit,&wait);
repeat:
flag = 0;
+ current->state = TASK_INTERRUPTIBLE;
read_lock(&tasklist_lock);
for (p = current->p_cptr ; p ; p = p->p_osptr) {
if (pid>0) {
@@ -521,12 +524,12 @@ repeat:
retval = -ERESTARTSYS;
if (signal_pending(current))
goto end_wait4;
- current->state=TASK_INTERRUPTIBLE;
schedule();
goto repeat;
}
retval = -ECHILD;
end_wait4:
+ current->state = TASK_RUNNING;
remove_wait_queue(&current->wait_chldexit,&wait);
return retval;
}
diff --git a/kernel/fork.c b/kernel/fork.c
index 2cce575fc..a90a6bc47 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -650,6 +650,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
p->p_cptr = NULL;
init_waitqueue_head(&p->wait_chldexit);
p->vfork_sem = NULL;
+ sema_init(&p->exit_sem, 1);
p->sigpending = 0;
sigemptyset(&p->signal);
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 8b19e2415..36d754380 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -23,22 +23,36 @@
char modprobe_path[256] = "/sbin/modprobe";
static inline void
-use_init_file_context(void)
+use_init_fs_context(void)
{
- struct fs_struct * fs;
-
- lock_kernel();
+ struct fs_struct *our_fs, *init_fs;
/*
- * 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
+ * Make modprobe's fs context be a copy of init's.
+ *
+ * We cannot use the user's fs context, because it
+ * may have a different root than init.
+ * Since init was created with CLONE_FS, we can grab
+ * its fs context from "init_task".
+ *
+ * The fs context has to be a copy. If it is shared
+ * with init, then any chdir() call in modprobe will
+ * also affect init and the other threads sharing
+ * init_task's fs context.
+ *
+ * We created the exec_modprobe thread without CLONE_FS,
+ * so we can update the fields in our fs context freely.
*/
- exit_fs(current); /* current->fs->count--; */
- fs = init_task.fs;
- current->fs = fs;
- atomic_inc(&fs->count);
+ lock_kernel();
+
+ our_fs = current->fs;
+ dput(our_fs->root);
+ dput(our_fs->pwd);
+
+ init_fs = init_task.fs;
+ our_fs->umask = init_fs->umask;
+ our_fs->root = dget(init_fs->root);
+ our_fs->pwd = dget(init_fs->pwd);
unlock_kernel();
}
@@ -49,7 +63,10 @@ static int exec_modprobe(void * module_name)
char *argv[] = { modprobe_path, "-s", "-k", (char*)module_name, NULL };
int i;
- use_init_file_context();
+ current->session = 1;
+ current->pgrp = 1;
+
+ use_init_fs_context();
/* Prevent parent user process from sending signals to child.
Otherwise, if the modprobe program does not exist, it might
@@ -104,7 +121,7 @@ int request_module(const char * module_name)
return -EPERM;
}
- pid = kernel_thread(exec_modprobe, (void*) module_name, CLONE_FS);
+ pid = kernel_thread(exec_modprobe, (void*) module_name, 0);
if (pid < 0) {
printk(KERN_ERR "request_module[%s]: fork failed, errno %d\n", module_name, -pid);
return pid;
@@ -126,8 +143,8 @@ int request_module(const char * module_name)
spin_unlock_irq(&current->sigmask_lock);
if (waitpid_result != pid) {
- printk (KERN_ERR "kmod: waitpid(%d,NULL,0) failed, returning %d.\n",
- pid, waitpid_result);
+ printk(KERN_ERR "request_module[%s]: waitpid(%d,...) failed, errno %d\n",
+ module_name, pid, -waitpid_result);
}
return 0;
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 52952cf97..555e735d0 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -93,7 +93,6 @@ EXPORT_SYMBOL(exit_sighand);
/* internal kernel memory management */
EXPORT_SYMBOL(__get_free_pages);
-EXPORT_SYMBOL(__get_pages);
EXPORT_SYMBOL(free_pages);
EXPORT_SYMBOL(__free_page);
EXPORT_SYMBOL(kmem_find_general_cachep);
@@ -192,6 +191,7 @@ EXPORT_SYMBOL(posix_lock_file);
EXPORT_SYMBOL(posix_test_lock);
EXPORT_SYMBOL(posix_block_lock);
EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(locks_mandatory_area);
EXPORT_SYMBOL(dput);
EXPORT_SYMBOL(put_cached_page);
EXPORT_SYMBOL(is_root_busy);
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 4945a0223..2980059b2 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -50,15 +50,15 @@ repeat:
flush_cache_page(vma, addr);
if (write) {
- maddr = kmap(page, KM_WRITE);
+ maddr = kmap(page);
memcpy((char *)maddr + (addr & ~PAGE_MASK), buf, len);
flush_page_to_ram(page);
- kunmap(maddr, KM_WRITE);
+ kunmap(page);
} else {
- maddr = kmap(page, KM_READ);
+ maddr = kmap(page);
memcpy(buf, (char *)maddr + (addr & ~PAGE_MASK), len);
flush_page_to_ram(page);
- kunmap(maddr, KM_READ);
+ kunmap(page);
}
return len;
diff --git a/kernel/resource.c b/kernel/resource.c
index 26ee5e29d..e3dd3a16d 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -20,7 +20,7 @@ struct resource iomem_resource = { "PCI mem", 0x00000000, 0xFFFFFFFF, IORESOURCE
static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
/*
- * This generates reports for /proc/ioports and /proc/memory
+ * This generates reports for /proc/ioports and /proc/iomem
*/
static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end)
{
diff --git a/kernel/sys.c b/kernel/sys.c
index a0179d14e..344e56f35 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -896,6 +896,25 @@ asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim)
? -EFAULT : 0;
}
+/*
+ * Back compatibility for getrlimit. Needed for some apps.
+ */
+
+asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim)
+{
+ struct rlimit x;
+ if (resource >= RLIM_NLIMITS)
+ return -EINVAL;
+
+ memcpy(&x, current->rlim + resource, sizeof(*rlim));
+ if(x.rlim_cur > 0x7FFFFFFF)
+ x.rlim_cur = 0x7FFFFFFF;
+ if(x.rlim_max > 0x7FFFFFFF)
+ x.rlim_max = 0x7FFFFFFF;
+ return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
+}
+
+
asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim)
{
struct rlimit new_rlim, *old_rlim;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 5b8638cdc..f18ad13c1 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -49,7 +49,11 @@ extern char modprobe_path[];
extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
-extern int shmmax;
+extern size_t shm_prm[];
+extern int msg_ctlmax;
+extern int msg_ctlmnb;
+extern int msg_ctlmni;
+extern int sem_ctls[];
#endif
#ifdef __sparc__
@@ -136,7 +140,7 @@ struct inode_operations proc_sys_inode_operations =
NULL /* revalidate */
};
-extern struct proc_dir_entry proc_sys_root;
+extern struct proc_dir_entry *proc_sys_root;
static void register_proc_table(ctl_table *, struct proc_dir_entry *);
static void unregister_proc_table(ctl_table *, struct proc_dir_entry *);
@@ -213,7 +217,15 @@ static ctl_table kern_table[] = {
{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
0644, NULL, &proc_dointvec},
#ifdef CONFIG_SYSVIPC
- {KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
+ {KERN_SHMMAX, "shmmax", &shm_prm, 3*sizeof (size_t),
+ 0644, NULL, &proc_doulongvec_minmax},
+ {KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_MSGMNB, "msgmnb", &msg_ctlmnb, sizeof (int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_SEM, "sem", &sem_ctls, 4*sizeof (int),
0644, NULL, &proc_dointvec},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
@@ -285,7 +297,7 @@ static ctl_table dev_table[] = {
void __init sysctl_init(void)
{
#ifdef CONFIG_PROC_FS
- register_proc_table(root_table, &proc_sys_root);
+ register_proc_table(root_table, proc_sys_root);
#endif
}
@@ -480,7 +492,7 @@ struct ctl_table_header *register_sysctl_table(ctl_table * table,
else
DLIST_INSERT_BEFORE(&root_table_header, tmp, ctl_entry);
#ifdef CONFIG_PROC_FS
- register_proc_table(table, &proc_sys_root);
+ register_proc_table(table, proc_sys_root);
#endif
return tmp;
}
@@ -492,7 +504,7 @@ void unregister_sysctl_table(struct ctl_table_header * header)
{
DLIST_DELETE(header, ctl_entry);
#ifdef CONFIG_PROC_FS
- unregister_proc_table(header->ctl_table, &proc_sys_root);
+ unregister_proc_table(header->ctl_table, proc_sys_root);
#endif
kfree(header);
}
@@ -1067,6 +1079,12 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp,
return -ENOSYS;
}
+int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return -ENOSYS;
+}
+
int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
@@ -1312,6 +1330,12 @@ int proc_dointvec(ctl_table *table, int write, struct file *filp,
return -ENOSYS;
}
+int proc_dointvec_bset(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return -ENOSYS;
+}
+
int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{