xref: /linux/fs/proc/root.c (revision f3d9478b2ce468c3115b02ecae7e975990697f15)
1 /*
2  *  linux/fs/proc/root.c
3  *
4  *  Copyright (C) 1991, 1992 Linus Torvalds
5  *
6  *  proc root directory handling functions
7  */
8 
9 #include <asm/uaccess.h>
10 
11 #include <linux/errno.h>
12 #include <linux/time.h>
13 #include <linux/proc_fs.h>
14 #include <linux/stat.h>
15 #include <linux/config.h>
16 #include <linux/init.h>
17 #include <linux/module.h>
18 #include <linux/bitops.h>
19 #include <linux/smp_lock.h>
20 
21 #include "internal.h"
22 
23 struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
24 
25 #ifdef CONFIG_SYSCTL
26 struct proc_dir_entry *proc_sys_root;
27 #endif
28 
29 static struct super_block *proc_get_sb(struct file_system_type *fs_type,
30 	int flags, const char *dev_name, void *data)
31 {
32 	return get_sb_single(fs_type, flags, data, proc_fill_super);
33 }
34 
35 static struct file_system_type proc_fs_type = {
36 	.name		= "proc",
37 	.get_sb		= proc_get_sb,
38 	.kill_sb	= kill_anon_super,
39 };
40 
41 void __init proc_root_init(void)
42 {
43 	int err = proc_init_inodecache();
44 	if (err)
45 		return;
46 	err = register_filesystem(&proc_fs_type);
47 	if (err)
48 		return;
49 	proc_mnt = kern_mount(&proc_fs_type);
50 	err = PTR_ERR(proc_mnt);
51 	if (IS_ERR(proc_mnt)) {
52 		unregister_filesystem(&proc_fs_type);
53 		return;
54 	}
55 	proc_misc_init();
56 	proc_net = proc_mkdir("net", NULL);
57 	proc_net_stat = proc_mkdir("net/stat", NULL);
58 
59 #ifdef CONFIG_SYSVIPC
60 	proc_mkdir("sysvipc", NULL);
61 #endif
62 #ifdef CONFIG_SYSCTL
63 	proc_sys_root = proc_mkdir("sys", NULL);
64 #endif
65 #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
66 	proc_mkdir("sys/fs", NULL);
67 	proc_mkdir("sys/fs/binfmt_misc", NULL);
68 #endif
69 	proc_root_fs = proc_mkdir("fs", NULL);
70 	proc_root_driver = proc_mkdir("driver", NULL);
71 	proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
72 #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
73 	/* just give it a mountpoint */
74 	proc_mkdir("openprom", NULL);
75 #endif
76 	proc_tty_init();
77 #ifdef CONFIG_PROC_DEVICETREE
78 	proc_device_tree_init();
79 #endif
80 	proc_bus = proc_mkdir("bus", NULL);
81 }
82 
83 static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
84 )
85 {
86 	generic_fillattr(dentry->d_inode, stat);
87 	stat->nlink = proc_root.nlink + nr_processes();
88 	return 0;
89 }
90 
91 static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd)
92 {
93 	if (!proc_lookup(dir, dentry, nd)) {
94 		return NULL;
95 	}
96 
97 	return proc_pid_lookup(dir, dentry, nd);
98 }
99 
100 static int proc_root_readdir(struct file * filp,
101 	void * dirent, filldir_t filldir)
102 {
103 	unsigned int nr = filp->f_pos;
104 	int ret;
105 
106 	lock_kernel();
107 
108 	if (nr < FIRST_PROCESS_ENTRY) {
109 		int error = proc_readdir(filp, dirent, filldir);
110 		if (error <= 0) {
111 			unlock_kernel();
112 			return error;
113 		}
114 		filp->f_pos = FIRST_PROCESS_ENTRY;
115 	}
116 	unlock_kernel();
117 
118 	ret = proc_pid_readdir(filp, dirent, filldir);
119 	return ret;
120 }
121 
122 /*
123  * The root /proc directory is special, as it has the
124  * <pid> directories. Thus we don't use the generic
125  * directory handling functions for that..
126  */
127 static struct file_operations proc_root_operations = {
128 	.read		 = generic_read_dir,
129 	.readdir	 = proc_root_readdir,
130 };
131 
132 /*
133  * proc root can do almost nothing..
134  */
135 static struct inode_operations proc_root_inode_operations = {
136 	.lookup		= proc_root_lookup,
137 	.getattr	= proc_root_getattr,
138 };
139 
140 /*
141  * This is the root "inode" in the /proc tree..
142  */
143 struct proc_dir_entry proc_root = {
144 	.low_ino	= PROC_ROOT_INO,
145 	.namelen	= 5,
146 	.name		= "/proc",
147 	.mode		= S_IFDIR | S_IRUGO | S_IXUGO,
148 	.nlink		= 2,
149 	.proc_iops	= &proc_root_inode_operations,
150 	.proc_fops	= &proc_root_operations,
151 	.parent		= &proc_root,
152 };
153 
154 EXPORT_SYMBOL(proc_symlink);
155 EXPORT_SYMBOL(proc_mkdir);
156 EXPORT_SYMBOL(create_proc_entry);
157 EXPORT_SYMBOL(remove_proc_entry);
158 EXPORT_SYMBOL(proc_root);
159 EXPORT_SYMBOL(proc_root_fs);
160 EXPORT_SYMBOL(proc_net);
161 EXPORT_SYMBOL(proc_net_stat);
162 EXPORT_SYMBOL(proc_bus);
163 EXPORT_SYMBOL(proc_root_driver);
164