aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namespace.c28
-rw-r--r--fs/open.c12
-rw-r--r--include/linux/fs_struct.h4
3 files changed, 20 insertions, 24 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index ac19212c9bc3..eef57635ee07 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1650,15 +1650,14 @@ out1:
1650 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. 1650 * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
1651 * It can block. Requires the big lock held. 1651 * It can block. Requires the big lock held.
1652 */ 1652 */
1653void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, 1653void set_fs_root(struct fs_struct *fs, struct path *path)
1654 struct dentry *dentry)
1655{ 1654{
1656 struct path old_root; 1655 struct path old_root;
1657 1656
1658 write_lock(&fs->lock); 1657 write_lock(&fs->lock);
1659 old_root = fs->root; 1658 old_root = fs->root;
1660 fs->root.mnt = mntget(mnt); 1659 fs->root = *path;
1661 fs->root.dentry = dget(dentry); 1660 path_get(path);
1662 write_unlock(&fs->lock); 1661 write_unlock(&fs->lock);
1663 if (old_root.dentry) 1662 if (old_root.dentry)
1664 path_put(&old_root); 1663 path_put(&old_root);
@@ -1668,15 +1667,14 @@ void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt,
1668 * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. 1667 * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values.
1669 * It can block. Requires the big lock held. 1668 * It can block. Requires the big lock held.
1670 */ 1669 */
1671void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, 1670void set_fs_pwd(struct fs_struct *fs, struct path *path)
1672 struct dentry *dentry)
1673{ 1671{
1674 struct path old_pwd; 1672 struct path old_pwd;
1675 1673
1676 write_lock(&fs->lock); 1674 write_lock(&fs->lock);
1677 old_pwd = fs->pwd; 1675 old_pwd = fs->pwd;
1678 fs->pwd.mnt = mntget(mnt); 1676 fs->pwd = *path;
1679 fs->pwd.dentry = dget(dentry); 1677 path_get(path);
1680 write_unlock(&fs->lock); 1678 write_unlock(&fs->lock);
1681 1679
1682 if (old_pwd.dentry) 1680 if (old_pwd.dentry)
@@ -1697,12 +1695,10 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
1697 task_unlock(p); 1695 task_unlock(p);
1698 if (fs->root.dentry == old_nd->path.dentry 1696 if (fs->root.dentry == old_nd->path.dentry
1699 && fs->root.mnt == old_nd->path.mnt) 1697 && fs->root.mnt == old_nd->path.mnt)
1700 set_fs_root(fs, new_nd->path.mnt, 1698 set_fs_root(fs, &new_nd->path);
1701 new_nd->path.dentry);
1702 if (fs->pwd.dentry == old_nd->path.dentry 1699 if (fs->pwd.dentry == old_nd->path.dentry
1703 && fs->pwd.mnt == old_nd->path.mnt) 1700 && fs->pwd.mnt == old_nd->path.mnt)
1704 set_fs_pwd(fs, new_nd->path.mnt, 1701 set_fs_pwd(fs, &new_nd->path);
1705 new_nd->path.dentry);
1706 put_fs_struct(fs); 1702 put_fs_struct(fs);
1707 } else 1703 } else
1708 task_unlock(p); 1704 task_unlock(p);
@@ -1845,6 +1841,7 @@ static void __init init_mount_tree(void)
1845{ 1841{
1846 struct vfsmount *mnt; 1842 struct vfsmount *mnt;
1847 struct mnt_namespace *ns; 1843 struct mnt_namespace *ns;
1844 struct path root;
1848 1845
1849 mnt = do_kern_mount("rootfs", 0, "rootfs", NULL); 1846 mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);
1850 if (IS_ERR(mnt)) 1847 if (IS_ERR(mnt))
@@ -1863,8 +1860,11 @@ static void __init init_mount_tree(void)
1863 init_task.nsproxy->mnt_ns = ns; 1860 init_task.nsproxy->mnt_ns = ns;
1864 get_mnt_ns(ns); 1861 get_mnt_ns(ns);
1865 1862
1866 set_fs_pwd(current->fs, ns->root, ns->root->mnt_root); 1863 root.mnt = ns->root;
1867 set_fs_root(current->fs, ns->root, ns->root->mnt_root); 1864 root.dentry = ns->root->mnt_root;
1865
1866 set_fs_pwd(current->fs, &root);
1867 set_fs_root(current->fs, &root);
1868} 1868}
1869 1869
1870void __init mnt_init(void) 1870void __init mnt_init(void)
diff --git a/fs/open.c b/fs/open.c
index ca8ac4bbd3bd..54198538b67e 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -490,7 +490,7 @@ asmlinkage long sys_chdir(const char __user * filename)
490 if (error) 490 if (error)
491 goto dput_and_out; 491 goto dput_and_out;
492 492
493 set_fs_pwd(current->fs, nd.path.mnt, nd.path.dentry); 493 set_fs_pwd(current->fs, &nd.path);
494 494
495dput_and_out: 495dput_and_out:
496 path_put(&nd.path); 496 path_put(&nd.path);
@@ -501,9 +501,7 @@ out:
501asmlinkage long sys_fchdir(unsigned int fd) 501asmlinkage long sys_fchdir(unsigned int fd)
502{ 502{
503 struct file *file; 503 struct file *file;
504 struct dentry *dentry;
505 struct inode *inode; 504 struct inode *inode;
506 struct vfsmount *mnt;
507 int error; 505 int error;
508 506
509 error = -EBADF; 507 error = -EBADF;
@@ -511,9 +509,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
511 if (!file) 509 if (!file)
512 goto out; 510 goto out;
513 511
514 dentry = file->f_path.dentry; 512 inode = file->f_path.dentry->d_inode;
515 mnt = file->f_path.mnt;
516 inode = dentry->d_inode;
517 513
518 error = -ENOTDIR; 514 error = -ENOTDIR;
519 if (!S_ISDIR(inode->i_mode)) 515 if (!S_ISDIR(inode->i_mode))
@@ -521,7 +517,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
521 517
522 error = file_permission(file, MAY_EXEC); 518 error = file_permission(file, MAY_EXEC);
523 if (!error) 519 if (!error)
524 set_fs_pwd(current->fs, mnt, dentry); 520 set_fs_pwd(current->fs, &file->f_path);
525out_putf: 521out_putf:
526 fput(file); 522 fput(file);
527out: 523out:
@@ -545,7 +541,7 @@ asmlinkage long sys_chroot(const char __user * filename)
545 if (!capable(CAP_SYS_CHROOT)) 541 if (!capable(CAP_SYS_CHROOT))
546 goto dput_and_out; 542 goto dput_and_out;
547 543
548 set_fs_root(current->fs, nd.path.mnt, nd.path.dentry); 544 set_fs_root(current->fs, &nd.path);
549 set_fs_altroot(); 545 set_fs_altroot();
550 error = 0; 546 error = 0;
551dput_and_out: 547dput_and_out:
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index e3e7254412da..282f54219129 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -20,8 +20,8 @@ extern struct kmem_cache *fs_cachep;
20 20
21extern void exit_fs(struct task_struct *); 21extern void exit_fs(struct task_struct *);
22extern void set_fs_altroot(void); 22extern void set_fs_altroot(void);
23extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *); 23extern void set_fs_root(struct fs_struct *, struct path *);
24extern void set_fs_pwd(struct fs_struct *, struct vfsmount *, struct dentry *); 24extern void set_fs_pwd(struct fs_struct *, struct path *);
25extern struct fs_struct *copy_fs_struct(struct fs_struct *); 25extern struct fs_struct *copy_fs_struct(struct fs_struct *);
26extern void put_fs_struct(struct fs_struct *); 26extern void put_fs_struct(struct fs_struct *);
27 27