at v2.6.18-rc2 162 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/init.h> 16#include <linux/module.h> 17#include <linux/bitops.h> 18#include <linux/smp_lock.h> 19 20#include "internal.h" 21 22struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; 23 24#ifdef CONFIG_SYSCTL 25struct proc_dir_entry *proc_sys_root; 26#endif 27 28static int proc_get_sb(struct file_system_type *fs_type, 29 int flags, const char *dev_name, void *data, struct vfsmount *mnt) 30{ 31 return get_sb_single(fs_type, flags, data, proc_fill_super, mnt); 32} 33 34static struct file_system_type proc_fs_type = { 35 .name = "proc", 36 .get_sb = proc_get_sb, 37 .kill_sb = kill_anon_super, 38}; 39 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 int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat 83) 84{ 85 generic_fillattr(dentry->d_inode, stat); 86 stat->nlink = proc_root.nlink + nr_processes(); 87 return 0; 88} 89 90static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) 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 .getattr = proc_root_getattr, 137}; 138 139/* 140 * This is the root "inode" in the /proc tree.. 141 */ 142struct proc_dir_entry proc_root = { 143 .low_ino = PROC_ROOT_INO, 144 .namelen = 5, 145 .name = "/proc", 146 .mode = S_IFDIR | S_IRUGO | S_IXUGO, 147 .nlink = 2, 148 .proc_iops = &proc_root_inode_operations, 149 .proc_fops = &proc_root_operations, 150 .parent = &proc_root, 151}; 152 153EXPORT_SYMBOL(proc_symlink); 154EXPORT_SYMBOL(proc_mkdir); 155EXPORT_SYMBOL(create_proc_entry); 156EXPORT_SYMBOL(remove_proc_entry); 157EXPORT_SYMBOL(proc_root); 158EXPORT_SYMBOL(proc_root_fs); 159EXPORT_SYMBOL(proc_net); 160EXPORT_SYMBOL(proc_net_stat); 161EXPORT_SYMBOL(proc_bus); 162EXPORT_SYMBOL(proc_root_driver);