diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 31 |
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); | |||
451 | void release_mounts(struct list_head *head) | 452 | void 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); |
828 | out_unlock: | 829 | out_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); |
1006 | out1: | 1007 | out1: |
1007 | up(&nd->dentry->d_inode->i_sem); | 1008 | mutex_unlock(&nd->dentry->d_inode->i_mutex); |
1008 | out: | 1009 | out: |
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(¤t->fs->lock); | 1581 | read_unlock(¤t->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); |
1624 | out2: | 1635 | out2: |
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); |