summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/fcntl.c6
-rw-r--r--fs/open.c5
-rw-r--r--fs/proc/kcore.c5
-rw-r--r--fs/super.c19
4 files changed, 21 insertions, 14 deletions
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 659821873..35a5dbc7d 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -132,7 +132,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
struct file * file;
struct files_struct * files = current->files;
- write_lock(&current->files->file_lock);
+ write_lock(&files->file_lock);
if (!(file = fcheck(oldfd)))
goto out_unlock;
err = newfd;
@@ -158,7 +158,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
FD_SET(newfd, files->open_fds);
write_unlock(&files->file_lock);
- do_close(newfd, 0);
+ do_close(files, newfd, 0);
write_lock(&files->file_lock);
allocate_fd(files, file, newfd);
@@ -167,7 +167,7 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
out:
return err;
out_unlock:
- write_unlock(&current->files->file_lock);
+ write_unlock(&files->file_lock);
goto out;
}
diff --git a/fs/open.c b/fs/open.c
index dc2eaebe9..c42b15a41 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -804,11 +804,10 @@ int filp_close(struct file *filp, fl_owner_t id)
* or not in the open-files bitmap. dup2 uses this to retain the fd
* without races.
*/
-int do_close(unsigned int fd, int release)
+int do_close(struct files_struct *files, unsigned int fd, int release)
{
int error;
struct file * filp;
- struct files_struct * files = current->files;
error = -EBADF;
write_lock(&files->file_lock);
@@ -829,7 +828,7 @@ out_unlock:
asmlinkage long sys_close(unsigned int fd)
{
- return do_close(fd, 1);
+ return do_close(current->files, fd, 1);
}
/*
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 01db469da..fe944bab6 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -17,6 +17,7 @@
#include <linux/elfcore.h>
#include <linux/vmalloc.h>
#include <asm/uaccess.h>
+#include <asm/io.h>
static int open_kcore(struct inode * inode, struct file * filp)
@@ -47,7 +48,7 @@ static ssize_t read_kcore(struct file *file, char *buf, size_t count, loff_t *pp
memset(&dump, 0, sizeof(struct user));
dump.magic = CMAGIC;
- dump.u_dsize = max_mapnr;
+ dump.u_dsize = (virt_to_phys(high_memory) >> PAGE_SHIFT);
#if defined (__i386__)
dump.start_code = PAGE_OFFSET;
#endif
@@ -55,7 +56,7 @@ static ssize_t read_kcore(struct file *file, char *buf, size_t count, loff_t *pp
dump.start_data = PAGE_OFFSET;
#endif
- memsize = (max_mapnr + 1) << PAGE_SHIFT;
+ memsize = virt_to_phys(high_memory);
if (p >= memsize)
return 0;
if (count > memsize - p)
diff --git a/fs/super.c b/fs/super.c
index 91e17f2b6..8576d79d0 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1566,15 +1566,22 @@ static void chroot_fs_refs(struct dentry *old_root,
struct vfsmount *new_rootmnt)
{
struct task_struct *p;
+ struct fs_struct *fs;
read_lock(&tasklist_lock);
for_each_task(p) {
- /* FIXME - unprotected usage of ->fs + (harmless) race */
- if (!p->fs) continue;
- if (p->fs->root == old_root && p->fs->rootmnt == old_rootmnt)
- set_fs_root(p->fs, new_rootmnt, new_root);
- if (p->fs->pwd == old_root && p->fs->pwdmnt == old_rootmnt)
- set_fs_pwd(p->fs, new_rootmnt, new_root);
+ task_lock(p);
+ fs = p->fs;
+ if (fs) {
+ atomic_inc(&fs->count);
+ task_unlock(p);
+ if (fs->root==old_root && fs->rootmnt==old_rootmnt)
+ set_fs_root(fs, new_rootmnt, new_root);
+ if (fs->pwd==old_root && fs->pwdmnt==old_rootmnt)
+ set_fs_pwd(fs, new_rootmnt, new_root);
+ put_fs_struct(fs);
+ } else
+ task_unlock(p);
}
read_unlock(&tasklist_lock);
}