patch-2.3.99-pre9 linux/fs/exec.c
Next file: linux/fs/ext2/balloc.c
Previous file: linux/fs/devfs/util.c
Back to the patch index
Back to the overall index
- Lines: 161
- Date:
Sun May 21 11:38:47 2000
- Orig file:
v2.3.99-pre8/linux/fs/exec.c
- Orig date:
Thu May 11 15:30:08 2000
diff -u --recursive --new-file v2.3.99-pre8/linux/fs/exec.c linux/fs/exec.c
@@ -45,8 +45,8 @@
#include <linux/kmod.h>
#endif
-static struct linux_binfmt *formats = (struct linux_binfmt *) NULL;
-static spinlock_t binfmt_lock = SPIN_LOCK_UNLOCKED;
+static struct linux_binfmt *formats;
+static rwlock_t binfmt_lock = RW_LOCK_UNLOCKED;
int register_binfmt(struct linux_binfmt * fmt)
{
@@ -56,17 +56,17 @@
return -EINVAL;
if (fmt->next)
return -EBUSY;
- spin_lock(&binfmt_lock);
+ write_lock(&binfmt_lock);
while (*tmp) {
if (fmt == *tmp) {
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
return -EBUSY;
}
tmp = &(*tmp)->next;
}
fmt->next = formats;
formats = fmt;
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
return 0;
}
@@ -74,16 +74,16 @@
{
struct linux_binfmt ** tmp = &formats;
- spin_lock(&binfmt_lock);
+ write_lock(&binfmt_lock);
while (*tmp) {
if (fmt == *tmp) {
*tmp = fmt->next;
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
return 0;
}
tmp = &(*tmp)->next;
}
- spin_unlock(&binfmt_lock);
+ write_unlock(&binfmt_lock);
return -EINVAL;
}
@@ -103,35 +103,34 @@
{
int fd, retval;
struct file * file;
- struct linux_binfmt * fmt;
- lock_kernel();
fd = sys_open(library, 0, 0);
- retval = fd;
if (fd < 0)
- goto out;
+ return fd;
file = fget(fd);
retval = -ENOEXEC;
- if (file && file->f_op && file->f_op->read) {
- spin_lock(&binfmt_lock);
- for (fmt = formats ; fmt ; fmt = fmt->next) {
- if (!fmt->load_shlib)
- continue;
- if (!try_inc_mod_count(fmt->module))
- continue;
- spin_unlock(&binfmt_lock);
- retval = fmt->load_shlib(file);
- spin_lock(&binfmt_lock);
- put_binfmt(fmt);
- if (retval != -ENOEXEC)
- break;
+ if (file) {
+ if(file->f_op && file->f_op->read) {
+ struct linux_binfmt * fmt;
+
+ read_lock(&binfmt_lock);
+ for (fmt = formats ; fmt ; fmt = fmt->next) {
+ if (!fmt->load_shlib)
+ continue;
+ if (!try_inc_mod_count(fmt->module))
+ continue;
+ read_unlock(&binfmt_lock);
+ retval = fmt->load_shlib(file);
+ read_lock(&binfmt_lock);
+ put_binfmt(fmt);
+ if (retval != -ENOEXEC)
+ break;
+ }
+ read_unlock(&binfmt_lock);
}
- spin_unlock(&binfmt_lock);
+ fput(file);
}
- fput(file);
sys_close(fd);
-out:
- unlock_kernel();
return retval;
}
@@ -288,6 +287,7 @@
if (!mpnt)
return -ENOMEM;
+ down(¤t->mm->mmap_sem);
{
mpnt->vm_mm = current->mm;
mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p;
@@ -311,6 +311,7 @@
}
stack_base += PAGE_SIZE;
}
+ up(¤t->mm->mmap_sem);
return 0;
}
@@ -745,14 +746,14 @@
}
#endif
for (try=0; try<2; try++) {
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
for (fmt = formats ; fmt ; fmt = fmt->next) {
int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
if (!fn)
continue;
if (!try_inc_mod_count(fmt->module))
continue;
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
retval = fn(bprm, regs);
if (retval >= 0) {
put_binfmt(fmt);
@@ -762,16 +763,16 @@
current->did_exec = 1;
return retval;
}
- spin_lock(&binfmt_lock);
+ read_lock(&binfmt_lock);
put_binfmt(fmt);
if (retval != -ENOEXEC)
break;
if (!bprm->file) {
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
return retval;
}
}
- spin_unlock(&binfmt_lock);
+ read_unlock(&binfmt_lock);
if (retval != -ENOEXEC) {
break;
#ifdef CONFIG_KMOD
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)