aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-11 08:46:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-11 08:46:53 -0400
commit336879b1da97fffc097f77c6d6f818660f2826f0 (patch)
tree4ddb4d1c5d2b67fb096c72e41d2a03b01a605041 /fs/namespace.c
parent3d3cbd84300e7be1e53083cac0f6f9c12978ecb4 (diff)
parentfdcaa1dbb7c6ed419b10fb8cdb5001ab0a00538f (diff)
Merge remote-tracking branch 'airlied/drm-next' into topic/vblank-rework
Dave asked me to do the backmerge before sending him the revised pull request, so here we go. Nothing fancy in the conflicts, just a few things changed right next to each another. Conflicts: drivers/gpu/drm/drm_irq.c Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c132
1 files changed, 88 insertions, 44 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 182bc41cd887..a01c7730e9af 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -16,7 +16,6 @@
16#include <linux/namei.h> 16#include <linux/namei.h>
17#include <linux/security.h> 17#include <linux/security.h>
18#include <linux/idr.h> 18#include <linux/idr.h>
19#include <linux/acct.h> /* acct_auto_close_mnt */
20#include <linux/init.h> /* init_rootfs */ 19#include <linux/init.h> /* init_rootfs */
21#include <linux/fs_struct.h> /* get_fs_root et.al. */ 20#include <linux/fs_struct.h> /* get_fs_root et.al. */
22#include <linux/fsnotify.h> /* fsnotify_vfsmount_delete */ 21#include <linux/fsnotify.h> /* fsnotify_vfsmount_delete */
@@ -779,6 +778,20 @@ static void attach_mnt(struct mount *mnt,
779 list_add_tail(&mnt->mnt_child, &parent->mnt_mounts); 778 list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
780} 779}
781 780
781static void attach_shadowed(struct mount *mnt,
782 struct mount *parent,
783 struct mount *shadows)
784{
785 if (shadows) {
786 hlist_add_behind_rcu(&mnt->mnt_hash, &shadows->mnt_hash);
787 list_add(&mnt->mnt_child, &shadows->mnt_child);
788 } else {
789 hlist_add_head_rcu(&mnt->mnt_hash,
790 m_hash(&parent->mnt, mnt->mnt_mountpoint));
791 list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
792 }
793}
794
782/* 795/*
783 * vfsmount lock must be held for write 796 * vfsmount lock must be held for write
784 */ 797 */
@@ -797,12 +810,7 @@ static void commit_tree(struct mount *mnt, struct mount *shadows)
797 810
798 list_splice(&head, n->list.prev); 811 list_splice(&head, n->list.prev);
799 812
800 if (shadows) 813 attach_shadowed(mnt, parent, shadows);
801 hlist_add_after_rcu(&shadows->mnt_hash, &mnt->mnt_hash);
802 else
803 hlist_add_head_rcu(&mnt->mnt_hash,
804 m_hash(&parent->mnt, mnt->mnt_mountpoint));
805 list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
806 touch_mnt_namespace(n); 814 touch_mnt_namespace(n);
807} 815}
808 816
@@ -890,8 +898,21 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
890 898
891 mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED); 899 mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~(MNT_WRITE_HOLD|MNT_MARKED);
892 /* Don't allow unprivileged users to change mount flags */ 900 /* Don't allow unprivileged users to change mount flags */
893 if ((flag & CL_UNPRIVILEGED) && (mnt->mnt.mnt_flags & MNT_READONLY)) 901 if (flag & CL_UNPRIVILEGED) {
894 mnt->mnt.mnt_flags |= MNT_LOCK_READONLY; 902 mnt->mnt.mnt_flags |= MNT_LOCK_ATIME;
903
904 if (mnt->mnt.mnt_flags & MNT_READONLY)
905 mnt->mnt.mnt_flags |= MNT_LOCK_READONLY;
906
907 if (mnt->mnt.mnt_flags & MNT_NODEV)
908 mnt->mnt.mnt_flags |= MNT_LOCK_NODEV;
909
910 if (mnt->mnt.mnt_flags & MNT_NOSUID)
911 mnt->mnt.mnt_flags |= MNT_LOCK_NOSUID;
912
913 if (mnt->mnt.mnt_flags & MNT_NOEXEC)
914 mnt->mnt.mnt_flags |= MNT_LOCK_NOEXEC;
915 }
895 916
896 /* Don't allow unprivileged users to reveal what is under a mount */ 917 /* Don't allow unprivileged users to reveal what is under a mount */
897 if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire)) 918 if ((flag & CL_UNPRIVILEGED) && list_empty(&old->mnt_expire))
@@ -938,7 +959,6 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
938 959
939static void mntput_no_expire(struct mount *mnt) 960static void mntput_no_expire(struct mount *mnt)
940{ 961{
941put_again:
942 rcu_read_lock(); 962 rcu_read_lock();
943 mnt_add_count(mnt, -1); 963 mnt_add_count(mnt, -1);
944 if (likely(mnt->mnt_ns)) { /* shouldn't be the last one */ 964 if (likely(mnt->mnt_ns)) { /* shouldn't be the last one */
@@ -951,14 +971,6 @@ put_again:
951 unlock_mount_hash(); 971 unlock_mount_hash();
952 return; 972 return;
953 } 973 }
954 if (unlikely(mnt->mnt_pinned)) {
955 mnt_add_count(mnt, mnt->mnt_pinned + 1);
956 mnt->mnt_pinned = 0;
957 rcu_read_unlock();
958 unlock_mount_hash();
959 acct_auto_close_mnt(&mnt->mnt);
960 goto put_again;
961 }
962 if (unlikely(mnt->mnt.mnt_flags & MNT_DOOMED)) { 974 if (unlikely(mnt->mnt.mnt_flags & MNT_DOOMED)) {
963 rcu_read_unlock(); 975 rcu_read_unlock();
964 unlock_mount_hash(); 976 unlock_mount_hash();
@@ -981,6 +993,8 @@ put_again:
981 * so mnt_get_writers() below is safe. 993 * so mnt_get_writers() below is safe.
982 */ 994 */
983 WARN_ON(mnt_get_writers(mnt)); 995 WARN_ON(mnt_get_writers(mnt));
996 if (unlikely(mnt->mnt_pins.first))
997 mnt_pin_kill(mnt);
984 fsnotify_vfsmount_delete(&mnt->mnt); 998 fsnotify_vfsmount_delete(&mnt->mnt);
985 dput(mnt->mnt.mnt_root); 999 dput(mnt->mnt.mnt_root);
986 deactivate_super(mnt->mnt.mnt_sb); 1000 deactivate_super(mnt->mnt.mnt_sb);
@@ -1008,25 +1022,15 @@ struct vfsmount *mntget(struct vfsmount *mnt)
1008} 1022}
1009EXPORT_SYMBOL(mntget); 1023EXPORT_SYMBOL(mntget);
1010 1024
1011void mnt_pin(struct vfsmount *mnt) 1025struct vfsmount *mnt_clone_internal(struct path *path)
1012{
1013 lock_mount_hash();
1014 real_mount(mnt)->mnt_pinned++;
1015 unlock_mount_hash();
1016}
1017EXPORT_SYMBOL(mnt_pin);
1018
1019void mnt_unpin(struct vfsmount *m)
1020{ 1026{
1021 struct mount *mnt = real_mount(m); 1027 struct mount *p;
1022 lock_mount_hash(); 1028 p = clone_mnt(real_mount(path->mnt), path->dentry, CL_PRIVATE);
1023 if (mnt->mnt_pinned) { 1029 if (IS_ERR(p))
1024 mnt_add_count(mnt, 1); 1030 return ERR_CAST(p);
1025 mnt->mnt_pinned--; 1031 p->mnt.mnt_flags |= MNT_INTERNAL;
1026 } 1032 return &p->mnt;
1027 unlock_mount_hash();
1028} 1033}
1029EXPORT_SYMBOL(mnt_unpin);
1030 1034
1031static inline void mangle(struct seq_file *m, const char *s) 1035static inline void mangle(struct seq_file *m, const char *s)
1032{ 1036{
@@ -1492,6 +1496,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1492 continue; 1496 continue;
1493 1497
1494 for (s = r; s; s = next_mnt(s, r)) { 1498 for (s = r; s; s = next_mnt(s, r)) {
1499 struct mount *t = NULL;
1495 if (!(flag & CL_COPY_UNBINDABLE) && 1500 if (!(flag & CL_COPY_UNBINDABLE) &&
1496 IS_MNT_UNBINDABLE(s)) { 1501 IS_MNT_UNBINDABLE(s)) {
1497 s = skip_mnt_tree(s); 1502 s = skip_mnt_tree(s);
@@ -1513,7 +1518,14 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1513 goto out; 1518 goto out;
1514 lock_mount_hash(); 1519 lock_mount_hash();
1515 list_add_tail(&q->mnt_list, &res->mnt_list); 1520 list_add_tail(&q->mnt_list, &res->mnt_list);
1516 attach_mnt(q, parent, p->mnt_mp); 1521 mnt_set_mountpoint(parent, p->mnt_mp, q);
1522 if (!list_empty(&parent->mnt_mounts)) {
1523 t = list_last_entry(&parent->mnt_mounts,
1524 struct mount, mnt_child);
1525 if (t->mnt_mp != p->mnt_mp)
1526 t = NULL;
1527 }
1528 attach_shadowed(q, parent, t);
1517 unlock_mount_hash(); 1529 unlock_mount_hash();
1518 } 1530 }
1519 } 1531 }
@@ -1896,9 +1908,6 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags)
1896 if (readonly_request == __mnt_is_readonly(mnt)) 1908 if (readonly_request == __mnt_is_readonly(mnt))
1897 return 0; 1909 return 0;
1898 1910
1899 if (mnt->mnt_flags & MNT_LOCK_READONLY)
1900 return -EPERM;
1901
1902 if (readonly_request) 1911 if (readonly_request)
1903 error = mnt_make_readonly(real_mount(mnt)); 1912 error = mnt_make_readonly(real_mount(mnt));
1904 else 1913 else
@@ -1924,6 +1933,33 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
1924 if (path->dentry != path->mnt->mnt_root) 1933 if (path->dentry != path->mnt->mnt_root)
1925 return -EINVAL; 1934 return -EINVAL;
1926 1935
1936 /* Don't allow changing of locked mnt flags.
1937 *
1938 * No locks need to be held here while testing the various
1939 * MNT_LOCK flags because those flags can never be cleared
1940 * once they are set.
1941 */
1942 if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
1943 !(mnt_flags & MNT_READONLY)) {
1944 return -EPERM;
1945 }
1946 if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
1947 !(mnt_flags & MNT_NODEV)) {
1948 return -EPERM;
1949 }
1950 if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) &&
1951 !(mnt_flags & MNT_NOSUID)) {
1952 return -EPERM;
1953 }
1954 if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) &&
1955 !(mnt_flags & MNT_NOEXEC)) {
1956 return -EPERM;
1957 }
1958 if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
1959 ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (mnt_flags & MNT_ATIME_MASK))) {
1960 return -EPERM;
1961 }
1962
1927 err = security_sb_remount(sb, data); 1963 err = security_sb_remount(sb, data);
1928 if (err) 1964 if (err)
1929 return err; 1965 return err;
@@ -1937,7 +1973,7 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
1937 err = do_remount_sb(sb, flags, data, 0); 1973 err = do_remount_sb(sb, flags, data, 0);
1938 if (!err) { 1974 if (!err) {
1939 lock_mount_hash(); 1975 lock_mount_hash();
1940 mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK; 1976 mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
1941 mnt->mnt.mnt_flags = mnt_flags; 1977 mnt->mnt.mnt_flags = mnt_flags;
1942 touch_mnt_namespace(mnt->mnt_ns); 1978 touch_mnt_namespace(mnt->mnt_ns);
1943 unlock_mount_hash(); 1979 unlock_mount_hash();
@@ -2122,7 +2158,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
2122 */ 2158 */
2123 if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) { 2159 if (!(type->fs_flags & FS_USERNS_DEV_MOUNT)) {
2124 flags |= MS_NODEV; 2160 flags |= MS_NODEV;
2125 mnt_flags |= MNT_NODEV; 2161 mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
2126 } 2162 }
2127 } 2163 }
2128 2164
@@ -2436,6 +2472,14 @@ long do_mount(const char *dev_name, const char *dir_name,
2436 if (flags & MS_RDONLY) 2472 if (flags & MS_RDONLY)
2437 mnt_flags |= MNT_READONLY; 2473 mnt_flags |= MNT_READONLY;
2438 2474
2475 /* The default atime for remount is preservation */
2476 if ((flags & MS_REMOUNT) &&
2477 ((flags & (MS_NOATIME | MS_NODIRATIME | MS_RELATIME |
2478 MS_STRICTATIME)) == 0)) {
2479 mnt_flags &= ~MNT_ATIME_MASK;
2480 mnt_flags |= path.mnt->mnt_flags & MNT_ATIME_MASK;
2481 }
2482
2439 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN | 2483 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_BORN |
2440 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | 2484 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
2441 MS_STRICTATIME); 2485 MS_STRICTATIME);
@@ -2972,13 +3016,13 @@ static void *mntns_get(struct task_struct *task)
2972 struct mnt_namespace *ns = NULL; 3016 struct mnt_namespace *ns = NULL;
2973 struct nsproxy *nsproxy; 3017 struct nsproxy *nsproxy;
2974 3018
2975 rcu_read_lock(); 3019 task_lock(task);
2976 nsproxy = task_nsproxy(task); 3020 nsproxy = task->nsproxy;
2977 if (nsproxy) { 3021 if (nsproxy) {
2978 ns = nsproxy->mnt_ns; 3022 ns = nsproxy->mnt_ns;
2979 get_mnt_ns(ns); 3023 get_mnt_ns(ns);
2980 } 3024 }
2981 rcu_read_unlock(); 3025 task_unlock(task);
2982 3026
2983 return ns; 3027 return ns;
2984} 3028}