Blame view
fs/proc/root.c
4.35 KB
1da177e4c
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
/* * linux/fs/proc/root.c * * Copyright (C) 1991, 1992 Linus Torvalds * * proc root directory handling functions */ #include <asm/uaccess.h> #include <linux/errno.h> #include <linux/time.h> #include <linux/proc_fs.h> #include <linux/stat.h> |
1da177e4c
|
15 |
#include <linux/init.h> |
914e26379
|
16 |
#include <linux/sched.h> |
1da177e4c
|
17 18 |
#include <linux/module.h> #include <linux/bitops.h> |
f6c7a1f34
|
19 |
#include <linux/mount.h> |
07543f5c7
|
20 |
#include <linux/pid_namespace.h> |
1da177e4c
|
21 |
|
fee781e6c
|
22 |
#include "internal.h" |
07543f5c7
|
23 24 25 26 27 28 29 |
static int proc_test_super(struct super_block *sb, void *data) { return sb->s_fs_info == data; } static int proc_set_super(struct super_block *sb, void *data) { |
ff78fca2a
|
30 31 32 33 34 35 |
int err = set_anon_super(sb, NULL); if (!err) { struct pid_namespace *ns = (struct pid_namespace *)data; sb->s_fs_info = get_pid_ns(ns); } return err; |
07543f5c7
|
36 |
} |
aed1d84f9
|
37 38 |
static struct dentry *proc_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) |
1da177e4c
|
39 |
{ |
07543f5c7
|
40 41 42 43 |
int err; struct super_block *sb; struct pid_namespace *ns; struct proc_inode *ei; |
07543f5c7
|
44 45 46 47 48 49 50 |
if (flags & MS_KERNMOUNT) ns = (struct pid_namespace *)data; else ns = current->nsproxy->pid_ns; sb = sget(fs_type, proc_test_super, proc_set_super, ns); if (IS_ERR(sb)) |
aed1d84f9
|
51 |
return ERR_CAST(sb); |
07543f5c7
|
52 53 54 55 56 |
if (!sb->s_root) { sb->s_flags = flags; err = proc_fill_super(sb); if (err) { |
6f5bbff9a
|
57 |
deactivate_locked_super(sb); |
aed1d84f9
|
58 |
return ERR_PTR(err); |
07543f5c7
|
59 |
} |
07543f5c7
|
60 |
sb->s_flags |= MS_ACTIVE; |
07543f5c7
|
61 |
} |
4308eebbe
|
62 63 64 65 66 67 |
ei = PROC_I(sb->s_root->d_inode); if (!ei->pid) { rcu_read_lock(); ei->pid = get_pid(find_pid_ns(1, ns)); rcu_read_unlock(); } |
aed1d84f9
|
68 |
return dget(sb->s_root); |
07543f5c7
|
69 70 71 72 73 74 75 76 77 |
} static void proc_kill_sb(struct super_block *sb) { struct pid_namespace *ns; ns = (struct pid_namespace *)sb->s_fs_info; kill_anon_super(sb); put_pid_ns(ns); |
1da177e4c
|
78 |
} |
c2319540c
|
79 |
static struct file_system_type proc_fs_type = { |
1da177e4c
|
80 |
.name = "proc", |
aed1d84f9
|
81 |
.mount = proc_mount, |
07543f5c7
|
82 |
.kill_sb = proc_kill_sb, |
1da177e4c
|
83 |
}; |
1da177e4c
|
84 85 |
void __init proc_root_init(void) { |
5bcd7ff9e
|
86 87 88 |
int err; proc_init_inodecache(); |
1da177e4c
|
89 90 91 |
err = register_filesystem(&proc_fs_type); if (err) return; |
905ad269c
|
92 93 |
err = pid_ns_prepare_proc(&init_pid_ns); if (err) { |
1da177e4c
|
94 95 96 |
unregister_filesystem(&proc_fs_type); return; } |
07543f5c7
|
97 |
|
59c7572e8
|
98 |
proc_symlink("mounts", NULL, "self/mounts"); |
457c4cbc5
|
99 100 |
proc_net_init(); |
1da177e4c
|
101 102 103 104 |
#ifdef CONFIG_SYSVIPC proc_mkdir("sysvipc", NULL); #endif |
36a5aeb87
|
105 |
proc_mkdir("fs", NULL); |
928b4d8c8
|
106 |
proc_mkdir("driver", NULL); |
1da177e4c
|
107 108 109 110 111 112 113 114 115 |
proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) /* just give it a mountpoint */ proc_mkdir("openprom", NULL); #endif proc_tty_init(); #ifdef CONFIG_PROC_DEVICETREE proc_device_tree_init(); #endif |
9c37066d8
|
116 |
proc_mkdir("bus", NULL); |
77b14db50
|
117 |
proc_sys_init(); |
1da177e4c
|
118 |
} |
76b6159ba
|
119 120 |
static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat ) |
1da177e4c
|
121 |
{ |
76b6159ba
|
122 123 124 125 |
generic_fillattr(dentry->d_inode, stat); stat->nlink = proc_root.nlink + nr_processes(); return 0; } |
1da177e4c
|
126 |
|
76b6159ba
|
127 128 |
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) { |
1da177e4c
|
129 130 131 132 133 134 135 136 137 138 139 140 |
if (!proc_lookup(dir, dentry, nd)) { return NULL; } return proc_pid_lookup(dir, dentry, nd); } static int proc_root_readdir(struct file * filp, void * dirent, filldir_t filldir) { unsigned int nr = filp->f_pos; int ret; |
1da177e4c
|
141 142 |
if (nr < FIRST_PROCESS_ENTRY) { int error = proc_readdir(filp, dirent, filldir); |
b4df2b92d
|
143 |
if (error <= 0) |
1da177e4c
|
144 |
return error; |
1da177e4c
|
145 146 |
filp->f_pos = FIRST_PROCESS_ENTRY; } |
1da177e4c
|
147 148 149 150 151 152 153 154 155 156 |
ret = proc_pid_readdir(filp, dirent, filldir); return ret; } /* * The root /proc directory is special, as it has the * <pid> directories. Thus we don't use the generic * directory handling functions for that.. */ |
00977a59b
|
157 |
static const struct file_operations proc_root_operations = { |
1da177e4c
|
158 159 |
.read = generic_read_dir, .readdir = proc_root_readdir, |
6038f373a
|
160 |
.llseek = default_llseek, |
1da177e4c
|
161 162 163 164 165 |
}; /* * proc root can do almost nothing.. */ |
c5ef1c42c
|
166 |
static const struct inode_operations proc_root_inode_operations = { |
1da177e4c
|
167 |
.lookup = proc_root_lookup, |
76b6159ba
|
168 |
.getattr = proc_root_getattr, |
1da177e4c
|
169 170 171 172 173 174 175 176 |
}; /* * This is the root "inode" in the /proc tree.. */ struct proc_dir_entry proc_root = { .low_ino = PROC_ROOT_INO, .namelen = 5, |
1da177e4c
|
177 178 |
.mode = S_IFDIR | S_IRUGO | S_IXUGO, .nlink = 2, |
5a622f2d0
|
179 |
.count = ATOMIC_INIT(1), |
1da177e4c
|
180 181 182 |
.proc_iops = &proc_root_inode_operations, .proc_fops = &proc_root_operations, .parent = &proc_root, |
09570f914
|
183 |
.name = "/proc", |
1da177e4c
|
184 |
}; |
6f4e64335
|
185 186 187 188 189 190 191 |
int pid_ns_prepare_proc(struct pid_namespace *ns) { struct vfsmount *mnt; mnt = kern_mount_data(&proc_fs_type, ns); if (IS_ERR(mnt)) return PTR_ERR(mnt); |
579441a39
|
192 |
ns->proc_mnt = mnt; |
6f4e64335
|
193 194 195 196 197 |
return 0; } void pid_ns_release_proc(struct pid_namespace *ns) { |
905ad269c
|
198 |
kern_unmount(ns->proc_mnt); |
6f4e64335
|
199 |
} |