diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-03-13 20:55:15 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-03-13 20:55:15 +0000 |
commit | 1471f525455788c20b130690e0f104df451aeb43 (patch) | |
tree | 3778beba56558beb9a9548ea5b467e9c44ea966f /kernel | |
parent | e80d2c5456d30ebba5b0eb8a9d33e17d815d4d83 (diff) |
Merge with Linux 2.3.51.
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/acct.c | 12 | ||||
-rw-r--r-- | kernel/exit.c | 12 | ||||
-rw-r--r-- | kernel/fork.c | 4 | ||||
-rw-r--r-- | kernel/ksyms.c | 19 | ||||
-rw-r--r-- | kernel/module.c | 35 | ||||
-rw-r--r-- | kernel/signal.c | 2 | ||||
-rw-r--r-- | kernel/sys.c | 46 | ||||
-rw-r--r-- | kernel/sysctl.c | 28 |
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. */ |