summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-03-13 20:55:15 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-03-13 20:55:15 +0000
commit1471f525455788c20b130690e0f104df451aeb43 (patch)
tree3778beba56558beb9a9548ea5b467e9c44ea966f /kernel
parente80d2c5456d30ebba5b0eb8a9d33e17d815d4d83 (diff)
Merge with Linux 2.3.51.
Diffstat (limited to 'kernel')
-rw-r--r--kernel/acct.c12
-rw-r--r--kernel/exit.c12
-rw-r--r--kernel/fork.c4
-rw-r--r--kernel/ksyms.c19
-rw-r--r--kernel/module.c35
-rw-r--r--kernel/signal.c2
-rw-r--r--kernel/sys.c46
-rw-r--r--kernel/sysctl.c28
8 files changed, 97 insertions, 61 deletions
diff --git a/kernel/acct.c b/kernel/acct.c
index fdadf7a9f..63e66a558 100644
--- a/kernel/acct.c
+++ b/kernel/acct.c
@@ -88,24 +88,16 @@ void acct_timeout(unsigned long unused)
*/
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 (!file || !acct_needcheck)
return res;
- 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);
/* May block */
- sb->s_op->statfs(sb, &sbuf, sizeof(struct statfs));
- set_fs(fs);
+ if (vfs_statfs(file->f_dentry->d_inode->i_sb, &sbuf))
+ return res;
if (sbuf.f_bavail <= SUSPEND * sbuf.f_blocks / 100)
act = -1;
diff --git a/kernel/exit.c b/kernel/exit.c
index 9dd09f050..333981ab9 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -45,6 +45,18 @@ void release(struct task_struct * p)
current->cmin_flt += p->min_flt + p->cmin_flt;
current->cmaj_flt += p->maj_flt + p->cmaj_flt;
current->cnswap += p->nswap + p->cnswap;
+ /*
+ * Potentially available timeslices are retrieved
+ * here - this way the parent does not get penalized
+ * for creating too many processes.
+ *
+ * (this cannot be used to artificially 'generate'
+ * timeslices, because any timeslice recovered here
+ * was given away by the parent in the first place.)
+ */
+ current->counter += p->counter;
+ if (current->counter > current->priority)
+ current->counter = current->priority;
free_task_struct(p);
} else {
printk("task releasing itself\n");
diff --git a/kernel/fork.c b/kernel/fork.c
index 71989b3f7..f30adb908 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -713,8 +713,10 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
* more scheduling fairness. This is only important in the first
* timeslice, on the long run the scheduling behaviour is unchanged.
*/
+ p->counter = (current->counter + 1) >> 1;
current->counter >>= 1;
- p->counter = current->counter;
+ if (!current->counter)
+ current->need_resched = 1;
/*
* Ok, add it to the run-queues and make it
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 45594e6af..78b40185d 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -131,7 +131,6 @@ EXPORT_SYMBOL(def_blk_fops);
EXPORT_SYMBOL(in_group_p);
EXPORT_SYMBOL(update_atime);
EXPORT_SYMBOL(get_super);
-EXPORT_SYMBOL(get_fs_type);
EXPORT_SYMBOL(get_empty_super);
EXPORT_SYMBOL(remove_vfsmnt);
EXPORT_SYMBOL(getname);
@@ -157,11 +156,6 @@ EXPORT_SYMBOL(d_path);
EXPORT_SYMBOL(mark_buffer_dirty);
EXPORT_SYMBOL(__mark_buffer_dirty);
EXPORT_SYMBOL(__mark_inode_dirty);
-EXPORT_SYMBOL(free_kiovec);
-EXPORT_SYMBOL(brw_kiovec);
-EXPORT_SYMBOL(alloc_kiovec);
-EXPORT_SYMBOL(expand_kiobuf);
-EXPORT_SYMBOL(unmap_kiobuf);
EXPORT_SYMBOL(get_empty_filp);
EXPORT_SYMBOL(init_private_file);
EXPORT_SYMBOL(filp_open);
@@ -358,6 +352,18 @@ EXPORT_SYMBOL(__br_write_lock);
EXPORT_SYMBOL(__br_write_unlock);
#endif
+/* Kiobufs */
+EXPORT_SYMBOL(kiobuf_init);
+
+EXPORT_SYMBOL(alloc_kiovec);
+EXPORT_SYMBOL(free_kiovec);
+EXPORT_SYMBOL(expand_kiobuf);
+
+EXPORT_SYMBOL(map_user_kiobuf);
+EXPORT_SYMBOL(lock_kiovec);
+EXPORT_SYMBOL(unlock_kiovec);
+EXPORT_SYMBOL(brw_kiovec);
+
/* autoirq from drivers/net/auto_irq.c */
EXPORT_SYMBOL(autoirq_setup);
EXPORT_SYMBOL(autoirq_report);
@@ -393,6 +399,7 @@ EXPORT_SYMBOL(schedule_timeout);
EXPORT_SYMBOL(jiffies);
EXPORT_SYMBOL(xtime);
EXPORT_SYMBOL(do_gettimeofday);
+EXPORT_SYMBOL(do_settimeofday);
#ifndef __ia64__
EXPORT_SYMBOL(loops_per_sec);
#endif
diff --git a/kernel/module.c b/kernel/module.c
index fb9d4ef8d..c36964022 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -350,6 +350,21 @@ err0:
return error;
}
+static spinlock_t unload_lock = SPIN_LOCK_UNLOCKED;
+int try_inc_mod_count(struct module *mod)
+{
+ int res = 1;
+ if (mod) {
+ spin_lock(&unload_lock);
+ if (mod->flags & MOD_DELETED)
+ res = 0;
+ else
+ __MOD_INC_USE_COUNT(mod);
+ spin_unlock(&unload_lock);
+ }
+ return res;
+}
+
asmlinkage long
sys_delete_module(const char *name_user)
{
@@ -377,11 +392,18 @@ sys_delete_module(const char *name_user)
}
put_mod_name(name);
error = -EBUSY;
- if (mod->refs != NULL || __MOD_IN_USE(mod))
+ if (mod->refs != NULL)
goto out;
- free_module(mod, 0);
- error = 0;
+ spin_lock(&unload_lock);
+ if (!__MOD_IN_USE(mod)) {
+ mod->flags |= MOD_DELETED;
+ spin_unlock(&unload_lock);
+ free_module(mod, 0);
+ error = 0;
+ } else {
+ spin_unlock(&unload_lock);
+ }
goto out;
}
@@ -390,6 +412,7 @@ restart:
something_changed = 0;
for (mod = module_list; mod != &kernel_module; mod = next) {
next = mod->next;
+ spin_lock(&unload_lock);
if (mod->refs == NULL
&& (mod->flags & MOD_AUTOCLEAN)
&& (mod->flags & MOD_RUNNING)
@@ -398,11 +421,16 @@ restart:
&& !__MOD_IN_USE(mod)) {
if ((mod->flags & MOD_VISITED)
&& !(mod->flags & MOD_JUST_FREED)) {
+ spin_unlock(&unload_lock);
mod->flags &= ~MOD_VISITED;
} else {
+ mod->flags |= MOD_DELETED;
+ spin_unlock(&unload_lock);
free_module(mod, 1);
something_changed = 1;
}
+ } else {
+ spin_unlock(&unload_lock);
}
}
if (something_changed)
@@ -775,7 +803,6 @@ free_module(struct module *mod, int tag_freed)
/* Let the module clean up. */
- mod->flags |= MOD_DELETED;
if (mod->flags & MOD_RUNNING)
{
if(mod->cleanup)
diff --git a/kernel/signal.c b/kernel/signal.c
index dca49b492..55017e2f6 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -40,6 +40,8 @@ void __init signals_init(void)
sizeof(struct signal_queue),
__alignof__(struct signal_queue),
SIG_SLAB_DEBUG, NULL, NULL);
+ if (!signal_queue_cachep)
+ panic("signals_init(): cannot create signal_queue SLAB cache");
}
diff --git a/kernel/sys.c b/kernel/sys.c
index 550df4db9..1748d8afd 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -808,23 +808,39 @@ asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist)
return 0;
}
-int in_group_p(gid_t grp)
+static int supplemental_group_member(gid_t grp)
{
- if (grp != current->fsgid) {
- int i = current->ngroups;
- if (i) {
- gid_t *groups = current->groups;
- do {
- if (*groups == grp)
- goto out;
- groups++;
- i--;
- } while (i);
- }
- return 0;
+ int i = current->ngroups;
+
+ if (i) {
+ gid_t *groups = current->groups;
+ do {
+ if (*groups == grp)
+ return 1;
+ groups++;
+ i--;
+ } while (i);
}
-out:
- return 1;
+ return 0;
+}
+
+/*
+ * Check whether we're fsgid/egid or in the supplemental group..
+ */
+int in_group_p(gid_t grp)
+{
+ int retval = 1;
+ if (grp != current->fsgid)
+ retval = supplemental_group_member(grp);
+ return retval;
+}
+
+int in_egroup_p(gid_t grp)
+{
+ int retval = 1;
+ if (grp != current->egid)
+ retval = supplemental_group_member(grp);
+ return retval;
}
DECLARE_RWSEM(uts_sem);
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index efcda3de4..0001a1473 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -57,8 +57,7 @@ extern int sg_big_buff;
#endif
#ifdef CONFIG_SYSVIPC
extern size_t shm_ctlmax;
-extern int shm_ctlall;
-extern int shm_ctlmni;
+extern char shm_path[];
extern int msg_ctlmax;
extern int msg_ctlmnb;
extern int msg_ctlmni;
@@ -200,12 +199,10 @@ static ctl_table kern_table[] = {
{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
0644, NULL, &proc_dointvec},
#ifdef CONFIG_SYSVIPC
+ {KERN_SHMPATH, "shmpath", &shm_path, 256,
+ 0644, NULL, &proc_dostring, &sysctl_string },
{KERN_SHMMAX, "shmmax", &shm_ctlmax, sizeof (size_t),
0644, NULL, &proc_doulongvec_minmax},
- {KERN_SHMALL, "shmall", &shm_ctlall, sizeof (int),
- 0644, NULL, &proc_dointvec},
- {KERN_SHMMNI, "shmmni", &shm_ctlmni, sizeof (int),
- 0644, NULL, &proc_dointvec},
{KERN_MSGMAX, "msgmax", &msg_ctlmax, sizeof (int),
0644, NULL, &proc_dointvec},
{KERN_MSGMNI, "msgmni", &msg_ctlmni, sizeof (int),
@@ -351,25 +348,6 @@ extern asmlinkage long sys_sysctl(struct __sysctl_args *args)
return error;
}
-/* Like in_group_p, but testing against egid, not fsgid */
-int in_egroup_p(gid_t grp)
-{
- if (grp != current->egid) {
- int i = current->ngroups;
- if (i) {
- gid_t *groups = current->groups;
- do {
- if (*groups == grp)
- goto out;
- groups++;
- i--;
- } while (i);
- }
- return 0;
- }
-out:
- return 1;
-}
/* ctl_perm does NOT grant the superuser all rights automatically, because
some sysctl variables are readonly even to root. */