11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/fs/proc/root.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1991, 1992 Linus Torvalds 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * proc root directory handling functions 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #include <asm/uaccess.h> 101da177e4SLinus Torvalds 111da177e4SLinus Torvalds #include <linux/errno.h> 121da177e4SLinus Torvalds #include <linux/time.h> 131da177e4SLinus Torvalds #include <linux/proc_fs.h> 141da177e4SLinus Torvalds #include <linux/stat.h> 151da177e4SLinus Torvalds #include <linux/config.h> 161da177e4SLinus Torvalds #include <linux/init.h> 171da177e4SLinus Torvalds #include <linux/module.h> 181da177e4SLinus Torvalds #include <linux/bitops.h> 191da177e4SLinus Torvalds #include <linux/smp_lock.h> 201da177e4SLinus Torvalds 21fee781e6SAdrian Bunk #include "internal.h" 22fee781e6SAdrian Bunk 231da177e4SLinus Torvalds struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; 241da177e4SLinus Torvalds 251da177e4SLinus Torvalds #ifdef CONFIG_SYSCTL 261da177e4SLinus Torvalds struct proc_dir_entry *proc_sys_root; 271da177e4SLinus Torvalds #endif 281da177e4SLinus Torvalds 291da177e4SLinus Torvalds static struct super_block *proc_get_sb(struct file_system_type *fs_type, 301da177e4SLinus Torvalds int flags, const char *dev_name, void *data) 311da177e4SLinus Torvalds { 321da177e4SLinus Torvalds return get_sb_single(fs_type, flags, data, proc_fill_super); 331da177e4SLinus Torvalds } 341da177e4SLinus Torvalds 351da177e4SLinus Torvalds static struct file_system_type proc_fs_type = { 361da177e4SLinus Torvalds .name = "proc", 371da177e4SLinus Torvalds .get_sb = proc_get_sb, 381da177e4SLinus Torvalds .kill_sb = kill_anon_super, 391da177e4SLinus Torvalds }; 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds void __init proc_root_init(void) 421da177e4SLinus Torvalds { 431da177e4SLinus Torvalds int err = proc_init_inodecache(); 441da177e4SLinus Torvalds if (err) 451da177e4SLinus Torvalds return; 461da177e4SLinus Torvalds err = register_filesystem(&proc_fs_type); 471da177e4SLinus Torvalds if (err) 481da177e4SLinus Torvalds return; 491da177e4SLinus Torvalds proc_mnt = kern_mount(&proc_fs_type); 501da177e4SLinus Torvalds err = PTR_ERR(proc_mnt); 511da177e4SLinus Torvalds if (IS_ERR(proc_mnt)) { 521da177e4SLinus Torvalds unregister_filesystem(&proc_fs_type); 531da177e4SLinus Torvalds return; 541da177e4SLinus Torvalds } 551da177e4SLinus Torvalds proc_misc_init(); 561da177e4SLinus Torvalds proc_net = proc_mkdir("net", NULL); 571da177e4SLinus Torvalds proc_net_stat = proc_mkdir("net/stat", NULL); 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds #ifdef CONFIG_SYSVIPC 601da177e4SLinus Torvalds proc_mkdir("sysvipc", NULL); 611da177e4SLinus Torvalds #endif 621da177e4SLinus Torvalds #ifdef CONFIG_SYSCTL 631da177e4SLinus Torvalds proc_sys_root = proc_mkdir("sys", NULL); 641da177e4SLinus Torvalds #endif 651da177e4SLinus Torvalds #if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE) 661da177e4SLinus Torvalds proc_mkdir("sys/fs", NULL); 671da177e4SLinus Torvalds proc_mkdir("sys/fs/binfmt_misc", NULL); 681da177e4SLinus Torvalds #endif 691da177e4SLinus Torvalds proc_root_fs = proc_mkdir("fs", NULL); 701da177e4SLinus Torvalds proc_root_driver = proc_mkdir("driver", NULL); 711da177e4SLinus Torvalds proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */ 721da177e4SLinus Torvalds #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE) 731da177e4SLinus Torvalds /* just give it a mountpoint */ 741da177e4SLinus Torvalds proc_mkdir("openprom", NULL); 751da177e4SLinus Torvalds #endif 761da177e4SLinus Torvalds proc_tty_init(); 771da177e4SLinus Torvalds #ifdef CONFIG_PROC_DEVICETREE 781da177e4SLinus Torvalds proc_device_tree_init(); 791da177e4SLinus Torvalds #endif 801da177e4SLinus Torvalds proc_bus = proc_mkdir("bus", NULL); 811da177e4SLinus Torvalds } 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry, struct nameidata *nd) 841da177e4SLinus Torvalds { 851da177e4SLinus Torvalds /* 861da177e4SLinus Torvalds * nr_threads is actually protected by the tasklist_lock; 871da177e4SLinus Torvalds * however, it's conventional to do reads, especially for 881da177e4SLinus Torvalds * reporting, without any locking whatsoever. 891da177e4SLinus Torvalds */ 901da177e4SLinus Torvalds if (dir->i_ino == PROC_ROOT_INO) /* check for safety... */ 911da177e4SLinus Torvalds dir->i_nlink = proc_root.nlink + nr_threads; 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds if (!proc_lookup(dir, dentry, nd)) { 941da177e4SLinus Torvalds return NULL; 951da177e4SLinus Torvalds } 961da177e4SLinus Torvalds 971da177e4SLinus Torvalds return proc_pid_lookup(dir, dentry, nd); 981da177e4SLinus Torvalds } 991da177e4SLinus Torvalds 1001da177e4SLinus Torvalds static int proc_root_readdir(struct file * filp, 1011da177e4SLinus Torvalds void * dirent, filldir_t filldir) 1021da177e4SLinus Torvalds { 1031da177e4SLinus Torvalds unsigned int nr = filp->f_pos; 1041da177e4SLinus Torvalds int ret; 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds lock_kernel(); 1071da177e4SLinus Torvalds 1081da177e4SLinus Torvalds if (nr < FIRST_PROCESS_ENTRY) { 1091da177e4SLinus Torvalds int error = proc_readdir(filp, dirent, filldir); 1101da177e4SLinus Torvalds if (error <= 0) { 1111da177e4SLinus Torvalds unlock_kernel(); 1121da177e4SLinus Torvalds return error; 1131da177e4SLinus Torvalds } 1141da177e4SLinus Torvalds filp->f_pos = FIRST_PROCESS_ENTRY; 1151da177e4SLinus Torvalds } 1161da177e4SLinus Torvalds unlock_kernel(); 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds ret = proc_pid_readdir(filp, dirent, filldir); 1191da177e4SLinus Torvalds return ret; 1201da177e4SLinus Torvalds } 1211da177e4SLinus Torvalds 1221da177e4SLinus Torvalds /* 1231da177e4SLinus Torvalds * The root /proc directory is special, as it has the 1241da177e4SLinus Torvalds * <pid> directories. Thus we don't use the generic 1251da177e4SLinus Torvalds * directory handling functions for that.. 1261da177e4SLinus Torvalds */ 1271da177e4SLinus Torvalds static struct file_operations proc_root_operations = { 1281da177e4SLinus Torvalds .read = generic_read_dir, 1291da177e4SLinus Torvalds .readdir = proc_root_readdir, 1301da177e4SLinus Torvalds }; 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds /* 1331da177e4SLinus Torvalds * proc root can do almost nothing.. 1341da177e4SLinus Torvalds */ 1351da177e4SLinus Torvalds static struct inode_operations proc_root_inode_operations = { 1361da177e4SLinus Torvalds .lookup = proc_root_lookup, 1371da177e4SLinus Torvalds }; 1381da177e4SLinus Torvalds 1391da177e4SLinus Torvalds /* 1401da177e4SLinus Torvalds * This is the root "inode" in the /proc tree.. 1411da177e4SLinus Torvalds */ 1421da177e4SLinus Torvalds struct proc_dir_entry proc_root = { 1431da177e4SLinus Torvalds .low_ino = PROC_ROOT_INO, 1441da177e4SLinus Torvalds .namelen = 5, 1451da177e4SLinus Torvalds .name = "/proc", 1461da177e4SLinus Torvalds .mode = S_IFDIR | S_IRUGO | S_IXUGO, 1471da177e4SLinus Torvalds .nlink = 2, 1481da177e4SLinus Torvalds .proc_iops = &proc_root_inode_operations, 1491da177e4SLinus Torvalds .proc_fops = &proc_root_operations, 1501da177e4SLinus Torvalds .parent = &proc_root, 1511da177e4SLinus Torvalds }; 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds EXPORT_SYMBOL(proc_symlink); 1541da177e4SLinus Torvalds EXPORT_SYMBOL(proc_mkdir); 1551da177e4SLinus Torvalds EXPORT_SYMBOL(create_proc_entry); 1561da177e4SLinus Torvalds EXPORT_SYMBOL(remove_proc_entry); 1571da177e4SLinus Torvalds EXPORT_SYMBOL(proc_root); 1581da177e4SLinus Torvalds EXPORT_SYMBOL(proc_root_fs); 1591da177e4SLinus Torvalds EXPORT_SYMBOL(proc_net); 1601da177e4SLinus Torvalds EXPORT_SYMBOL(proc_net_stat); 1611da177e4SLinus Torvalds EXPORT_SYMBOL(proc_bus); 1621da177e4SLinus Torvalds EXPORT_SYMBOL(proc_root_driver); 163