diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 75 |
1 files changed, 10 insertions, 65 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 06f8e63f6cb1..c6f54e4c4290 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/ramfs.h> | 27 | #include <linux/ramfs.h> |
28 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
29 | #include <linux/idr.h> | 29 | #include <linux/idr.h> |
30 | #include <linux/fs_struct.h> | ||
30 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
31 | #include <asm/unistd.h> | 32 | #include <asm/unistd.h> |
32 | #include "pnode.h" | 33 | #include "pnode.h" |
@@ -397,11 +398,10 @@ static void __mnt_unmake_readonly(struct vfsmount *mnt) | |||
397 | spin_unlock(&vfsmount_lock); | 398 | spin_unlock(&vfsmount_lock); |
398 | } | 399 | } |
399 | 400 | ||
400 | int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) | 401 | void simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) |
401 | { | 402 | { |
402 | mnt->mnt_sb = sb; | 403 | mnt->mnt_sb = sb; |
403 | mnt->mnt_root = dget(sb->s_root); | 404 | mnt->mnt_root = dget(sb->s_root); |
404 | return 0; | ||
405 | } | 405 | } |
406 | 406 | ||
407 | EXPORT_SYMBOL(simple_set_mnt); | 407 | EXPORT_SYMBOL(simple_set_mnt); |
@@ -780,6 +780,7 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt) | |||
780 | { MNT_NOATIME, ",noatime" }, | 780 | { MNT_NOATIME, ",noatime" }, |
781 | { MNT_NODIRATIME, ",nodiratime" }, | 781 | { MNT_NODIRATIME, ",nodiratime" }, |
782 | { MNT_RELATIME, ",relatime" }, | 782 | { MNT_RELATIME, ",relatime" }, |
783 | { MNT_STRICTATIME, ",strictatime" }, | ||
783 | { 0, NULL } | 784 | { 0, NULL } |
784 | }; | 785 | }; |
785 | const struct proc_fs_info *fs_infop; | 786 | const struct proc_fs_info *fs_infop; |
@@ -1919,6 +1920,9 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1919 | if (data_page) | 1920 | if (data_page) |
1920 | ((char *)data_page)[PAGE_SIZE - 1] = 0; | 1921 | ((char *)data_page)[PAGE_SIZE - 1] = 0; |
1921 | 1922 | ||
1923 | /* Default to relatime */ | ||
1924 | mnt_flags |= MNT_RELATIME; | ||
1925 | |||
1922 | /* Separate the per-mountpoint flags */ | 1926 | /* Separate the per-mountpoint flags */ |
1923 | if (flags & MS_NOSUID) | 1927 | if (flags & MS_NOSUID) |
1924 | mnt_flags |= MNT_NOSUID; | 1928 | mnt_flags |= MNT_NOSUID; |
@@ -1930,13 +1934,14 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1930 | mnt_flags |= MNT_NOATIME; | 1934 | mnt_flags |= MNT_NOATIME; |
1931 | if (flags & MS_NODIRATIME) | 1935 | if (flags & MS_NODIRATIME) |
1932 | mnt_flags |= MNT_NODIRATIME; | 1936 | mnt_flags |= MNT_NODIRATIME; |
1933 | if (flags & MS_RELATIME) | 1937 | if (flags & MS_STRICTATIME) |
1934 | mnt_flags |= MNT_RELATIME; | 1938 | mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME); |
1935 | if (flags & MS_RDONLY) | 1939 | if (flags & MS_RDONLY) |
1936 | mnt_flags |= MNT_READONLY; | 1940 | mnt_flags |= MNT_READONLY; |
1937 | 1941 | ||
1938 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | | 1942 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | |
1939 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); | 1943 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | |
1944 | MS_STRICTATIME); | ||
1940 | 1945 | ||
1941 | /* ... and get the mountpoint */ | 1946 | /* ... and get the mountpoint */ |
1942 | retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); | 1947 | retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); |
@@ -2089,66 +2094,6 @@ out1: | |||
2089 | } | 2094 | } |
2090 | 2095 | ||
2091 | /* | 2096 | /* |
2092 | * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values. | ||
2093 | * It can block. Requires the big lock held. | ||
2094 | */ | ||
2095 | void set_fs_root(struct fs_struct *fs, struct path *path) | ||
2096 | { | ||
2097 | struct path old_root; | ||
2098 | |||
2099 | write_lock(&fs->lock); | ||
2100 | old_root = fs->root; | ||
2101 | fs->root = *path; | ||
2102 | path_get(path); | ||
2103 | write_unlock(&fs->lock); | ||
2104 | if (old_root.dentry) | ||
2105 | path_put(&old_root); | ||
2106 | } | ||
2107 | |||
2108 | /* | ||
2109 | * Replace the fs->{pwdmnt,pwd} with {mnt,dentry}. Put the old values. | ||
2110 | * It can block. Requires the big lock held. | ||
2111 | */ | ||
2112 | void set_fs_pwd(struct fs_struct *fs, struct path *path) | ||
2113 | { | ||
2114 | struct path old_pwd; | ||
2115 | |||
2116 | write_lock(&fs->lock); | ||
2117 | old_pwd = fs->pwd; | ||
2118 | fs->pwd = *path; | ||
2119 | path_get(path); | ||
2120 | write_unlock(&fs->lock); | ||
2121 | |||
2122 | if (old_pwd.dentry) | ||
2123 | path_put(&old_pwd); | ||
2124 | } | ||
2125 | |||
2126 | static void chroot_fs_refs(struct path *old_root, struct path *new_root) | ||
2127 | { | ||
2128 | struct task_struct *g, *p; | ||
2129 | struct fs_struct *fs; | ||
2130 | |||
2131 | read_lock(&tasklist_lock); | ||
2132 | do_each_thread(g, p) { | ||
2133 | task_lock(p); | ||
2134 | fs = p->fs; | ||
2135 | if (fs) { | ||
2136 | atomic_inc(&fs->count); | ||
2137 | task_unlock(p); | ||
2138 | if (fs->root.dentry == old_root->dentry | ||
2139 | && fs->root.mnt == old_root->mnt) | ||
2140 | set_fs_root(fs, new_root); | ||
2141 | if (fs->pwd.dentry == old_root->dentry | ||
2142 | && fs->pwd.mnt == old_root->mnt) | ||
2143 | set_fs_pwd(fs, new_root); | ||
2144 | put_fs_struct(fs); | ||
2145 | } else | ||
2146 | task_unlock(p); | ||
2147 | } while_each_thread(g, p); | ||
2148 | read_unlock(&tasklist_lock); | ||
2149 | } | ||
2150 | |||
2151 | /* | ||
2152 | * pivot_root Semantics: | 2097 | * pivot_root Semantics: |
2153 | * Moves the root file system of the current process to the directory put_old, | 2098 | * Moves the root file system of the current process to the directory put_old, |
2154 | * makes new_root as the new root file system of the current process, and sets | 2099 | * makes new_root as the new root file system of the current process, and sets |