diff options
-rw-r--r-- | fs/namespace.c | 28 | ||||
-rw-r--r-- | fs/open.c | 12 | ||||
-rw-r--r-- | include/linux/fs_struct.h | 4 |
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 | */ |
1653 | void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, | 1653 | void 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 | */ |
1671 | void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, | 1670 | void 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 | ||
1870 | void __init mnt_init(void) | 1870 | void __init mnt_init(void) |
@@ -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 | ||
495 | dput_and_out: | 495 | dput_and_out: |
496 | path_put(&nd.path); | 496 | path_put(&nd.path); |
@@ -501,9 +501,7 @@ out: | |||
501 | asmlinkage long sys_fchdir(unsigned int fd) | 501 | asmlinkage 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); |
525 | out_putf: | 521 | out_putf: |
526 | fput(file); | 522 | fput(file); |
527 | out: | 523 | out: |
@@ -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; |
551 | dput_and_out: | 547 | dput_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 | ||
21 | extern void exit_fs(struct task_struct *); | 21 | extern void exit_fs(struct task_struct *); |
22 | extern void set_fs_altroot(void); | 22 | extern void set_fs_altroot(void); |
23 | extern void set_fs_root(struct fs_struct *, struct vfsmount *, struct dentry *); | 23 | extern void set_fs_root(struct fs_struct *, struct path *); |
24 | extern void set_fs_pwd(struct fs_struct *, struct vfsmount *, struct dentry *); | 24 | extern void set_fs_pwd(struct fs_struct *, struct path *); |
25 | extern struct fs_struct *copy_fs_struct(struct fs_struct *); | 25 | extern struct fs_struct *copy_fs_struct(struct fs_struct *); |
26 | extern void put_fs_struct(struct fs_struct *); | 26 | extern void put_fs_struct(struct fs_struct *); |
27 | 27 | ||