aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/root.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/root.c')
-rw-r--r--fs/proc/root.c58
1 files changed, 25 insertions, 33 deletions
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 4258384ed22d..d6c3b416529b 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -28,32 +28,22 @@ static int proc_test_super(struct super_block *sb, void *data)
28 28
29static int proc_set_super(struct super_block *sb, void *data) 29static int proc_set_super(struct super_block *sb, void *data)
30{ 30{
31 struct pid_namespace *ns; 31 int err = set_anon_super(sb, NULL);
32 32 if (!err) {
33 ns = (struct pid_namespace *)data; 33 struct pid_namespace *ns = (struct pid_namespace *)data;
34 sb->s_fs_info = get_pid_ns(ns); 34 sb->s_fs_info = get_pid_ns(ns);
35 return set_anon_super(sb, NULL); 35 }
36 return err;
36} 37}
37 38
38static int proc_get_sb(struct file_system_type *fs_type, 39static struct dentry *proc_mount(struct file_system_type *fs_type,
39 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 40 int flags, const char *dev_name, void *data)
40{ 41{
41 int err; 42 int err;
42 struct super_block *sb; 43 struct super_block *sb;
43 struct pid_namespace *ns; 44 struct pid_namespace *ns;
44 struct proc_inode *ei; 45 struct proc_inode *ei;
45 46
46 if (proc_mnt) {
47 /* Seed the root directory with a pid so it doesn't need
48 * to be special in base.c. I would do this earlier but
49 * the only task alive when /proc is mounted the first time
50 * is the init_task and it doesn't have any pids.
51 */
52 ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode);
53 if (!ei->pid)
54 ei->pid = find_get_pid(1);
55 }
56
57 if (flags & MS_KERNMOUNT) 47 if (flags & MS_KERNMOUNT)
58 ns = (struct pid_namespace *)data; 48 ns = (struct pid_namespace *)data;
59 else 49 else
@@ -61,29 +51,27 @@ static int proc_get_sb(struct file_system_type *fs_type,
61 51
62 sb = sget(fs_type, proc_test_super, proc_set_super, ns); 52 sb = sget(fs_type, proc_test_super, proc_set_super, ns);
63 if (IS_ERR(sb)) 53 if (IS_ERR(sb))
64 return PTR_ERR(sb); 54 return ERR_CAST(sb);
65 55
66 if (!sb->s_root) { 56 if (!sb->s_root) {
67 sb->s_flags = flags; 57 sb->s_flags = flags;
68 err = proc_fill_super(sb); 58 err = proc_fill_super(sb);
69 if (err) { 59 if (err) {
70 deactivate_locked_super(sb); 60 deactivate_locked_super(sb);
71 return err; 61 return ERR_PTR(err);
72 }
73
74 ei = PROC_I(sb->s_root->d_inode);
75 if (!ei->pid) {
76 rcu_read_lock();
77 ei->pid = get_pid(find_pid_ns(1, ns));
78 rcu_read_unlock();
79 } 62 }
80 63
81 sb->s_flags |= MS_ACTIVE; 64 sb->s_flags |= MS_ACTIVE;
82 ns->proc_mnt = mnt;
83 } 65 }
84 66
85 simple_set_mnt(mnt, sb); 67 ei = PROC_I(sb->s_root->d_inode);
86 return 0; 68 if (!ei->pid) {
69 rcu_read_lock();
70 ei->pid = get_pid(find_pid_ns(1, ns));
71 rcu_read_unlock();
72 }
73
74 return dget(sb->s_root);
87} 75}
88 76
89static void proc_kill_sb(struct super_block *sb) 77static void proc_kill_sb(struct super_block *sb)
@@ -97,24 +85,26 @@ static void proc_kill_sb(struct super_block *sb)
97 85
98static struct file_system_type proc_fs_type = { 86static struct file_system_type proc_fs_type = {
99 .name = "proc", 87 .name = "proc",
100 .get_sb = proc_get_sb, 88 .mount = proc_mount,
101 .kill_sb = proc_kill_sb, 89 .kill_sb = proc_kill_sb,
102}; 90};
103 91
104void __init proc_root_init(void) 92void __init proc_root_init(void)
105{ 93{
94 struct vfsmount *mnt;
106 int err; 95 int err;
107 96
108 proc_init_inodecache(); 97 proc_init_inodecache();
109 err = register_filesystem(&proc_fs_type); 98 err = register_filesystem(&proc_fs_type);
110 if (err) 99 if (err)
111 return; 100 return;
112 proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns); 101 mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
113 if (IS_ERR(proc_mnt)) { 102 if (IS_ERR(mnt)) {
114 unregister_filesystem(&proc_fs_type); 103 unregister_filesystem(&proc_fs_type);
115 return; 104 return;
116 } 105 }
117 106
107 init_pid_ns.proc_mnt = mnt;
118 proc_symlink("mounts", NULL, "self/mounts"); 108 proc_symlink("mounts", NULL, "self/mounts");
119 109
120 proc_net_init(); 110 proc_net_init();
@@ -179,6 +169,7 @@ static int proc_root_readdir(struct file * filp,
179static const struct file_operations proc_root_operations = { 169static const struct file_operations proc_root_operations = {
180 .read = generic_read_dir, 170 .read = generic_read_dir,
181 .readdir = proc_root_readdir, 171 .readdir = proc_root_readdir,
172 .llseek = default_llseek,
182}; 173};
183 174
184/* 175/*
@@ -212,6 +203,7 @@ int pid_ns_prepare_proc(struct pid_namespace *ns)
212 if (IS_ERR(mnt)) 203 if (IS_ERR(mnt))
213 return PTR_ERR(mnt); 204 return PTR_ERR(mnt);
214 205
206 ns->proc_mnt = mnt;
215 return 0; 207 return 0;
216} 208}
217 209