aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 2019899f2ab8..8bc15b362d23 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -16,6 +16,7 @@
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/quotaops.h> 17#include <linux/quotaops.h>
18#include <linux/acct.h> 18#include <linux/acct.h>
19#include <linux/capability.h>
19#include <linux/module.h> 20#include <linux/module.h>
20#include <linux/seq_file.h> 21#include <linux/seq_file.h>
21#include <linux/namespace.h> 22#include <linux/namespace.h>
@@ -355,14 +356,14 @@ static int show_vfsmnt(struct seq_file *m, void *v)
355 { MS_SYNCHRONOUS, ",sync" }, 356 { MS_SYNCHRONOUS, ",sync" },
356 { MS_DIRSYNC, ",dirsync" }, 357 { MS_DIRSYNC, ",dirsync" },
357 { MS_MANDLOCK, ",mand" }, 358 { MS_MANDLOCK, ",mand" },
358 { MS_NOATIME, ",noatime" },
359 { MS_NODIRATIME, ",nodiratime" },
360 { 0, NULL } 359 { 0, NULL }
361 }; 360 };
362 static struct proc_fs_info mnt_info[] = { 361 static struct proc_fs_info mnt_info[] = {
363 { MNT_NOSUID, ",nosuid" }, 362 { MNT_NOSUID, ",nosuid" },
364 { MNT_NODEV, ",nodev" }, 363 { MNT_NODEV, ",nodev" },
365 { MNT_NOEXEC, ",noexec" }, 364 { MNT_NOEXEC, ",noexec" },
365 { MNT_NOATIME, ",noatime" },
366 { MNT_NODIRATIME, ",nodiratime" },
366 { 0, NULL } 367 { 0, NULL }
367 }; 368 };
368 struct proc_fs_info *fs_infop; 369 struct proc_fs_info *fs_infop;
@@ -451,7 +452,7 @@ EXPORT_SYMBOL(may_umount);
451void release_mounts(struct list_head *head) 452void release_mounts(struct list_head *head)
452{ 453{
453 struct vfsmount *mnt; 454 struct vfsmount *mnt;
454 while(!list_empty(head)) { 455 while (!list_empty(head)) {
455 mnt = list_entry(head->next, struct vfsmount, mnt_hash); 456 mnt = list_entry(head->next, struct vfsmount, mnt_hash);
456 list_del_init(&mnt->mnt_hash); 457 list_del_init(&mnt->mnt_hash);
457 if (mnt->mnt_parent != mnt) { 458 if (mnt->mnt_parent != mnt) {
@@ -814,7 +815,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
814 return -ENOTDIR; 815 return -ENOTDIR;
815 816
816 err = -ENOENT; 817 err = -ENOENT;
817 down(&nd->dentry->d_inode->i_sem); 818 mutex_lock(&nd->dentry->d_inode->i_mutex);
818 if (IS_DEADDIR(nd->dentry->d_inode)) 819 if (IS_DEADDIR(nd->dentry->d_inode))
819 goto out_unlock; 820 goto out_unlock;
820 821
@@ -826,7 +827,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
826 if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry)) 827 if (IS_ROOT(nd->dentry) || !d_unhashed(nd->dentry))
827 err = attach_recursive_mnt(mnt, nd, NULL); 828 err = attach_recursive_mnt(mnt, nd, NULL);
828out_unlock: 829out_unlock:
829 up(&nd->dentry->d_inode->i_sem); 830 mutex_unlock(&nd->dentry->d_inode->i_mutex);
830 if (!err) 831 if (!err)
831 security_sb_post_addmount(mnt, nd); 832 security_sb_post_addmount(mnt, nd);
832 return err; 833 return err;
@@ -962,7 +963,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
962 goto out; 963 goto out;
963 964
964 err = -ENOENT; 965 err = -ENOENT;
965 down(&nd->dentry->d_inode->i_sem); 966 mutex_lock(&nd->dentry->d_inode->i_mutex);
966 if (IS_DEADDIR(nd->dentry->d_inode)) 967 if (IS_DEADDIR(nd->dentry->d_inode))
967 goto out1; 968 goto out1;
968 969
@@ -1004,7 +1005,7 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
1004 list_del_init(&old_nd.mnt->mnt_expire); 1005 list_del_init(&old_nd.mnt->mnt_expire);
1005 spin_unlock(&vfsmount_lock); 1006 spin_unlock(&vfsmount_lock);
1006out1: 1007out1:
1007 up(&nd->dentry->d_inode->i_sem); 1008 mutex_unlock(&nd->dentry->d_inode->i_mutex);
1008out: 1009out:
1009 up_write(&namespace_sem); 1010 up_write(&namespace_sem);
1010 if (!err) 1011 if (!err)
@@ -1286,7 +1287,13 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1286 mnt_flags |= MNT_NODEV; 1287 mnt_flags |= MNT_NODEV;
1287 if (flags & MS_NOEXEC) 1288 if (flags & MS_NOEXEC)
1288 mnt_flags |= MNT_NOEXEC; 1289 mnt_flags |= MNT_NOEXEC;
1289 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE); 1290 if (flags & MS_NOATIME)
1291 mnt_flags |= MNT_NOATIME;
1292 if (flags & MS_NODIRATIME)
1293 mnt_flags |= MNT_NODIRATIME;
1294
1295 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
1296 MS_NOATIME | MS_NODIRATIME);
1290 1297
1291 /* ... and get the mountpoint */ 1298 /* ... and get the mountpoint */
1292 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); 1299 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
@@ -1526,6 +1533,10 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
1526 * pointed to by put_old must yield the same directory as new_root. No other 1533 * pointed to by put_old must yield the same directory as new_root. No other
1527 * file system may be mounted on put_old. After all, new_root is a mountpoint. 1534 * file system may be mounted on put_old. After all, new_root is a mountpoint.
1528 * 1535 *
1536 * Also, the current root cannot be on the 'rootfs' (initial ramfs) filesystem.
1537 * See Documentation/filesystems/ramfs-rootfs-initramfs.txt for alternatives
1538 * in this situation.
1539 *
1529 * Notes: 1540 * Notes:
1530 * - we don't move root/cwd if they are not at the root (reason: if something 1541 * - we don't move root/cwd if they are not at the root (reason: if something
1531 * cared enough to change them, it's probably wrong to force them elsewhere) 1542 * cared enough to change them, it's probably wrong to force them elsewhere)
@@ -1569,7 +1580,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1569 user_nd.dentry = dget(current->fs->root); 1580 user_nd.dentry = dget(current->fs->root);
1570 read_unlock(&current->fs->lock); 1581 read_unlock(&current->fs->lock);
1571 down_write(&namespace_sem); 1582 down_write(&namespace_sem);
1572 down(&old_nd.dentry->d_inode->i_sem); 1583 mutex_lock(&old_nd.dentry->d_inode->i_mutex);
1573 error = -EINVAL; 1584 error = -EINVAL;
1574 if (IS_MNT_SHARED(old_nd.mnt) || 1585 if (IS_MNT_SHARED(old_nd.mnt) ||
1575 IS_MNT_SHARED(new_nd.mnt->mnt_parent) || 1586 IS_MNT_SHARED(new_nd.mnt->mnt_parent) ||
@@ -1622,7 +1633,7 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
1622 path_release(&root_parent); 1633 path_release(&root_parent);
1623 path_release(&parent_nd); 1634 path_release(&parent_nd);
1624out2: 1635out2:
1625 up(&old_nd.dentry->d_inode->i_sem); 1636 mutex_unlock(&old_nd.dentry->d_inode->i_mutex);
1626 up_write(&namespace_sem); 1637 up_write(&namespace_sem);
1627 path_release(&user_nd); 1638 path_release(&user_nd);
1628 path_release(&old_nd); 1639 path_release(&old_nd);