aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c72
1 files changed, 46 insertions, 26 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index c768f733c8d6..88058de59c7c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -573,7 +573,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
573 mnt->mnt_master = old; 573 mnt->mnt_master = old;
574 CLEAR_MNT_SHARED(mnt); 574 CLEAR_MNT_SHARED(mnt);
575 } else if (!(flag & CL_PRIVATE)) { 575 } else if (!(flag & CL_PRIVATE)) {
576 if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) 576 if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
577 list_add(&mnt->mnt_share, &old->mnt_share); 577 list_add(&mnt->mnt_share, &old->mnt_share);
578 if (IS_MNT_SLAVE(old)) 578 if (IS_MNT_SLAVE(old))
579 list_add(&mnt->mnt_slave, &old->mnt_slave); 579 list_add(&mnt->mnt_slave, &old->mnt_slave);
@@ -628,7 +628,6 @@ repeat:
628 mnt->mnt_pinned = 0; 628 mnt->mnt_pinned = 0;
629 spin_unlock(&vfsmount_lock); 629 spin_unlock(&vfsmount_lock);
630 acct_auto_close_mnt(mnt); 630 acct_auto_close_mnt(mnt);
631 security_sb_umount_close(mnt);
632 goto repeat; 631 goto repeat;
633 } 632 }
634} 633}
@@ -737,6 +736,21 @@ static void m_stop(struct seq_file *m, void *v)
737 up_read(&namespace_sem); 736 up_read(&namespace_sem);
738} 737}
739 738
739int mnt_had_events(struct proc_mounts *p)
740{
741 struct mnt_namespace *ns = p->ns;
742 int res = 0;
743
744 spin_lock(&vfsmount_lock);
745 if (p->event != ns->event) {
746 p->event = ns->event;
747 res = 1;
748 }
749 spin_unlock(&vfsmount_lock);
750
751 return res;
752}
753
740struct proc_fs_info { 754struct proc_fs_info {
741 int flag; 755 int flag;
742 const char *str; 756 const char *str;
@@ -1102,8 +1116,6 @@ static int do_umount(struct vfsmount *mnt, int flags)
1102 retval = 0; 1116 retval = 0;
1103 } 1117 }
1104 spin_unlock(&vfsmount_lock); 1118 spin_unlock(&vfsmount_lock);
1105 if (retval)
1106 security_sb_umount_busy(mnt);
1107 up_write(&namespace_sem); 1119 up_write(&namespace_sem);
1108 release_mounts(&umount_list); 1120 release_mounts(&umount_list);
1109 return retval; 1121 return retval;
@@ -1121,8 +1133,15 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags)
1121{ 1133{
1122 struct path path; 1134 struct path path;
1123 int retval; 1135 int retval;
1136 int lookup_flags = 0;
1137
1138 if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW))
1139 return -EINVAL;
1140
1141 if (!(flags & UMOUNT_NOFOLLOW))
1142 lookup_flags |= LOOKUP_FOLLOW;
1124 1143
1125 retval = user_path(name, &path); 1144 retval = user_path_at(AT_FDCWD, name, lookup_flags, &path);
1126 if (retval) 1145 if (retval)
1127 goto out; 1146 goto out;
1128 retval = -EINVAL; 1147 retval = -EINVAL;
@@ -1246,6 +1265,21 @@ void drop_collected_mounts(struct vfsmount *mnt)
1246 release_mounts(&umount_list); 1265 release_mounts(&umount_list);
1247} 1266}
1248 1267
1268int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
1269 struct vfsmount *root)
1270{
1271 struct vfsmount *mnt;
1272 int res = f(root, arg);
1273 if (res)
1274 return res;
1275 list_for_each_entry(mnt, &root->mnt_list, mnt_list) {
1276 res = f(mnt, arg);
1277 if (res)
1278 return res;
1279 }
1280 return 0;
1281}
1282
1249static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end) 1283static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end)
1250{ 1284{
1251 struct vfsmount *p; 1285 struct vfsmount *p;
@@ -1395,20 +1429,13 @@ static int graft_tree(struct vfsmount *mnt, struct path *path)
1395 1429
1396 err = -ENOENT; 1430 err = -ENOENT;
1397 mutex_lock(&path->dentry->d_inode->i_mutex); 1431 mutex_lock(&path->dentry->d_inode->i_mutex);
1398 if (IS_DEADDIR(path->dentry->d_inode)) 1432 if (cant_mount(path->dentry))
1399 goto out_unlock; 1433 goto out_unlock;
1400 1434
1401 err = security_sb_check_sb(mnt, path);
1402 if (err)
1403 goto out_unlock;
1404
1405 err = -ENOENT;
1406 if (!d_unlinked(path->dentry)) 1435 if (!d_unlinked(path->dentry))
1407 err = attach_recursive_mnt(mnt, path, NULL); 1436 err = attach_recursive_mnt(mnt, path, NULL);
1408out_unlock: 1437out_unlock:
1409 mutex_unlock(&path->dentry->d_inode->i_mutex); 1438 mutex_unlock(&path->dentry->d_inode->i_mutex);
1410 if (!err)
1411 security_sb_post_addmount(mnt, path);
1412 return err; 1439 return err;
1413} 1440}
1414 1441
@@ -1538,14 +1565,12 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
1538 err = do_remount_sb(sb, flags, data, 0); 1565 err = do_remount_sb(sb, flags, data, 0);
1539 if (!err) { 1566 if (!err) {
1540 spin_lock(&vfsmount_lock); 1567 spin_lock(&vfsmount_lock);
1541 mnt_flags |= path->mnt->mnt_flags & MNT_PNODE_MASK; 1568 mnt_flags |= path->mnt->mnt_flags & MNT_PROPAGATION_MASK;
1542 path->mnt->mnt_flags = mnt_flags; 1569 path->mnt->mnt_flags = mnt_flags;
1543 spin_unlock(&vfsmount_lock); 1570 spin_unlock(&vfsmount_lock);
1544 } 1571 }
1545 up_write(&sb->s_umount); 1572 up_write(&sb->s_umount);
1546 if (!err) { 1573 if (!err) {
1547 security_sb_post_remount(path->mnt, flags, data);
1548
1549 spin_lock(&vfsmount_lock); 1574 spin_lock(&vfsmount_lock);
1550 touch_mnt_namespace(path->mnt->mnt_ns); 1575 touch_mnt_namespace(path->mnt->mnt_ns);
1551 spin_unlock(&vfsmount_lock); 1576 spin_unlock(&vfsmount_lock);
@@ -1586,7 +1611,7 @@ static int do_move_mount(struct path *path, char *old_name)
1586 1611
1587 err = -ENOENT; 1612 err = -ENOENT;
1588 mutex_lock(&path->dentry->d_inode->i_mutex); 1613 mutex_lock(&path->dentry->d_inode->i_mutex);
1589 if (IS_DEADDIR(path->dentry->d_inode)) 1614 if (cant_mount(path->dentry))
1590 goto out1; 1615 goto out1;
1591 1616
1592 if (d_unlinked(path->dentry)) 1617 if (d_unlinked(path->dentry))
@@ -1671,7 +1696,7 @@ int do_add_mount(struct vfsmount *newmnt, struct path *path,
1671{ 1696{
1672 int err; 1697 int err;
1673 1698
1674 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD); 1699 mnt_flags &= ~(MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL);
1675 1700
1676 down_write(&namespace_sem); 1701 down_write(&namespace_sem);
1677 /* Something was mounted here while we slept */ 1702 /* Something was mounted here while we slept */
@@ -2197,7 +2222,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2197 if (!check_mnt(root.mnt)) 2222 if (!check_mnt(root.mnt))
2198 goto out2; 2223 goto out2;
2199 error = -ENOENT; 2224 error = -ENOENT;
2200 if (IS_DEADDIR(new.dentry->d_inode)) 2225 if (cant_mount(old.dentry))
2201 goto out2; 2226 goto out2;
2202 if (d_unlinked(new.dentry)) 2227 if (d_unlinked(new.dentry))
2203 goto out2; 2228 goto out2;
@@ -2240,7 +2265,6 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
2240 touch_mnt_namespace(current->nsproxy->mnt_ns); 2265 touch_mnt_namespace(current->nsproxy->mnt_ns);
2241 spin_unlock(&vfsmount_lock); 2266 spin_unlock(&vfsmount_lock);
2242 chroot_fs_refs(&root, &new); 2267 chroot_fs_refs(&root, &new);
2243 security_sb_post_pivotroot(&root, &new);
2244 error = 0; 2268 error = 0;
2245 path_put(&root_parent); 2269 path_put(&root_parent);
2246 path_put(&parent_path); 2270 path_put(&parent_path);
@@ -2314,17 +2338,13 @@ void __init mnt_init(void)
2314 2338
2315void put_mnt_ns(struct mnt_namespace *ns) 2339void put_mnt_ns(struct mnt_namespace *ns)
2316{ 2340{
2317 struct vfsmount *root;
2318 LIST_HEAD(umount_list); 2341 LIST_HEAD(umount_list);
2319 2342
2320 if (!atomic_dec_and_lock(&ns->count, &vfsmount_lock)) 2343 if (!atomic_dec_and_test(&ns->count))
2321 return; 2344 return;
2322 root = ns->root;
2323 ns->root = NULL;
2324 spin_unlock(&vfsmount_lock);
2325 down_write(&namespace_sem); 2345 down_write(&namespace_sem);
2326 spin_lock(&vfsmount_lock); 2346 spin_lock(&vfsmount_lock);
2327 umount_tree(root, 0, &umount_list); 2347 umount_tree(ns->root, 0, &umount_list);
2328 spin_unlock(&vfsmount_lock); 2348 spin_unlock(&vfsmount_lock);
2329 up_write(&namespace_sem); 2349 up_write(&namespace_sem);
2330 release_mounts(&umount_list); 2350 release_mounts(&umount_list);