aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-22 21:27:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-22 21:28:34 -0400
commit94bc891b00e40cbec375feb4568780af183fd7f4 (patch)
treefd48d354c61d2e736aa593c324a6d794afd8a4e7
parent934b7024f0ed29003c95cef447d92737ab86dc4f (diff)
parent1ec7f1ddbe5ba49f7b10c3b129d6d5c90c43526c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: [PATCH] get rid of __exit_files(), __exit_fs() and __put_fs_struct() [PATCH] proc_readfd_common() race fix [PATCH] double-free of inode on alloc_file() failure exit in create_write_pipe() [PATCH] teach seq_file to discard entries [PATCH] umount_tree() will unhash everything itself [PATCH] get rid of more nameidata passing in namespace.c [PATCH] switch a bunch of LSM hooks from nameidata to path [PATCH] lock exclusively in collect_mounts() and drop_collected_mounts() [PATCH] move a bunch of declarations to fs/internal.h
-rw-r--r--fs/internal.h11
-rw-r--r--fs/namespace.c66
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/pnode.c4
-rw-r--r--fs/pnode.h1
-rw-r--r--fs/proc/base.c4
-rw-r--r--fs/seq_file.c16
-rw-r--r--fs/super.c1
-rw-r--r--include/linux/dcache.h1
-rw-r--r--include/linux/fs.h6
-rw-r--r--include/linux/mount.h2
-rw-r--r--include/linux/security.h52
-rw-r--r--include/linux/seq_file.h2
-rw-r--r--kernel/exit.c27
-rw-r--r--security/dummy.c10
-rw-r--r--security/security.c20
-rw-r--r--security/selinux/hooks.c8
-rw-r--r--security/smack/smack_lsm.c4
18 files changed, 118 insertions, 120 deletions
diff --git a/fs/internal.h b/fs/internal.h
index 392e8ccd6fc4..80aa9a023372 100644
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -43,3 +43,14 @@ extern void __init chrdev_init(void);
43 * namespace.c 43 * namespace.c
44 */ 44 */
45extern int copy_mount_options(const void __user *, unsigned long *); 45extern int copy_mount_options(const void __user *, unsigned long *);
46
47extern void free_vfsmnt(struct vfsmount *);
48extern struct vfsmount *alloc_vfsmnt(const char *);
49extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
50extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
51 struct vfsmount *);
52extern void release_mounts(struct list_head *);
53extern void umount_tree(struct vfsmount *, int, struct list_head *);
54extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
55
56extern void __init mnt_init(void);
diff --git a/fs/namespace.c b/fs/namespace.c
index 678f7ce060f2..1bf302d0478b 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1091,20 +1091,20 @@ Enomem:
1091struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry) 1091struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
1092{ 1092{
1093 struct vfsmount *tree; 1093 struct vfsmount *tree;
1094 down_read(&namespace_sem); 1094 down_write(&namespace_sem);
1095 tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE); 1095 tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
1096 up_read(&namespace_sem); 1096 up_write(&namespace_sem);
1097 return tree; 1097 return tree;
1098} 1098}
1099 1099
1100void drop_collected_mounts(struct vfsmount *mnt) 1100void drop_collected_mounts(struct vfsmount *mnt)
1101{ 1101{
1102 LIST_HEAD(umount_list); 1102 LIST_HEAD(umount_list);
1103 down_read(&namespace_sem); 1103 down_write(&namespace_sem);
1104 spin_lock(&vfsmount_lock); 1104 spin_lock(&vfsmount_lock);
1105 umount_tree(mnt, 0, &umount_list); 1105 umount_tree(mnt, 0, &umount_list);
1106 spin_unlock(&vfsmount_lock); 1106 spin_unlock(&vfsmount_lock);
1107 up_read(&namespace_sem); 1107 up_write(&namespace_sem);
1108 release_mounts(&umount_list); 1108 release_mounts(&umount_list);
1109} 1109}
1110 1110
@@ -1205,32 +1205,32 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
1205 return 0; 1205 return 0;
1206} 1206}
1207 1207
1208static int graft_tree(struct vfsmount *mnt, struct nameidata *nd) 1208static int graft_tree(struct vfsmount *mnt, struct path *path)
1209{ 1209{
1210 int err; 1210 int err;
1211 if (mnt->mnt_sb->s_flags & MS_NOUSER) 1211 if (mnt->mnt_sb->s_flags & MS_NOUSER)
1212 return -EINVAL; 1212 return -EINVAL;
1213 1213
1214 if (S_ISDIR(nd->path.dentry->d_inode->i_mode) != 1214 if (S_ISDIR(path->dentry->d_inode->i_mode) !=
1215 S_ISDIR(mnt->mnt_root->d_inode->i_mode)) 1215 S_ISDIR(mnt->mnt_root->d_inode->i_mode))
1216 return -ENOTDIR; 1216 return -ENOTDIR;
1217 1217
1218 err = -ENOENT; 1218 err = -ENOENT;
1219 mutex_lock(&nd->path.dentry->d_inode->i_mutex); 1219 mutex_lock(&path->dentry->d_inode->i_mutex);
1220 if (IS_DEADDIR(nd->path.dentry->d_inode)) 1220 if (IS_DEADDIR(path->dentry->d_inode))
1221 goto out_unlock; 1221 goto out_unlock;
1222 1222
1223 err = security_sb_check_sb(mnt, nd); 1223 err = security_sb_check_sb(mnt, path);
1224 if (err) 1224 if (err)
1225 goto out_unlock; 1225 goto out_unlock;
1226 1226
1227 err = -ENOENT; 1227 err = -ENOENT;
1228 if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry)) 1228 if (IS_ROOT(path->dentry) || !d_unhashed(path->dentry))
1229 err = attach_recursive_mnt(mnt, &nd->path, NULL); 1229 err = attach_recursive_mnt(mnt, path, NULL);
1230out_unlock: 1230out_unlock:
1231 mutex_unlock(&nd->path.dentry->d_inode->i_mutex); 1231 mutex_unlock(&path->dentry->d_inode->i_mutex);
1232 if (!err) 1232 if (!err)
1233 security_sb_post_addmount(mnt, nd); 1233 security_sb_post_addmount(mnt, path);
1234 return err; 1234 return err;
1235} 1235}
1236 1236
@@ -1294,7 +1294,7 @@ static noinline int do_loopback(struct nameidata *nd, char *old_name,
1294 if (!mnt) 1294 if (!mnt)
1295 goto out; 1295 goto out;
1296 1296
1297 err = graft_tree(mnt, nd); 1297 err = graft_tree(mnt, &nd->path);
1298 if (err) { 1298 if (err) {
1299 LIST_HEAD(umount_list); 1299 LIST_HEAD(umount_list);
1300 spin_lock(&vfsmount_lock); 1300 spin_lock(&vfsmount_lock);
@@ -1501,7 +1501,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
1501 goto unlock; 1501 goto unlock;
1502 1502
1503 newmnt->mnt_flags = mnt_flags; 1503 newmnt->mnt_flags = mnt_flags;
1504 if ((err = graft_tree(newmnt, nd))) 1504 if ((err = graft_tree(newmnt, &nd->path)))
1505 goto unlock; 1505 goto unlock;
1506 1506
1507 if (fslist) /* add to the specified expiration list */ 1507 if (fslist) /* add to the specified expiration list */
@@ -1746,7 +1746,8 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1746 if (retval) 1746 if (retval)
1747 return retval; 1747 return retval;
1748 1748
1749 retval = security_sb_mount(dev_name, &nd, type_page, flags, data_page); 1749 retval = security_sb_mount(dev_name, &nd.path,
1750 type_page, flags, data_page);
1750 if (retval) 1751 if (retval)
1751 goto dput_out; 1752 goto dput_out;
1752 1753
@@ -1986,15 +1987,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1986 const char __user * put_old) 1987 const char __user * put_old)
1987{ 1988{
1988 struct vfsmount *tmp; 1989 struct vfsmount *tmp;
1989 struct nameidata new_nd, old_nd, user_nd; 1990 struct nameidata new_nd, old_nd;
1990 struct path parent_path, root_parent; 1991 struct path parent_path, root_parent, root;
1991 int error; 1992 int error;
1992 1993
1993 if (!capable(CAP_SYS_ADMIN)) 1994 if (!capable(CAP_SYS_ADMIN))
1994 return -EPERM; 1995 return -EPERM;
1995 1996
1996 lock_kernel();
1997
1998 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, 1997 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY,
1999 &new_nd); 1998 &new_nd);
2000 if (error) 1999 if (error)
@@ -2007,14 +2006,14 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2007 if (error) 2006 if (error)
2008 goto out1; 2007 goto out1;
2009 2008
2010 error = security_sb_pivotroot(&old_nd, &new_nd); 2009 error = security_sb_pivotroot(&old_nd.path, &new_nd.path);
2011 if (error) { 2010 if (error) {
2012 path_put(&old_nd.path); 2011 path_put(&old_nd.path);
2013 goto out1; 2012 goto out1;
2014 } 2013 }
2015 2014
2016 read_lock(&current->fs->lock); 2015 read_lock(&current->fs->lock);
2017 user_nd.path = current->fs->root; 2016 root = current->fs->root;
2018 path_get(&current->fs->root); 2017 path_get(&current->fs->root);
2019 read_unlock(&current->fs->lock); 2018 read_unlock(&current->fs->lock);
2020 down_write(&namespace_sem); 2019 down_write(&namespace_sem);
@@ -2022,9 +2021,9 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2022 error = -EINVAL; 2021 error = -EINVAL;
2023 if (IS_MNT_SHARED(old_nd.path.mnt) || 2022 if (IS_MNT_SHARED(old_nd.path.mnt) ||
2024 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || 2023 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) ||
2025 IS_MNT_SHARED(user_nd.path.mnt->mnt_parent)) 2024 IS_MNT_SHARED(root.mnt->mnt_parent))
2026 goto out2; 2025 goto out2;
2027 if (!check_mnt(user_nd.path.mnt)) 2026 if (!check_mnt(root.mnt))
2028 goto out2; 2027 goto out2;
2029 error = -ENOENT; 2028 error = -ENOENT;
2030 if (IS_DEADDIR(new_nd.path.dentry->d_inode)) 2029 if (IS_DEADDIR(new_nd.path.dentry->d_inode))
@@ -2034,13 +2033,13 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2034 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) 2033 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry))
2035 goto out2; 2034 goto out2;
2036 error = -EBUSY; 2035 error = -EBUSY;
2037 if (new_nd.path.mnt == user_nd.path.mnt || 2036 if (new_nd.path.mnt == root.mnt ||
2038 old_nd.path.mnt == user_nd.path.mnt) 2037 old_nd.path.mnt == root.mnt)
2039 goto out2; /* loop, on the same file system */ 2038 goto out2; /* loop, on the same file system */
2040 error = -EINVAL; 2039 error = -EINVAL;
2041 if (user_nd.path.mnt->mnt_root != user_nd.path.dentry) 2040 if (root.mnt->mnt_root != root.dentry)
2042 goto out2; /* not a mountpoint */ 2041 goto out2; /* not a mountpoint */
2043 if (user_nd.path.mnt->mnt_parent == user_nd.path.mnt) 2042 if (root.mnt->mnt_parent == root.mnt)
2044 goto out2; /* not attached */ 2043 goto out2; /* not attached */
2045 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) 2044 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry)
2046 goto out2; /* not a mountpoint */ 2045 goto out2; /* not a mountpoint */
@@ -2062,27 +2061,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2062 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) 2061 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
2063 goto out3; 2062 goto out3;
2064 detach_mnt(new_nd.path.mnt, &parent_path); 2063 detach_mnt(new_nd.path.mnt, &parent_path);
2065 detach_mnt(user_nd.path.mnt, &root_parent); 2064 detach_mnt(root.mnt, &root_parent);
2066 /* mount old root on put_old */ 2065 /* mount old root on put_old */
2067 attach_mnt(user_nd.path.mnt, &old_nd.path); 2066 attach_mnt(root.mnt, &old_nd.path);
2068 /* mount new_root on / */ 2067 /* mount new_root on / */
2069 attach_mnt(new_nd.path.mnt, &root_parent); 2068 attach_mnt(new_nd.path.mnt, &root_parent);
2070 touch_mnt_namespace(current->nsproxy->mnt_ns); 2069 touch_mnt_namespace(current->nsproxy->mnt_ns);
2071 spin_unlock(&vfsmount_lock); 2070 spin_unlock(&vfsmount_lock);
2072 chroot_fs_refs(&user_nd.path, &new_nd.path); 2071 chroot_fs_refs(&root, &new_nd.path);
2073 security_sb_post_pivotroot(&user_nd, &new_nd); 2072 security_sb_post_pivotroot(&root, &new_nd.path);
2074 error = 0; 2073 error = 0;
2075 path_put(&root_parent); 2074 path_put(&root_parent);
2076 path_put(&parent_path); 2075 path_put(&parent_path);
2077out2: 2076out2:
2078 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); 2077 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
2079 up_write(&namespace_sem); 2078 up_write(&namespace_sem);
2080 path_put(&user_nd.path); 2079 path_put(&root);
2081 path_put(&old_nd.path); 2080 path_put(&old_nd.path);
2082out1: 2081out1:
2083 path_put(&new_nd.path); 2082 path_put(&new_nd.path);
2084out0: 2083out0:
2085 unlock_kernel();
2086 return error; 2084 return error;
2087out3: 2085out3:
2088 spin_unlock(&vfsmount_lock); 2086 spin_unlock(&vfsmount_lock);
diff --git a/fs/pipe.c b/fs/pipe.c
index 8be381bbcb54..f73492b6817e 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -988,7 +988,10 @@ struct file *create_write_pipe(void)
988 return f; 988 return f;
989 989
990 err_dentry: 990 err_dentry:
991 free_pipe_info(inode);
991 dput(dentry); 992 dput(dentry);
993 return ERR_PTR(err);
994
992 err_inode: 995 err_inode:
993 free_pipe_info(inode); 996 free_pipe_info(inode);
994 iput(inode); 997 iput(inode);
diff --git a/fs/pnode.c b/fs/pnode.c
index 1d8f5447f3f7..f968e35d9785 100644
--- a/fs/pnode.c
+++ b/fs/pnode.c
@@ -9,6 +9,7 @@
9#include <linux/mnt_namespace.h> 9#include <linux/mnt_namespace.h>
10#include <linux/mount.h> 10#include <linux/mount.h>
11#include <linux/fs.h> 11#include <linux/fs.h>
12#include "internal.h"
12#include "pnode.h" 13#include "pnode.h"
13 14
14/* return the next shared peer mount of @p */ 15/* return the next shared peer mount of @p */
@@ -211,8 +212,7 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry,
211out: 212out:
212 spin_lock(&vfsmount_lock); 213 spin_lock(&vfsmount_lock);
213 while (!list_empty(&tmp_list)) { 214 while (!list_empty(&tmp_list)) {
214 child = list_entry(tmp_list.next, struct vfsmount, mnt_hash); 215 child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash);
215 list_del_init(&child->mnt_hash);
216 umount_tree(child, 0, &umount_list); 216 umount_tree(child, 0, &umount_list);
217 } 217 }
218 spin_unlock(&vfsmount_lock); 218 spin_unlock(&vfsmount_lock);
diff --git a/fs/pnode.h b/fs/pnode.h
index f249be2fee7a..973c3f825e7d 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -35,4 +35,5 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *,
35 struct list_head *); 35 struct list_head *);
36int propagate_umount(struct list_head *); 36int propagate_umount(struct list_head *);
37int propagate_mount_busy(struct vfsmount *, int); 37int propagate_mount_busy(struct vfsmount *, int);
38void mnt_release_group_id(struct vfsmount *);
38#endif /* _LINUX_PNODE_H */ 39#endif /* _LINUX_PNODE_H */
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 81d7d145292a..7313c62e3e9d 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1626,7 +1626,6 @@ static int proc_readfd_common(struct file * filp, void * dirent,
1626 unsigned int fd, ino; 1626 unsigned int fd, ino;
1627 int retval; 1627 int retval;
1628 struct files_struct * files; 1628 struct files_struct * files;
1629 struct fdtable *fdt;
1630 1629
1631 retval = -ENOENT; 1630 retval = -ENOENT;
1632 if (!p) 1631 if (!p)
@@ -1649,9 +1648,8 @@ static int proc_readfd_common(struct file * filp, void * dirent,
1649 if (!files) 1648 if (!files)
1650 goto out; 1649 goto out;
1651 rcu_read_lock(); 1650 rcu_read_lock();
1652 fdt = files_fdtable(files);
1653 for (fd = filp->f_pos-2; 1651 for (fd = filp->f_pos-2;
1654 fd < fdt->max_fds; 1652 fd < files_fdtable(files)->max_fds;
1655 fd++, filp->f_pos++) { 1653 fd++, filp->f_pos++) {
1656 char name[PROC_NUMBUF]; 1654 char name[PROC_NUMBUF];
1657 int len; 1655 int len;
diff --git a/fs/seq_file.c b/fs/seq_file.c
index 9943408b315e..cdfd996ca6ef 100644
--- a/fs/seq_file.c
+++ b/fs/seq_file.c
@@ -25,6 +25,7 @@
25 * into the buffer. In case of error ->start() and ->next() return 25 * into the buffer. In case of error ->start() and ->next() return
26 * ERR_PTR(error). In the end of sequence they return %NULL. ->show() 26 * ERR_PTR(error). In the end of sequence they return %NULL. ->show()
27 * returns 0 in case of success and negative number in case of error. 27 * returns 0 in case of success and negative number in case of error.
28 * Returning SEQ_SKIP means "discard this element and move on".
28 */ 29 */
29int seq_open(struct file *file, const struct seq_operations *op) 30int seq_open(struct file *file, const struct seq_operations *op)
30{ 31{
@@ -114,8 +115,10 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
114 if (!p || IS_ERR(p)) 115 if (!p || IS_ERR(p))
115 break; 116 break;
116 err = m->op->show(m, p); 117 err = m->op->show(m, p);
117 if (err) 118 if (err < 0)
118 break; 119 break;
120 if (unlikely(err))
121 m->count = 0;
119 if (m->count < m->size) 122 if (m->count < m->size)
120 goto Fill; 123 goto Fill;
121 m->op->stop(m, p); 124 m->op->stop(m, p);
@@ -140,9 +143,10 @@ Fill:
140 break; 143 break;
141 } 144 }
142 err = m->op->show(m, p); 145 err = m->op->show(m, p);
143 if (err || m->count == m->size) { 146 if (m->count == m->size || err) {
144 m->count = offs; 147 m->count = offs;
145 break; 148 if (likely(err <= 0))
149 break;
146 } 150 }
147 pos = next; 151 pos = next;
148 } 152 }
@@ -199,8 +203,12 @@ static int traverse(struct seq_file *m, loff_t offset)
199 if (IS_ERR(p)) 203 if (IS_ERR(p))
200 break; 204 break;
201 error = m->op->show(m, p); 205 error = m->op->show(m, p);
202 if (error) 206 if (error < 0)
203 break; 207 break;
208 if (unlikely(error)) {
209 error = 0;
210 m->count = 0;
211 }
204 if (m->count == m->size) 212 if (m->count == m->size)
205 goto Eoverflow; 213 goto Eoverflow;
206 if (pos + m->count > offset) { 214 if (pos + m->count > offset) {
diff --git a/fs/super.c b/fs/super.c
index 1f8f05ede437..4798350b2bc9 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -39,6 +39,7 @@
39#include <linux/mutex.h> 39#include <linux/mutex.h>
40#include <linux/file.h> 40#include <linux/file.h>
41#include <asm/uaccess.h> 41#include <asm/uaccess.h>
42#include "internal.h"
42 43
43 44
44LIST_HEAD(super_blocks); 45LIST_HEAD(super_blocks);
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 6bd646096fa6..fabd16d03a27 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -359,7 +359,6 @@ static inline int d_mountpoint(struct dentry *dentry)
359} 359}
360 360
361extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *); 361extern struct vfsmount *lookup_mnt(struct vfsmount *, struct dentry *);
362extern struct vfsmount *__lookup_mnt(struct vfsmount *, struct dentry *, int);
363extern struct dentry *lookup_create(struct nameidata *nd, int is_dir); 362extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
364 363
365extern int sysctl_vfs_cache_pressure; 364extern int sysctl_vfs_cache_pressure;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 0c609e71c379..cc2be2cf7d41 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -305,7 +305,6 @@ struct vfsmount;
305 305
306extern void __init inode_init(void); 306extern void __init inode_init(void);
307extern void __init inode_init_early(void); 307extern void __init inode_init_early(void);
308extern void __init mnt_init(void);
309extern void __init files_init(unsigned long); 308extern void __init files_init(unsigned long);
310 309
311struct buffer_head; 310struct buffer_head;
@@ -1536,12 +1535,7 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
1536#define kern_mount(type) kern_mount_data(type, NULL) 1535#define kern_mount(type) kern_mount_data(type, NULL)
1537extern int may_umount_tree(struct vfsmount *); 1536extern int may_umount_tree(struct vfsmount *);
1538extern int may_umount(struct vfsmount *); 1537extern int may_umount(struct vfsmount *);
1539extern void umount_tree(struct vfsmount *, int, struct list_head *);
1540extern void release_mounts(struct list_head *);
1541extern long do_mount(char *, char *, char *, unsigned long, void *); 1538extern long do_mount(char *, char *, char *, unsigned long, void *);
1542extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int);
1543extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
1544 struct vfsmount *);
1545extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *); 1539extern struct vfsmount *collect_mounts(struct vfsmount *, struct dentry *);
1546extern void drop_collected_mounts(struct vfsmount *); 1540extern void drop_collected_mounts(struct vfsmount *);
1547 1541
diff --git a/include/linux/mount.h b/include/linux/mount.h
index d6600e3f7e45..87b24cea1863 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -94,8 +94,6 @@ static inline void mntput(struct vfsmount *mnt)
94 } 94 }
95} 95}
96 96
97extern void free_vfsmnt(struct vfsmount *mnt);
98extern struct vfsmount *alloc_vfsmnt(const char *name);
99extern struct vfsmount *do_kern_mount(const char *fstype, int flags, 97extern struct vfsmount *do_kern_mount(const char *fstype, int flags,
100 const char *name, void *data); 98 const char *name, void *data);
101 99
diff --git a/include/linux/security.h b/include/linux/security.h
index fea1f4aa4dd5..53a34539382a 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -230,7 +230,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
230 * loopback/bind mount (@flags & MS_BIND), @dev_name identifies the 230 * loopback/bind mount (@flags & MS_BIND), @dev_name identifies the
231 * pathname of the object being mounted. 231 * pathname of the object being mounted.
232 * @dev_name contains the name for object being mounted. 232 * @dev_name contains the name for object being mounted.
233 * @nd contains the nameidata structure for mount point object. 233 * @path contains the path for mount point object.
234 * @type contains the filesystem type. 234 * @type contains the filesystem type.
235 * @flags contains the mount flags. 235 * @flags contains the mount flags.
236 * @data contains the filesystem-specific data. 236 * @data contains the filesystem-specific data.
@@ -249,7 +249,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
249 * Check permission before the device with superblock @mnt->sb is mounted 249 * Check permission before the device with superblock @mnt->sb is mounted
250 * on the mount point named by @nd. 250 * on the mount point named by @nd.
251 * @mnt contains the vfsmount for device being mounted. 251 * @mnt contains the vfsmount for device being mounted.
252 * @nd contains the nameidata object for the mount point. 252 * @path contains the path for the mount point.
253 * Return 0 if permission is granted. 253 * Return 0 if permission is granted.
254 * @sb_umount: 254 * @sb_umount:
255 * Check permission before the @mnt file system is unmounted. 255 * Check permission before the @mnt file system is unmounted.
@@ -278,16 +278,16 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
278 * This hook is called any time a mount is successfully grafetd to 278 * This hook is called any time a mount is successfully grafetd to
279 * the tree. 279 * the tree.
280 * @mnt contains the mounted filesystem. 280 * @mnt contains the mounted filesystem.
281 * @mountpoint_nd contains the nameidata structure for the mount point. 281 * @mountpoint contains the path for the mount point.
282 * @sb_pivotroot: 282 * @sb_pivotroot:
283 * Check permission before pivoting the root filesystem. 283 * Check permission before pivoting the root filesystem.
284 * @old_nd contains the nameidata structure for the new location of the current root (put_old). 284 * @old_path contains the path for the new location of the current root (put_old).
285 * @new_nd contains the nameidata structure for the new root (new_root). 285 * @new_path contains the path for the new root (new_root).
286 * Return 0 if permission is granted. 286 * Return 0 if permission is granted.
287 * @sb_post_pivotroot: 287 * @sb_post_pivotroot:
288 * Update module state after a successful pivot. 288 * Update module state after a successful pivot.
289 * @old_nd contains the nameidata structure for the old root. 289 * @old_path contains the path for the old root.
290 * @new_nd contains the nameidata structure for the new root. 290 * @new_path contains the path for the new root.
291 * @sb_get_mnt_opts: 291 * @sb_get_mnt_opts:
292 * Get the security relevant mount options used for a superblock 292 * Get the security relevant mount options used for a superblock
293 * @sb the superblock to get security mount options from 293 * @sb the superblock to get security mount options from
@@ -1315,20 +1315,20 @@ struct security_operations {
1315 int (*sb_copy_data)(char *orig, char *copy); 1315 int (*sb_copy_data)(char *orig, char *copy);
1316 int (*sb_kern_mount) (struct super_block *sb, void *data); 1316 int (*sb_kern_mount) (struct super_block *sb, void *data);
1317 int (*sb_statfs) (struct dentry *dentry); 1317 int (*sb_statfs) (struct dentry *dentry);
1318 int (*sb_mount) (char *dev_name, struct nameidata * nd, 1318 int (*sb_mount) (char *dev_name, struct path *path,
1319 char *type, unsigned long flags, void *data); 1319 char *type, unsigned long flags, void *data);
1320 int (*sb_check_sb) (struct vfsmount * mnt, struct nameidata * nd); 1320 int (*sb_check_sb) (struct vfsmount * mnt, struct path *path);
1321 int (*sb_umount) (struct vfsmount * mnt, int flags); 1321 int (*sb_umount) (struct vfsmount * mnt, int flags);
1322 void (*sb_umount_close) (struct vfsmount * mnt); 1322 void (*sb_umount_close) (struct vfsmount * mnt);
1323 void (*sb_umount_busy) (struct vfsmount * mnt); 1323 void (*sb_umount_busy) (struct vfsmount * mnt);
1324 void (*sb_post_remount) (struct vfsmount * mnt, 1324 void (*sb_post_remount) (struct vfsmount * mnt,
1325 unsigned long flags, void *data); 1325 unsigned long flags, void *data);
1326 void (*sb_post_addmount) (struct vfsmount * mnt, 1326 void (*sb_post_addmount) (struct vfsmount * mnt,
1327 struct nameidata * mountpoint_nd); 1327 struct path *mountpoint);
1328 int (*sb_pivotroot) (struct nameidata * old_nd, 1328 int (*sb_pivotroot) (struct path *old_path,
1329 struct nameidata * new_nd); 1329 struct path *new_path);
1330 void (*sb_post_pivotroot) (struct nameidata * old_nd, 1330 void (*sb_post_pivotroot) (struct path *old_path,
1331 struct nameidata * new_nd); 1331 struct path *new_path);
1332 int (*sb_get_mnt_opts) (const struct super_block *sb, 1332 int (*sb_get_mnt_opts) (const struct super_block *sb,
1333 struct security_mnt_opts *opts); 1333 struct security_mnt_opts *opts);
1334 int (*sb_set_mnt_opts) (struct super_block *sb, 1334 int (*sb_set_mnt_opts) (struct super_block *sb,
@@ -1593,16 +1593,16 @@ void security_sb_free(struct super_block *sb);
1593int security_sb_copy_data(char *orig, char *copy); 1593int security_sb_copy_data(char *orig, char *copy);
1594int security_sb_kern_mount(struct super_block *sb, void *data); 1594int security_sb_kern_mount(struct super_block *sb, void *data);
1595int security_sb_statfs(struct dentry *dentry); 1595int security_sb_statfs(struct dentry *dentry);
1596int security_sb_mount(char *dev_name, struct nameidata *nd, 1596int security_sb_mount(char *dev_name, struct path *path,
1597 char *type, unsigned long flags, void *data); 1597 char *type, unsigned long flags, void *data);
1598int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd); 1598int security_sb_check_sb(struct vfsmount *mnt, struct path *path);
1599int security_sb_umount(struct vfsmount *mnt, int flags); 1599int security_sb_umount(struct vfsmount *mnt, int flags);
1600void security_sb_umount_close(struct vfsmount *mnt); 1600void security_sb_umount_close(struct vfsmount *mnt);
1601void security_sb_umount_busy(struct vfsmount *mnt); 1601void security_sb_umount_busy(struct vfsmount *mnt);
1602void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data); 1602void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *data);
1603void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd); 1603void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint);
1604int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1604int security_sb_pivotroot(struct path *old_path, struct path *new_path);
1605void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd); 1605void security_sb_post_pivotroot(struct path *old_path, struct path *new_path);
1606int security_sb_get_mnt_opts(const struct super_block *sb, 1606int security_sb_get_mnt_opts(const struct super_block *sb,
1607 struct security_mnt_opts *opts); 1607 struct security_mnt_opts *opts);
1608int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts); 1608int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
@@ -1872,7 +1872,7 @@ static inline int security_sb_statfs (struct dentry *dentry)
1872 return 0; 1872 return 0;
1873} 1873}
1874 1874
1875static inline int security_sb_mount (char *dev_name, struct nameidata *nd, 1875static inline int security_sb_mount (char *dev_name, struct path *path,
1876 char *type, unsigned long flags, 1876 char *type, unsigned long flags,
1877 void *data) 1877 void *data)
1878{ 1878{
@@ -1880,7 +1880,7 @@ static inline int security_sb_mount (char *dev_name, struct nameidata *nd,
1880} 1880}
1881 1881
1882static inline int security_sb_check_sb (struct vfsmount *mnt, 1882static inline int security_sb_check_sb (struct vfsmount *mnt,
1883 struct nameidata *nd) 1883 struct path *path)
1884{ 1884{
1885 return 0; 1885 return 0;
1886} 1886}
@@ -1901,17 +1901,17 @@ static inline void security_sb_post_remount (struct vfsmount *mnt,
1901{ } 1901{ }
1902 1902
1903static inline void security_sb_post_addmount (struct vfsmount *mnt, 1903static inline void security_sb_post_addmount (struct vfsmount *mnt,
1904 struct nameidata *mountpoint_nd) 1904 struct path *mountpoint)
1905{ } 1905{ }
1906 1906
1907static inline int security_sb_pivotroot (struct nameidata *old_nd, 1907static inline int security_sb_pivotroot (struct path *old_path,
1908 struct nameidata *new_nd) 1908 struct path *new_path)
1909{ 1909{
1910 return 0; 1910 return 0;
1911} 1911}
1912 1912
1913static inline void security_sb_post_pivotroot (struct nameidata *old_nd, 1913static inline void security_sb_post_pivotroot (struct path *old_path,
1914 struct nameidata *new_nd) 1914 struct path *new_path)
1915{ } 1915{ }
1916static inline int security_sb_get_mnt_opts(const struct super_block *sb, 1916static inline int security_sb_get_mnt_opts(const struct super_block *sb,
1917 struct security_mnt_opts *opts) 1917 struct security_mnt_opts *opts)
diff --git a/include/linux/seq_file.h b/include/linux/seq_file.h
index 1da1e6208a0a..d65796dc26d9 100644
--- a/include/linux/seq_file.h
+++ b/include/linux/seq_file.h
@@ -30,6 +30,8 @@ struct seq_operations {
30 int (*show) (struct seq_file *m, void *v); 30 int (*show) (struct seq_file *m, void *v);
31}; 31};
32 32
33#define SEQ_SKIP 1
34
33int seq_open(struct file *, const struct seq_operations *); 35int seq_open(struct file *, const struct seq_operations *);
34ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); 36ssize_t seq_read(struct file *, char __user *, size_t, loff_t *);
35loff_t seq_lseek(struct file *, loff_t, int); 37loff_t seq_lseek(struct file *, loff_t, int);
diff --git a/kernel/exit.c b/kernel/exit.c
index 073005b1cfb2..cece89f80ab4 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -521,7 +521,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
521} 521}
522EXPORT_SYMBOL(reset_files_struct); 522EXPORT_SYMBOL(reset_files_struct);
523 523
524static void __exit_files(struct task_struct *tsk) 524void exit_files(struct task_struct *tsk)
525{ 525{
526 struct files_struct * files = tsk->files; 526 struct files_struct * files = tsk->files;
527 527
@@ -533,12 +533,7 @@ static void __exit_files(struct task_struct *tsk)
533 } 533 }
534} 534}
535 535
536void exit_files(struct task_struct *tsk) 536void put_fs_struct(struct fs_struct *fs)
537{
538 __exit_files(tsk);
539}
540
541static void __put_fs_struct(struct fs_struct *fs)
542{ 537{
543 /* No need to hold fs->lock if we are killing it */ 538 /* No need to hold fs->lock if we are killing it */
544 if (atomic_dec_and_test(&fs->count)) { 539 if (atomic_dec_and_test(&fs->count)) {
@@ -550,12 +545,7 @@ static void __put_fs_struct(struct fs_struct *fs)
550 } 545 }
551} 546}
552 547
553void put_fs_struct(struct fs_struct *fs) 548void exit_fs(struct task_struct *tsk)
554{
555 __put_fs_struct(fs);
556}
557
558static void __exit_fs(struct task_struct *tsk)
559{ 549{
560 struct fs_struct * fs = tsk->fs; 550 struct fs_struct * fs = tsk->fs;
561 551
@@ -563,15 +553,10 @@ static void __exit_fs(struct task_struct *tsk)
563 task_lock(tsk); 553 task_lock(tsk);
564 tsk->fs = NULL; 554 tsk->fs = NULL;
565 task_unlock(tsk); 555 task_unlock(tsk);
566 __put_fs_struct(fs); 556 put_fs_struct(fs);
567 } 557 }
568} 558}
569 559
570void exit_fs(struct task_struct *tsk)
571{
572 __exit_fs(tsk);
573}
574
575EXPORT_SYMBOL_GPL(exit_fs); 560EXPORT_SYMBOL_GPL(exit_fs);
576 561
577/* 562/*
@@ -967,8 +952,8 @@ NORET_TYPE void do_exit(long code)
967 if (group_dead) 952 if (group_dead)
968 acct_process(); 953 acct_process();
969 exit_sem(tsk); 954 exit_sem(tsk);
970 __exit_files(tsk); 955 exit_files(tsk);
971 __exit_fs(tsk); 956 exit_fs(tsk);
972 check_stack_usage(); 957 check_stack_usage();
973 exit_thread(); 958 exit_thread();
974 cgroup_exit(tsk, 1); 959 cgroup_exit(tsk, 1);
diff --git a/security/dummy.c b/security/dummy.c
index 98d5f969cdc8..b0232bbf427b 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -196,13 +196,13 @@ static int dummy_sb_statfs (struct dentry *dentry)
196 return 0; 196 return 0;
197} 197}
198 198
199static int dummy_sb_mount (char *dev_name, struct nameidata *nd, char *type, 199static int dummy_sb_mount (char *dev_name, struct path *path, char *type,
200 unsigned long flags, void *data) 200 unsigned long flags, void *data)
201{ 201{
202 return 0; 202 return 0;
203} 203}
204 204
205static int dummy_sb_check_sb (struct vfsmount *mnt, struct nameidata *nd) 205static int dummy_sb_check_sb (struct vfsmount *mnt, struct path *path)
206{ 206{
207 return 0; 207 return 0;
208} 208}
@@ -229,17 +229,17 @@ static void dummy_sb_post_remount (struct vfsmount *mnt, unsigned long flags,
229} 229}
230 230
231 231
232static void dummy_sb_post_addmount (struct vfsmount *mnt, struct nameidata *nd) 232static void dummy_sb_post_addmount (struct vfsmount *mnt, struct path *path)
233{ 233{
234 return; 234 return;
235} 235}
236 236
237static int dummy_sb_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) 237static int dummy_sb_pivotroot (struct path *old_path, struct path *new_path)
238{ 238{
239 return 0; 239 return 0;
240} 240}
241 241
242static void dummy_sb_post_pivotroot (struct nameidata *old_nd, struct nameidata *new_nd) 242static void dummy_sb_post_pivotroot (struct path *old_path, struct path *new_path)
243{ 243{
244 return; 244 return;
245} 245}
diff --git a/security/security.c b/security/security.c
index 2e250c7028eb..8a285c7b9962 100644
--- a/security/security.c
+++ b/security/security.c
@@ -296,15 +296,15 @@ int security_sb_statfs(struct dentry *dentry)
296 return security_ops->sb_statfs(dentry); 296 return security_ops->sb_statfs(dentry);
297} 297}
298 298
299int security_sb_mount(char *dev_name, struct nameidata *nd, 299int security_sb_mount(char *dev_name, struct path *path,
300 char *type, unsigned long flags, void *data) 300 char *type, unsigned long flags, void *data)
301{ 301{
302 return security_ops->sb_mount(dev_name, nd, type, flags, data); 302 return security_ops->sb_mount(dev_name, path, type, flags, data);
303} 303}
304 304
305int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd) 305int security_sb_check_sb(struct vfsmount *mnt, struct path *path)
306{ 306{
307 return security_ops->sb_check_sb(mnt, nd); 307 return security_ops->sb_check_sb(mnt, path);
308} 308}
309 309
310int security_sb_umount(struct vfsmount *mnt, int flags) 310int security_sb_umount(struct vfsmount *mnt, int flags)
@@ -327,19 +327,19 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d
327 security_ops->sb_post_remount(mnt, flags, data); 327 security_ops->sb_post_remount(mnt, flags, data);
328} 328}
329 329
330void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd) 330void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint)
331{ 331{
332 security_ops->sb_post_addmount(mnt, mountpoint_nd); 332 security_ops->sb_post_addmount(mnt, mountpoint);
333} 333}
334 334
335int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) 335int security_sb_pivotroot(struct path *old_path, struct path *new_path)
336{ 336{
337 return security_ops->sb_pivotroot(old_nd, new_nd); 337 return security_ops->sb_pivotroot(old_path, new_path);
338} 338}
339 339
340void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) 340void security_sb_post_pivotroot(struct path *old_path, struct path *new_path)
341{ 341{
342 security_ops->sb_post_pivotroot(old_nd, new_nd); 342 security_ops->sb_post_pivotroot(old_path, new_path);
343} 343}
344 344
345int security_sb_get_mnt_opts(const struct super_block *sb, 345int security_sb_get_mnt_opts(const struct super_block *sb,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 33af321f647b..308e2cf17d75 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2401,22 +2401,22 @@ static int selinux_sb_statfs(struct dentry *dentry)
2401} 2401}
2402 2402
2403static int selinux_mount(char *dev_name, 2403static int selinux_mount(char *dev_name,
2404 struct nameidata *nd, 2404 struct path *path,
2405 char *type, 2405 char *type,
2406 unsigned long flags, 2406 unsigned long flags,
2407 void *data) 2407 void *data)
2408{ 2408{
2409 int rc; 2409 int rc;
2410 2410
2411 rc = secondary_ops->sb_mount(dev_name, nd, type, flags, data); 2411 rc = secondary_ops->sb_mount(dev_name, path, type, flags, data);
2412 if (rc) 2412 if (rc)
2413 return rc; 2413 return rc;
2414 2414
2415 if (flags & MS_REMOUNT) 2415 if (flags & MS_REMOUNT)
2416 return superblock_has_perm(current, nd->path.mnt->mnt_sb, 2416 return superblock_has_perm(current, path->mnt->mnt_sb,
2417 FILESYSTEM__REMOUNT, NULL); 2417 FILESYSTEM__REMOUNT, NULL);
2418 else 2418 else
2419 return dentry_has_perm(current, nd->path.mnt, nd->path.dentry, 2419 return dentry_has_perm(current, path->mnt, path->dentry,
2420 FILE__MOUNTON); 2420 FILE__MOUNTON);
2421} 2421}
2422 2422
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 93f5b0ce662a..4215971434e6 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -315,10 +315,10 @@ static int smack_sb_statfs(struct dentry *dentry)
315 * Returns 0 if current can write the floor of the filesystem 315 * Returns 0 if current can write the floor of the filesystem
316 * being mounted on, an error code otherwise. 316 * being mounted on, an error code otherwise.
317 */ 317 */
318static int smack_sb_mount(char *dev_name, struct nameidata *nd, 318static int smack_sb_mount(char *dev_name, struct path *path,
319 char *type, unsigned long flags, void *data) 319 char *type, unsigned long flags, void *data)
320{ 320{
321 struct superblock_smack *sbp = nd->path.mnt->mnt_sb->s_security; 321 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
322 322
323 return smk_curacc(sbp->smk_floor, MAY_WRITE); 323 return smk_curacc(sbp->smk_floor, MAY_WRITE);
324} 324}