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/sched.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 <asm/bitops.h>
19
20struct proc_dir_entry *proc_net, *proc_bus, *proc_root_fs, *proc_root_driver;
21
22#ifdef CONFIG_SYSCTL
23struct proc_dir_entry *proc_sys_root;
24#endif
25
26static DECLARE_FSTYPE(proc_fs_type, "proc", proc_read_super, FS_SINGLE);
27
28void __init proc_root_init(void)
29{
30	int err = register_filesystem(&proc_fs_type);
31	if (err)
32		return;
33	proc_mnt = kern_mount(&proc_fs_type);
34	err = PTR_ERR(proc_mnt);
35	if (IS_ERR(proc_mnt)) {
36		unregister_filesystem(&proc_fs_type);
37		return;
38	}
39	proc_misc_init();
40	proc_net = proc_mkdir("net", 0);
41#ifdef CONFIG_SYSVIPC
42	proc_mkdir("sysvipc", 0);
43#endif
44#ifdef CONFIG_SYSCTL
45	proc_sys_root = proc_mkdir("sys", 0);
46#endif
47#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
48	proc_mkdir("sys/fs", 0);
49	proc_mkdir("sys/fs/binfmt_misc", 0);
50#endif
51	proc_root_fs = proc_mkdir("fs", 0);
52	proc_root_driver = proc_mkdir("driver", 0);
53#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
54	/* just give it a mountpoint */
55	proc_mkdir("openprom", 0);
56#endif
57	proc_tty_init();
58#ifdef CONFIG_PROC_DEVICETREE
59	proc_device_tree_init();
60#endif
61#ifdef CONFIG_PPC_ISERIES
62	iSeries_proc_create();
63#endif
64#ifdef CONFIG_PPC64
65	proc_ppc64_init();
66#endif
67#ifdef CONFIG_PPC_RTAS
68	proc_rtas_init();
69#endif
70	proc_bus = proc_mkdir("bus", 0);
71}
72
73static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
74{
75	if (dir->i_ino == PROC_ROOT_INO) { /* check for safety... */
76		int nlink = proc_root.nlink;
77
78		nlink += nr_threads;
79
80		dir->i_nlink = nlink;
81	}
82
83	if (!proc_lookup(dir, dentry))
84		return NULL;
85
86	return proc_pid_lookup(dir, dentry);
87}
88
89static int proc_root_readdir(struct file * filp,
90	void * dirent, filldir_t filldir)
91{
92	unsigned int nr = filp->f_pos;
93
94	if (nr < FIRST_PROCESS_ENTRY) {
95		int error = proc_readdir(filp, dirent, filldir);
96		if (error <= 0)
97			return error;
98		filp->f_pos = FIRST_PROCESS_ENTRY;
99	}
100
101	return proc_pid_readdir(filp, dirent, filldir);
102}
103
104/*
105 * The root /proc directory is special, as it has the
106 * <pid> directories. Thus we don't use the generic
107 * directory handling functions for that..
108 */
109static struct file_operations proc_root_operations = {
110	read:		 generic_read_dir,
111	readdir:	 proc_root_readdir,
112};
113
114/*
115 * proc root can do almost nothing..
116 */
117static struct inode_operations proc_root_inode_operations = {
118	lookup:		proc_root_lookup,
119};
120
121/*
122 * This is the root "inode" in the /proc tree..
123 */
124struct proc_dir_entry proc_root = {
125	low_ino:	PROC_ROOT_INO,
126	namelen:	5,
127	name:		"/proc",
128	mode:		S_IFDIR | S_IRUGO | S_IXUGO,
129	nlink:		2,
130	proc_iops:	&proc_root_inode_operations,
131	proc_fops:	&proc_root_operations,
132	parent:		&proc_root,
133};
134
135#ifdef CONFIG_SYSCTL
136EXPORT_SYMBOL(proc_sys_root);
137#endif
138EXPORT_SYMBOL(proc_symlink);
139EXPORT_SYMBOL(proc_mknod);
140EXPORT_SYMBOL(proc_mkdir);
141EXPORT_SYMBOL(create_proc_entry);
142EXPORT_SYMBOL(remove_proc_entry);
143EXPORT_SYMBOL(proc_root);
144EXPORT_SYMBOL(proc_root_fs);
145EXPORT_SYMBOL(proc_net);
146EXPORT_SYMBOL(proc_bus);
147EXPORT_SYMBOL(proc_root_driver);
148