diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/fcntl.c | 6 | ||||
-rw-r--r-- | fs/open.c | 5 | ||||
-rw-r--r-- | fs/proc/kcore.c | 5 | ||||
-rw-r--r-- | fs/super.c | 19 |
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(¤t->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(¤t->files->file_lock); + write_unlock(&files->file_lock); goto out; } @@ -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); } |