at v2.6.12-rc2 161 lines 3.9 kB view raw
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 21struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; 22 23#ifdef CONFIG_SYSCTL 24struct proc_dir_entry *proc_sys_root; 25#endif 26 27static struct super_block *proc_get_sb(struct file_system_type *fs_type, 28 int flags, const char *dev_name, void *data) 29{ 30 return get_sb_single(fs_type, flags, data, proc_fill_super); 31} 32 33static struct file_system_type proc_fs_type = { 34 .name = "proc", 35 .get_sb = proc_get_sb, 36 .kill_sb = kill_anon_super, 37}; 38 39extern int __init proc_init_inodecache(void); 40void __init proc_root_init(void) 41{ 42 int err = proc_init_inodecache(); 43 if (err) 44 return; 45 err = register_filesystem(&proc_fs_type); 46 if (err) 47 return; 48 proc_mnt = kern_mount(&proc_fs_type); 49 err = PTR_ERR(proc_mnt); 50 if (IS_ERR(proc_mnt)) { 51 unregister_filesystem(&proc_fs_type); 52 return; 53 } 54 proc_misc_init(); 55 proc_net = proc_mkdir("net", NULL); 56 proc_net_stat = proc_mkdir("net/stat", NULL); 57 58#ifdef CONFIG_SYSVIPC 59 proc_mkdir("sysvipc", NULL); 60#endif 61#ifdef CONFIG_SYSCTL 62 proc_sys_root = proc_mkdir("sys", NULL); 63#endif 64#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) 65 proc_mkdir("sys/fs", NULL); 66 proc_mkdir("sys/fs/binfmt_misc", NULL); 67#endif 68 proc_root_fs = proc_mkdir("fs", NULL); 69 proc_root_driver = proc_mkdir("driver", NULL); 70 proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ 71#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) 72 /* just give it a mountpoint */ 73 proc_mkdir("openprom", NULL); 74#endif 75 proc_tty_init(); 76#ifdef CONFIG_PROC_DEVICETREE 77 proc_device_tree_init(); 78#endif 79 proc_bus = proc_mkdir("bus", NULL); 80} 81 82static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) 83{ 84 /* 85 * nr_threads is actually protected by the tasklist_lock; 86 * however, it's conventional to do reads, especially for 87 * reporting, without any locking whatsoever. 88 */ 89 if (dir->i_ino == PROC_ROOT_INO) /* check for safety... */ 90 dir->i_nlink = proc_root.nlink + nr_threads; 91 92 if (!proc_lookup(dir, dentry, nd)) { 93 return NULL; 94 } 95 96 return proc_pid_lookup(dir, dentry, nd); 97} 98 99static int proc_root_readdir(struct file * filp, 100 void * dirent, filldir_t filldir) 101{ 102 unsigned int nr = filp->f_pos; 103 int ret; 104 105 lock_kernel(); 106 107 if (nr < FIRST_PROCESS_ENTRY) { 108 int error = proc_readdir(filp, dirent, filldir); 109 if (error <= 0) { 110 unlock_kernel(); 111 return error; 112 } 113 filp->f_pos = FIRST_PROCESS_ENTRY; 114 } 115 unlock_kernel(); 116 117 ret = proc_pid_readdir(filp, dirent, filldir); 118 return ret; 119} 120 121/* 122 * The root /proc directory is special, as it has the 123 * <pid> directories. Thus we don't use the generic 124 * directory handling functions for that.. 125 */ 126static struct file_operations proc_root_operations = { 127 .read = generic_read_dir, 128 .readdir = proc_root_readdir, 129}; 130 131/* 132 * proc root can do almost nothing.. 133 */ 134static struct inode_operations proc_root_inode_operations = { 135 .lookup = proc_root_lookup, 136}; 137 138/* 139 * This is the root "inode" in the /proc tree.. 140 */ 141struct proc_dir_entry proc_root = { 142 .low_ino = PROC_ROOT_INO, 143 .namelen = 5, 144 .name = "/proc", 145 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 146 .nlink = 2, 147 .proc_iops = &proc_root_inode_operations, 148 .proc_fops = &proc_root_operations, 149 .parent = &proc_root, 150}; 151 152EXPORT_SYMBOL(proc_symlink); 153EXPORT_SYMBOL(proc_mkdir); 154EXPORT_SYMBOL(create_proc_entry); 155EXPORT_SYMBOL(remove_proc_entry); 156EXPORT_SYMBOL(proc_root); 157EXPORT_SYMBOL(proc_root_fs); 158EXPORT_SYMBOL(proc_net); 159EXPORT_SYMBOL(proc_net_stat); 160EXPORT_SYMBOL(proc_bus); 161EXPORT_SYMBOL(proc_root_driver);