diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/dcache.c | 34 | ||||
-rw-r--r-- | fs/namei.c | 53 | ||||
-rw-r--r-- | fs/namespace.c | 57 | ||||
-rw-r--r-- | fs/proc/base.c | 8 |
4 files changed, 67 insertions, 85 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 44f6cf23b70e..66aaf52199e9 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1849,8 +1849,7 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1849 | char *buf, int buflen) | 1849 | char *buf, int buflen) |
1850 | { | 1850 | { |
1851 | char *res; | 1851 | char *res; |
1852 | struct vfsmount *rootmnt; | 1852 | struct path root; |
1853 | struct dentry *root; | ||
1854 | 1853 | ||
1855 | /* | 1854 | /* |
1856 | * We have various synthetic filesystems that never get mounted. On | 1855 | * We have various synthetic filesystems that never get mounted. On |
@@ -1863,14 +1862,13 @@ char * d_path(struct dentry *dentry, struct vfsmount *vfsmnt, | |||
1863 | return dentry->d_op->d_dname(dentry, buf, buflen); | 1862 | return dentry->d_op->d_dname(dentry, buf, buflen); |
1864 | 1863 | ||
1865 | read_lock(¤t->fs->lock); | 1864 | read_lock(¤t->fs->lock); |
1866 | rootmnt = mntget(current->fs->rootmnt); | 1865 | root = current->fs->root; |
1867 | root = dget(current->fs->root); | 1866 | path_get(¤t->fs->root); |
1868 | read_unlock(¤t->fs->lock); | 1867 | read_unlock(¤t->fs->lock); |
1869 | spin_lock(&dcache_lock); | 1868 | spin_lock(&dcache_lock); |
1870 | res = __d_path(dentry, vfsmnt, root, rootmnt, buf, buflen); | 1869 | res = __d_path(dentry, vfsmnt, root.dentry, root.mnt, buf, buflen); |
1871 | spin_unlock(&dcache_lock); | 1870 | spin_unlock(&dcache_lock); |
1872 | dput(root); | 1871 | path_put(&root); |
1873 | mntput(rootmnt); | ||
1874 | return res; | 1872 | return res; |
1875 | } | 1873 | } |
1876 | 1874 | ||
@@ -1916,28 +1914,28 @@ char *dynamic_dname(struct dentry *dentry, char *buffer, int buflen, | |||
1916 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size) | 1914 | asmlinkage long sys_getcwd(char __user *buf, unsigned long size) |
1917 | { | 1915 | { |
1918 | int error; | 1916 | int error; |
1919 | struct vfsmount *pwdmnt, *rootmnt; | 1917 | struct path pwd, root; |
1920 | struct dentry *pwd, *root; | ||
1921 | char *page = (char *) __get_free_page(GFP_USER); | 1918 | char *page = (char *) __get_free_page(GFP_USER); |
1922 | 1919 | ||
1923 | if (!page) | 1920 | if (!page) |
1924 | return -ENOMEM; | 1921 | return -ENOMEM; |
1925 | 1922 | ||
1926 | read_lock(¤t->fs->lock); | 1923 | read_lock(¤t->fs->lock); |
1927 | pwdmnt = mntget(current->fs->pwdmnt); | 1924 | pwd = current->fs->pwd; |
1928 | pwd = dget(current->fs->pwd); | 1925 | path_get(¤t->fs->pwd); |
1929 | rootmnt = mntget(current->fs->rootmnt); | 1926 | root = current->fs->root; |
1930 | root = dget(current->fs->root); | 1927 | path_get(¤t->fs->root); |
1931 | read_unlock(¤t->fs->lock); | 1928 | read_unlock(¤t->fs->lock); |
1932 | 1929 | ||
1933 | error = -ENOENT; | 1930 | error = -ENOENT; |
1934 | /* Has the current directory has been unlinked? */ | 1931 | /* Has the current directory has been unlinked? */ |
1935 | spin_lock(&dcache_lock); | 1932 | spin_lock(&dcache_lock); |
1936 | if (pwd->d_parent == pwd || !d_unhashed(pwd)) { | 1933 | if (pwd.dentry->d_parent == pwd.dentry || !d_unhashed(pwd.dentry)) { |
1937 | unsigned long len; | 1934 | unsigned long len; |
1938 | char * cwd; | 1935 | char * cwd; |
1939 | 1936 | ||
1940 | cwd = __d_path(pwd, pwdmnt, root, rootmnt, page, PAGE_SIZE); | 1937 | cwd = __d_path(pwd.dentry, pwd.mnt, root.dentry, root.mnt, |
1938 | page, PAGE_SIZE); | ||
1941 | spin_unlock(&dcache_lock); | 1939 | spin_unlock(&dcache_lock); |
1942 | 1940 | ||
1943 | error = PTR_ERR(cwd); | 1941 | error = PTR_ERR(cwd); |
@@ -1955,10 +1953,8 @@ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) | |||
1955 | spin_unlock(&dcache_lock); | 1953 | spin_unlock(&dcache_lock); |
1956 | 1954 | ||
1957 | out: | 1955 | out: |
1958 | dput(pwd); | 1956 | path_put(&pwd); |
1959 | mntput(pwdmnt); | 1957 | path_put(&root); |
1960 | dput(root); | ||
1961 | mntput(rootmnt); | ||
1962 | free_page((unsigned long) page); | 1958 | free_page((unsigned long) page); |
1963 | return error; | 1959 | return error; |
1964 | } | 1960 | } |
diff --git a/fs/namei.c b/fs/namei.c index a6575ca9f9d7..941c8e8228c0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -549,16 +549,16 @@ walk_init_root(const char *name, struct nameidata *nd) | |||
549 | struct fs_struct *fs = current->fs; | 549 | struct fs_struct *fs = current->fs; |
550 | 550 | ||
551 | read_lock(&fs->lock); | 551 | read_lock(&fs->lock); |
552 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 552 | if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { |
553 | nd->path.mnt = mntget(fs->altrootmnt); | 553 | nd->path = fs->altroot; |
554 | nd->path.dentry = dget(fs->altroot); | 554 | path_get(&fs->altroot); |
555 | read_unlock(&fs->lock); | 555 | read_unlock(&fs->lock); |
556 | if (__emul_lookup_dentry(name,nd)) | 556 | if (__emul_lookup_dentry(name,nd)) |
557 | return 0; | 557 | return 0; |
558 | read_lock(&fs->lock); | 558 | read_lock(&fs->lock); |
559 | } | 559 | } |
560 | nd->path.mnt = mntget(fs->rootmnt); | 560 | nd->path = fs->root; |
561 | nd->path.dentry = dget(fs->root); | 561 | path_get(&fs->root); |
562 | read_unlock(&fs->lock); | 562 | read_unlock(&fs->lock); |
563 | return 1; | 563 | return 1; |
564 | } | 564 | } |
@@ -755,8 +755,8 @@ static __always_inline void follow_dotdot(struct nameidata *nd) | |||
755 | struct dentry *old = nd->path.dentry; | 755 | struct dentry *old = nd->path.dentry; |
756 | 756 | ||
757 | read_lock(&fs->lock); | 757 | read_lock(&fs->lock); |
758 | if (nd->path.dentry == fs->root && | 758 | if (nd->path.dentry == fs->root.dentry && |
759 | nd->path.mnt == fs->rootmnt) { | 759 | nd->path.mnt == fs->root.mnt) { |
760 | read_unlock(&fs->lock); | 760 | read_unlock(&fs->lock); |
761 | break; | 761 | break; |
762 | } | 762 | } |
@@ -1078,8 +1078,8 @@ static int __emul_lookup_dentry(const char *name, struct nameidata *nd) | |||
1078 | */ | 1078 | */ |
1079 | nd->last_type = LAST_ROOT; | 1079 | nd->last_type = LAST_ROOT; |
1080 | read_lock(&fs->lock); | 1080 | read_lock(&fs->lock); |
1081 | nd->path.mnt = mntget(fs->rootmnt); | 1081 | nd->path = fs->root; |
1082 | nd->path.dentry = dget(fs->root); | 1082 | path_get(&fs->root); |
1083 | read_unlock(&fs->lock); | 1083 | read_unlock(&fs->lock); |
1084 | if (path_walk(name, nd) == 0) { | 1084 | if (path_walk(name, nd) == 0) { |
1085 | if (nd->path.dentry->d_inode) { | 1085 | if (nd->path.dentry->d_inode) { |
@@ -1099,29 +1099,22 @@ void set_fs_altroot(void) | |||
1099 | { | 1099 | { |
1100 | char *emul = __emul_prefix(); | 1100 | char *emul = __emul_prefix(); |
1101 | struct nameidata nd; | 1101 | struct nameidata nd; |
1102 | struct vfsmount *mnt = NULL, *oldmnt; | 1102 | struct path path = {}, old_path; |
1103 | struct dentry *dentry = NULL, *olddentry; | ||
1104 | int err; | 1103 | int err; |
1105 | struct fs_struct *fs = current->fs; | 1104 | struct fs_struct *fs = current->fs; |
1106 | 1105 | ||
1107 | if (!emul) | 1106 | if (!emul) |
1108 | goto set_it; | 1107 | goto set_it; |
1109 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); | 1108 | err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd); |
1110 | if (!err) { | 1109 | if (!err) |
1111 | mnt = nd.path.mnt; | 1110 | path = nd.path; |
1112 | dentry = nd.path.dentry; | ||
1113 | } | ||
1114 | set_it: | 1111 | set_it: |
1115 | write_lock(&fs->lock); | 1112 | write_lock(&fs->lock); |
1116 | oldmnt = fs->altrootmnt; | 1113 | old_path = fs->altroot; |
1117 | olddentry = fs->altroot; | 1114 | fs->altroot = path; |
1118 | fs->altrootmnt = mnt; | ||
1119 | fs->altroot = dentry; | ||
1120 | write_unlock(&fs->lock); | 1115 | write_unlock(&fs->lock); |
1121 | if (olddentry) { | 1116 | if (old_path.dentry) |
1122 | dput(olddentry); | 1117 | path_put(&old_path); |
1123 | mntput(oldmnt); | ||
1124 | } | ||
1125 | } | 1118 | } |
1126 | 1119 | ||
1127 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ | 1120 | /* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ |
@@ -1139,21 +1132,21 @@ static int do_path_lookup(int dfd, const char *name, | |||
1139 | 1132 | ||
1140 | if (*name=='/') { | 1133 | if (*name=='/') { |
1141 | read_lock(&fs->lock); | 1134 | read_lock(&fs->lock); |
1142 | if (fs->altroot && !(nd->flags & LOOKUP_NOALT)) { | 1135 | if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) { |
1143 | nd->path.mnt = mntget(fs->altrootmnt); | 1136 | nd->path = fs->altroot; |
1144 | nd->path.dentry = dget(fs->altroot); | 1137 | path_get(&fs->altroot); |
1145 | read_unlock(&fs->lock); | 1138 | read_unlock(&fs->lock); |
1146 | if (__emul_lookup_dentry(name,nd)) | 1139 | if (__emul_lookup_dentry(name,nd)) |
1147 | goto out; /* found in altroot */ | 1140 | goto out; /* found in altroot */ |
1148 | read_lock(&fs->lock); | 1141 | read_lock(&fs->lock); |
1149 | } | 1142 | } |
1150 | nd->path.mnt = mntget(fs->rootmnt); | 1143 | nd->path = fs->root; |
1151 | nd->path.dentry = dget(fs->root); | 1144 | path_get(&fs->root); |
1152 | read_unlock(&fs->lock); | 1145 | read_unlock(&fs->lock); |
1153 | } else if (dfd == AT_FDCWD) { | 1146 | } else if (dfd == AT_FDCWD) { |
1154 | read_lock(&fs->lock); | 1147 | read_lock(&fs->lock); |
1155 | nd->path.mnt = mntget(fs->pwdmnt); | 1148 | nd->path = fs->pwd; |
1156 | nd->path.dentry = dget(fs->pwd); | 1149 | path_get(&fs->pwd); |
1157 | read_unlock(&fs->lock); | 1150 | read_unlock(&fs->lock); |
1158 | } else { | 1151 | } else { |
1159 | struct dentry *dentry; | 1152 | struct dentry *dentry; |
diff --git a/fs/namespace.c b/fs/namespace.c index c77eedd2ac66..ac19212c9bc3 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -593,7 +593,7 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
593 | * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount] | 593 | * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount] |
594 | */ | 594 | */ |
595 | if (flags & MNT_EXPIRE) { | 595 | if (flags & MNT_EXPIRE) { |
596 | if (mnt == current->fs->rootmnt || | 596 | if (mnt == current->fs->root.mnt || |
597 | flags & (MNT_FORCE | MNT_DETACH)) | 597 | flags & (MNT_FORCE | MNT_DETACH)) |
598 | return -EINVAL; | 598 | return -EINVAL; |
599 | 599 | ||
@@ -628,7 +628,7 @@ static int do_umount(struct vfsmount *mnt, int flags) | |||
628 | * /reboot - static binary that would close all descriptors and | 628 | * /reboot - static binary that would close all descriptors and |
629 | * call reboot(9). Then init(8) could umount root and exec /reboot. | 629 | * call reboot(9). Then init(8) could umount root and exec /reboot. |
630 | */ | 630 | */ |
631 | if (mnt == current->fs->rootmnt && !(flags & MNT_DETACH)) { | 631 | if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) { |
632 | /* | 632 | /* |
633 | * Special case for "unmounting" root ... | 633 | * Special case for "unmounting" root ... |
634 | * we just try to remount it readonly. | 634 | * we just try to remount it readonly. |
@@ -1559,17 +1559,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, | |||
1559 | while (p) { | 1559 | while (p) { |
1560 | q->mnt_ns = new_ns; | 1560 | q->mnt_ns = new_ns; |
1561 | if (fs) { | 1561 | if (fs) { |
1562 | if (p == fs->rootmnt) { | 1562 | if (p == fs->root.mnt) { |
1563 | rootmnt = p; | 1563 | rootmnt = p; |
1564 | fs->rootmnt = mntget(q); | 1564 | fs->root.mnt = mntget(q); |
1565 | } | 1565 | } |
1566 | if (p == fs->pwdmnt) { | 1566 | if (p == fs->pwd.mnt) { |
1567 | pwdmnt = p; | 1567 | pwdmnt = p; |
1568 | fs->pwdmnt = mntget(q); | 1568 | fs->pwd.mnt = mntget(q); |
1569 | } | 1569 | } |
1570 | if (p == fs->altrootmnt) { | 1570 | if (p == fs->altroot.mnt) { |
1571 | altrootmnt = p; | 1571 | altrootmnt = p; |
1572 | fs->altrootmnt = mntget(q); | 1572 | fs->altroot.mnt = mntget(q); |
1573 | } | 1573 | } |
1574 | } | 1574 | } |
1575 | p = next_mnt(p, mnt_ns->root); | 1575 | p = next_mnt(p, mnt_ns->root); |
@@ -1653,18 +1653,15 @@ out1: | |||
1653 | void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, | 1653 | void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, |
1654 | struct dentry *dentry) | 1654 | struct dentry *dentry) |
1655 | { | 1655 | { |
1656 | struct dentry *old_root; | 1656 | struct path old_root; |
1657 | struct vfsmount *old_rootmnt; | 1657 | |
1658 | write_lock(&fs->lock); | 1658 | write_lock(&fs->lock); |
1659 | old_root = fs->root; | 1659 | old_root = fs->root; |
1660 | old_rootmnt = fs->rootmnt; | 1660 | fs->root.mnt = mntget(mnt); |
1661 | fs->rootmnt = mntget(mnt); | 1661 | fs->root.dentry = dget(dentry); |
1662 | fs->root = dget(dentry); | ||
1663 | write_unlock(&fs->lock); | 1662 | write_unlock(&fs->lock); |
1664 | if (old_root) { | 1663 | if (old_root.dentry) |
1665 | dput(old_root); | 1664 | path_put(&old_root); |
1666 | mntput(old_rootmnt); | ||
1667 | } | ||
1668 | } | 1665 | } |
1669 | 1666 | ||
1670 | /* | 1667 | /* |
@@ -1674,20 +1671,16 @@ void set_fs_root(struct fs_struct *fs, struct vfsmount *mnt, | |||
1674 | void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, | 1671 | void set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, |
1675 | struct dentry *dentry) | 1672 | struct dentry *dentry) |
1676 | { | 1673 | { |
1677 | struct dentry *old_pwd; | 1674 | struct path old_pwd; |
1678 | struct vfsmount *old_pwdmnt; | ||
1679 | 1675 | ||
1680 | write_lock(&fs->lock); | 1676 | write_lock(&fs->lock); |
1681 | old_pwd = fs->pwd; | 1677 | old_pwd = fs->pwd; |
1682 | old_pwdmnt = fs->pwdmnt; | 1678 | fs->pwd.mnt = mntget(mnt); |
1683 | fs->pwdmnt = mntget(mnt); | 1679 | fs->pwd.dentry = dget(dentry); |
1684 | fs->pwd = dget(dentry); | ||
1685 | write_unlock(&fs->lock); | 1680 | write_unlock(&fs->lock); |
1686 | 1681 | ||
1687 | if (old_pwd) { | 1682 | if (old_pwd.dentry) |
1688 | dput(old_pwd); | 1683 | path_put(&old_pwd); |
1689 | mntput(old_pwdmnt); | ||
1690 | } | ||
1691 | } | 1684 | } |
1692 | 1685 | ||
1693 | static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) | 1686 | static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) |
@@ -1702,12 +1695,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd) | |||
1702 | if (fs) { | 1695 | if (fs) { |
1703 | atomic_inc(&fs->count); | 1696 | atomic_inc(&fs->count); |
1704 | task_unlock(p); | 1697 | task_unlock(p); |
1705 | if (fs->root == old_nd->path.dentry | 1698 | if (fs->root.dentry == old_nd->path.dentry |
1706 | && fs->rootmnt == old_nd->path.mnt) | 1699 | && fs->root.mnt == old_nd->path.mnt) |
1707 | set_fs_root(fs, new_nd->path.mnt, | 1700 | set_fs_root(fs, new_nd->path.mnt, |
1708 | new_nd->path.dentry); | 1701 | new_nd->path.dentry); |
1709 | if (fs->pwd == old_nd->path.dentry | 1702 | if (fs->pwd.dentry == old_nd->path.dentry |
1710 | && fs->pwdmnt == old_nd->path.mnt) | 1703 | && fs->pwd.mnt == old_nd->path.mnt) |
1711 | set_fs_pwd(fs, new_nd->path.mnt, | 1704 | set_fs_pwd(fs, new_nd->path.mnt, |
1712 | new_nd->path.dentry); | 1705 | new_nd->path.dentry); |
1713 | put_fs_struct(fs); | 1706 | put_fs_struct(fs); |
@@ -1773,8 +1766,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root, | |||
1773 | } | 1766 | } |
1774 | 1767 | ||
1775 | read_lock(¤t->fs->lock); | 1768 | read_lock(¤t->fs->lock); |
1776 | user_nd.path.mnt = mntget(current->fs->rootmnt); | 1769 | user_nd.path = current->fs->root; |
1777 | user_nd.path.dentry = dget(current->fs->root); | 1770 | path_get(¤t->fs->root); |
1778 | read_unlock(¤t->fs->lock); | 1771 | read_unlock(¤t->fs->lock); |
1779 | down_write(&namespace_sem); | 1772 | down_write(&namespace_sem); |
1780 | mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); | 1773 | mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index c742be48348f..080f1f6eda61 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -165,8 +165,8 @@ static int proc_cwd_link(struct inode *inode, struct dentry **dentry, struct vfs | |||
165 | } | 165 | } |
166 | if (fs) { | 166 | if (fs) { |
167 | read_lock(&fs->lock); | 167 | read_lock(&fs->lock); |
168 | *mnt = mntget(fs->pwdmnt); | 168 | *mnt = mntget(fs->pwd.mnt); |
169 | *dentry = dget(fs->pwd); | 169 | *dentry = dget(fs->pwd.dentry); |
170 | read_unlock(&fs->lock); | 170 | read_unlock(&fs->lock); |
171 | result = 0; | 171 | result = 0; |
172 | put_fs_struct(fs); | 172 | put_fs_struct(fs); |
@@ -186,8 +186,8 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
186 | } | 186 | } |
187 | if (fs) { | 187 | if (fs) { |
188 | read_lock(&fs->lock); | 188 | read_lock(&fs->lock); |
189 | *mnt = mntget(fs->rootmnt); | 189 | *mnt = mntget(fs->root.mnt); |
190 | *dentry = dget(fs->root); | 190 | *dentry = dget(fs->root.dentry); |
191 | read_unlock(&fs->lock); | 191 | read_unlock(&fs->lock); |
192 | result = 0; | 192 | result = 0; |
193 | put_fs_struct(fs); | 193 | put_fs_struct(fs); |