12b2af54aSKay Sievers /* 22b2af54aSKay Sievers * devtmpfs - kernel-maintained tmpfs-based /dev 32b2af54aSKay Sievers * 42b2af54aSKay Sievers * Copyright (C) 2009, Kay Sievers <kay.sievers@vrfy.org> 52b2af54aSKay Sievers * 62b2af54aSKay Sievers * During bootup, before any driver core device is registered, 72b2af54aSKay Sievers * devtmpfs, a tmpfs-based filesystem is created. Every driver-core 82b2af54aSKay Sievers * device which requests a device node, will add a node in this 9e454cea2SKay Sievers * filesystem. 10e454cea2SKay Sievers * By default, all devices are named after the the name of the 11e454cea2SKay Sievers * device, owned by root and have a default mode of 0600. Subsystems 12e454cea2SKay Sievers * can overwrite the default setting if needed. 132b2af54aSKay Sievers */ 142b2af54aSKay Sievers 152b2af54aSKay Sievers #include <linux/kernel.h> 162b2af54aSKay Sievers #include <linux/syscalls.h> 172b2af54aSKay Sievers #include <linux/mount.h> 182b2af54aSKay Sievers #include <linux/device.h> 192b2af54aSKay Sievers #include <linux/genhd.h> 202b2af54aSKay Sievers #include <linux/namei.h> 212b2af54aSKay Sievers #include <linux/fs.h> 222b2af54aSKay Sievers #include <linux/shmem_fs.h> 23da5e4ef7SPeter Korsgaard #include <linux/ramfs.h> 24e454cea2SKay Sievers #include <linux/sched.h> 255a0e3ad6STejun Heo #include <linux/slab.h> 262780f1ffSAl Viro #include <linux/kthread.h> 272b2af54aSKay Sievers 282780f1ffSAl Viro static struct task_struct *thread; 292b2af54aSKay Sievers 302b2af54aSKay Sievers #if defined CONFIG_DEVTMPFS_MOUNT 31fc14f2feSAl Viro static int mount_dev = 1; 322b2af54aSKay Sievers #else 33fc14f2feSAl Viro static int mount_dev; 342b2af54aSKay Sievers #endif 352b2af54aSKay Sievers 362780f1ffSAl Viro static DEFINE_SPINLOCK(req_lock); 372780f1ffSAl Viro 382780f1ffSAl Viro static struct req { 392780f1ffSAl Viro struct req *next; 402780f1ffSAl Viro struct completion done; 412780f1ffSAl Viro int err; 422780f1ffSAl Viro const char *name; 432780f1ffSAl Viro mode_t mode; /* 0 => delete */ 442780f1ffSAl Viro struct device *dev; 452780f1ffSAl Viro } *requests; 46ed413ae6SKay Sievers 472b2af54aSKay Sievers static int __init mount_param(char *str) 482b2af54aSKay Sievers { 49fc14f2feSAl Viro mount_dev = simple_strtoul(str, NULL, 0); 502b2af54aSKay Sievers return 1; 512b2af54aSKay Sievers } 522b2af54aSKay Sievers __setup("devtmpfs.mount=", mount_param); 532b2af54aSKay Sievers 54fc14f2feSAl Viro static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, 55fc14f2feSAl Viro const char *dev_name, void *data) 562b2af54aSKay Sievers { 57da5e4ef7SPeter Korsgaard #ifdef CONFIG_TMPFS 58fc14f2feSAl Viro return mount_single(fs_type, flags, data, shmem_fill_super); 59da5e4ef7SPeter Korsgaard #else 60fc14f2feSAl Viro return mount_single(fs_type, flags, data, ramfs_fill_super); 61da5e4ef7SPeter Korsgaard #endif 622b2af54aSKay Sievers } 632b2af54aSKay Sievers 642b2af54aSKay Sievers static struct file_system_type dev_fs_type = { 652b2af54aSKay Sievers .name = "devtmpfs", 66fc14f2feSAl Viro .mount = dev_mount, 672b2af54aSKay Sievers .kill_sb = kill_litter_super, 682b2af54aSKay Sievers }; 692b2af54aSKay Sievers 702b2af54aSKay Sievers #ifdef CONFIG_BLOCK 712b2af54aSKay Sievers static inline int is_blockdev(struct device *dev) 722b2af54aSKay Sievers { 732b2af54aSKay Sievers return dev->class == &block_class; 742b2af54aSKay Sievers } 752b2af54aSKay Sievers #else 762b2af54aSKay Sievers static inline int is_blockdev(struct device *dev) { return 0; } 772b2af54aSKay Sievers #endif 782b2af54aSKay Sievers 792780f1ffSAl Viro int devtmpfs_create_node(struct device *dev) 802780f1ffSAl Viro { 812780f1ffSAl Viro const char *tmp = NULL; 822780f1ffSAl Viro struct req req; 832780f1ffSAl Viro 842780f1ffSAl Viro if (!thread) 852780f1ffSAl Viro return 0; 862780f1ffSAl Viro 872780f1ffSAl Viro req.mode = 0; 882780f1ffSAl Viro req.name = device_get_devnode(dev, &req.mode, &tmp); 892780f1ffSAl Viro if (!req.name) 902780f1ffSAl Viro return -ENOMEM; 912780f1ffSAl Viro 922780f1ffSAl Viro if (req.mode == 0) 932780f1ffSAl Viro req.mode = 0600; 942780f1ffSAl Viro if (is_blockdev(dev)) 952780f1ffSAl Viro req.mode |= S_IFBLK; 962780f1ffSAl Viro else 972780f1ffSAl Viro req.mode |= S_IFCHR; 982780f1ffSAl Viro 992780f1ffSAl Viro req.dev = dev; 1002780f1ffSAl Viro 1012780f1ffSAl Viro init_completion(&req.done); 1022780f1ffSAl Viro 1032780f1ffSAl Viro spin_lock(&req_lock); 1042780f1ffSAl Viro req.next = requests; 1052780f1ffSAl Viro requests = &req; 1062780f1ffSAl Viro spin_unlock(&req_lock); 1072780f1ffSAl Viro 1082780f1ffSAl Viro wake_up_process(thread); 1092780f1ffSAl Viro wait_for_completion(&req.done); 1102780f1ffSAl Viro 1112780f1ffSAl Viro kfree(tmp); 1122780f1ffSAl Viro 1132780f1ffSAl Viro return req.err; 1142780f1ffSAl Viro } 1152780f1ffSAl Viro 1162780f1ffSAl Viro int devtmpfs_delete_node(struct device *dev) 1172780f1ffSAl Viro { 1182780f1ffSAl Viro const char *tmp = NULL; 1192780f1ffSAl Viro struct req req; 1202780f1ffSAl Viro 1212780f1ffSAl Viro if (!thread) 1222780f1ffSAl Viro return 0; 1232780f1ffSAl Viro 1242780f1ffSAl Viro req.name = device_get_devnode(dev, NULL, &tmp); 1252780f1ffSAl Viro if (!req.name) 1262780f1ffSAl Viro return -ENOMEM; 1272780f1ffSAl Viro 1282780f1ffSAl Viro req.mode = 0; 1292780f1ffSAl Viro req.dev = dev; 1302780f1ffSAl Viro 1312780f1ffSAl Viro init_completion(&req.done); 1322780f1ffSAl Viro 1332780f1ffSAl Viro spin_lock(&req_lock); 1342780f1ffSAl Viro req.next = requests; 1352780f1ffSAl Viro requests = &req; 1362780f1ffSAl Viro spin_unlock(&req_lock); 1372780f1ffSAl Viro 1382780f1ffSAl Viro wake_up_process(thread); 1392780f1ffSAl Viro wait_for_completion(&req.done); 1402780f1ffSAl Viro 1412780f1ffSAl Viro kfree(tmp); 1422780f1ffSAl Viro return req.err; 1432780f1ffSAl Viro } 1442780f1ffSAl Viro 1452b2af54aSKay Sievers static int dev_mkdir(const char *name, mode_t mode) 1462b2af54aSKay Sievers { 1472b2af54aSKay Sievers struct nameidata nd; 1482b2af54aSKay Sievers struct dentry *dentry; 1492b2af54aSKay Sievers int err; 1502b2af54aSKay Sievers 1512780f1ffSAl Viro err = kern_path_parent(name, &nd); 1522b2af54aSKay Sievers if (err) 1532b2af54aSKay Sievers return err; 1542b2af54aSKay Sievers 1552b2af54aSKay Sievers dentry = lookup_create(&nd, 1); 1562b2af54aSKay Sievers if (!IS_ERR(dentry)) { 1572b2af54aSKay Sievers err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); 158015bf43bSKay Sievers if (!err) 159015bf43bSKay Sievers /* mark as kernel-created inode */ 1602780f1ffSAl Viro dentry->d_inode->i_private = &thread; 1612b2af54aSKay Sievers dput(dentry); 1622b2af54aSKay Sievers } else { 1632b2af54aSKay Sievers err = PTR_ERR(dentry); 1642b2af54aSKay Sievers } 1652b2af54aSKay Sievers 166015bf43bSKay Sievers mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 1672b2af54aSKay Sievers path_put(&nd.path); 1682b2af54aSKay Sievers return err; 1692b2af54aSKay Sievers } 1702b2af54aSKay Sievers 1712b2af54aSKay Sievers static int create_path(const char *nodepath) 1722b2af54aSKay Sievers { 173015bf43bSKay Sievers int err; 1742b2af54aSKay Sievers 175015bf43bSKay Sievers err = dev_mkdir(nodepath, 0755); 176015bf43bSKay Sievers if (err == -ENOENT) { 177ed413ae6SKay Sievers char *path; 1782b2af54aSKay Sievers char *s; 1792b2af54aSKay Sievers 1802b2af54aSKay Sievers /* parent directories do not exist, create them */ 181ed413ae6SKay Sievers path = kstrdup(nodepath, GFP_KERNEL); 18280422738SKay Sievers if (!path) { 18380422738SKay Sievers err = -ENOMEM; 18480422738SKay Sievers goto out; 18580422738SKay Sievers } 1862b2af54aSKay Sievers s = path; 187ed413ae6SKay Sievers for (;;) { 1882b2af54aSKay Sievers s = strchr(s, '/'); 1892b2af54aSKay Sievers if (!s) 1902b2af54aSKay Sievers break; 1912b2af54aSKay Sievers s[0] = '\0'; 1922b2af54aSKay Sievers err = dev_mkdir(path, 0755); 1932b2af54aSKay Sievers if (err && err != -EEXIST) 1942b2af54aSKay Sievers break; 1952b2af54aSKay Sievers s[0] = '/'; 1962b2af54aSKay Sievers s++; 1972b2af54aSKay Sievers } 1982b2af54aSKay Sievers kfree(path); 199ed413ae6SKay Sievers } 20080422738SKay Sievers out: 2012b2af54aSKay Sievers return err; 2022b2af54aSKay Sievers } 2032b2af54aSKay Sievers 2042780f1ffSAl Viro static int handle_create(const char *nodename, mode_t mode, struct device *dev) 2052b2af54aSKay Sievers { 2062b2af54aSKay Sievers struct nameidata nd; 2072b2af54aSKay Sievers struct dentry *dentry; 2082b2af54aSKay Sievers int err; 2092b2af54aSKay Sievers 2102780f1ffSAl Viro err = kern_path_parent(nodename, &nd); 2112b2af54aSKay Sievers if (err == -ENOENT) { 2122b2af54aSKay Sievers create_path(nodename); 2132780f1ffSAl Viro err = kern_path_parent(nodename, &nd); 21400926996SKay Sievers } 2152b2af54aSKay Sievers if (err) 2162780f1ffSAl Viro return err; 2172b2af54aSKay Sievers 2182b2af54aSKay Sievers dentry = lookup_create(&nd, 0); 2192b2af54aSKay Sievers if (!IS_ERR(dentry)) { 2202b2af54aSKay Sievers err = vfs_mknod(nd.path.dentry->d_inode, 2212b2af54aSKay Sievers dentry, mode, dev->devt); 22200926996SKay Sievers if (!err) { 22300926996SKay Sievers struct iattr newattrs; 22400926996SKay Sievers 22500926996SKay Sievers /* fixup possibly umasked mode */ 22600926996SKay Sievers newattrs.ia_mode = mode; 22700926996SKay Sievers newattrs.ia_valid = ATTR_MODE; 22800926996SKay Sievers mutex_lock(&dentry->d_inode->i_mutex); 22900926996SKay Sievers notify_change(dentry, &newattrs); 23000926996SKay Sievers mutex_unlock(&dentry->d_inode->i_mutex); 23100926996SKay Sievers 23200926996SKay Sievers /* mark as kernel-created inode */ 2332780f1ffSAl Viro dentry->d_inode->i_private = &thread; 23400926996SKay Sievers } 2352b2af54aSKay Sievers dput(dentry); 2362b2af54aSKay Sievers } else { 2372b2af54aSKay Sievers err = PTR_ERR(dentry); 2382b2af54aSKay Sievers } 2392b2af54aSKay Sievers 24000926996SKay Sievers mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2412b2af54aSKay Sievers path_put(&nd.path); 2422b2af54aSKay Sievers return err; 2432b2af54aSKay Sievers } 2442b2af54aSKay Sievers 2452b2af54aSKay Sievers static int dev_rmdir(const char *name) 2462b2af54aSKay Sievers { 2472b2af54aSKay Sievers struct nameidata nd; 2482b2af54aSKay Sievers struct dentry *dentry; 2492b2af54aSKay Sievers int err; 2502b2af54aSKay Sievers 2512780f1ffSAl Viro err = kern_path_parent(name, &nd); 2522b2af54aSKay Sievers if (err) 2532b2af54aSKay Sievers return err; 2542b2af54aSKay Sievers 2552b2af54aSKay Sievers mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); 2562b2af54aSKay Sievers dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); 2572b2af54aSKay Sievers if (!IS_ERR(dentry)) { 258015bf43bSKay Sievers if (dentry->d_inode) { 2592780f1ffSAl Viro if (dentry->d_inode->i_private == &thread) 260015bf43bSKay Sievers err = vfs_rmdir(nd.path.dentry->d_inode, 261015bf43bSKay Sievers dentry); 2622b2af54aSKay Sievers else 263015bf43bSKay Sievers err = -EPERM; 264015bf43bSKay Sievers } else { 2652b2af54aSKay Sievers err = -ENOENT; 266015bf43bSKay Sievers } 2672b2af54aSKay Sievers dput(dentry); 2682b2af54aSKay Sievers } else { 2692b2af54aSKay Sievers err = PTR_ERR(dentry); 2702b2af54aSKay Sievers } 2712b2af54aSKay Sievers 272015bf43bSKay Sievers mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2732b2af54aSKay Sievers path_put(&nd.path); 2742b2af54aSKay Sievers return err; 2752b2af54aSKay Sievers } 2762b2af54aSKay Sievers 2772b2af54aSKay Sievers static int delete_path(const char *nodepath) 2782b2af54aSKay Sievers { 2792b2af54aSKay Sievers const char *path; 2802b2af54aSKay Sievers int err = 0; 2812b2af54aSKay Sievers 2822b2af54aSKay Sievers path = kstrdup(nodepath, GFP_KERNEL); 2832b2af54aSKay Sievers if (!path) 2842b2af54aSKay Sievers return -ENOMEM; 2852b2af54aSKay Sievers 286ed413ae6SKay Sievers for (;;) { 2872b2af54aSKay Sievers char *base; 2882b2af54aSKay Sievers 2892b2af54aSKay Sievers base = strrchr(path, '/'); 2902b2af54aSKay Sievers if (!base) 2912b2af54aSKay Sievers break; 2922b2af54aSKay Sievers base[0] = '\0'; 2932b2af54aSKay Sievers err = dev_rmdir(path); 2942b2af54aSKay Sievers if (err) 2952b2af54aSKay Sievers break; 2962b2af54aSKay Sievers } 2972b2af54aSKay Sievers 2982b2af54aSKay Sievers kfree(path); 2992b2af54aSKay Sievers return err; 3002b2af54aSKay Sievers } 3012b2af54aSKay Sievers 3022b2af54aSKay Sievers static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat) 3032b2af54aSKay Sievers { 3042b2af54aSKay Sievers /* did we create it */ 3052780f1ffSAl Viro if (inode->i_private != &thread) 3062b2af54aSKay Sievers return 0; 3072b2af54aSKay Sievers 3082b2af54aSKay Sievers /* does the dev_t match */ 3092b2af54aSKay Sievers if (is_blockdev(dev)) { 3102b2af54aSKay Sievers if (!S_ISBLK(stat->mode)) 3112b2af54aSKay Sievers return 0; 3122b2af54aSKay Sievers } else { 3132b2af54aSKay Sievers if (!S_ISCHR(stat->mode)) 3142b2af54aSKay Sievers return 0; 3152b2af54aSKay Sievers } 3162b2af54aSKay Sievers if (stat->rdev != dev->devt) 3172b2af54aSKay Sievers return 0; 3182b2af54aSKay Sievers 3192b2af54aSKay Sievers /* ours */ 3202b2af54aSKay Sievers return 1; 3212b2af54aSKay Sievers } 3222b2af54aSKay Sievers 3232780f1ffSAl Viro static int handle_remove(const char *nodename, struct device *dev) 3242b2af54aSKay Sievers { 3252b2af54aSKay Sievers struct nameidata nd; 3262b2af54aSKay Sievers struct dentry *dentry; 3272b2af54aSKay Sievers struct kstat stat; 3282b2af54aSKay Sievers int deleted = 1; 3292b2af54aSKay Sievers int err; 3302b2af54aSKay Sievers 3312780f1ffSAl Viro err = kern_path_parent(nodename, &nd); 3322b2af54aSKay Sievers if (err) 3332780f1ffSAl Viro return err; 3342b2af54aSKay Sievers 3352b2af54aSKay Sievers mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); 3362b2af54aSKay Sievers dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len); 3372b2af54aSKay Sievers if (!IS_ERR(dentry)) { 3382b2af54aSKay Sievers if (dentry->d_inode) { 3392b2af54aSKay Sievers err = vfs_getattr(nd.path.mnt, dentry, &stat); 3402b2af54aSKay Sievers if (!err && dev_mynode(dev, dentry->d_inode, &stat)) { 3415e31d76fSKay Sievers struct iattr newattrs; 3425e31d76fSKay Sievers /* 3435e31d76fSKay Sievers * before unlinking this node, reset permissions 3445e31d76fSKay Sievers * of possible references like hardlinks 3455e31d76fSKay Sievers */ 3465e31d76fSKay Sievers newattrs.ia_uid = 0; 3475e31d76fSKay Sievers newattrs.ia_gid = 0; 3485e31d76fSKay Sievers newattrs.ia_mode = stat.mode & ~0777; 3495e31d76fSKay Sievers newattrs.ia_valid = 3505e31d76fSKay Sievers ATTR_UID|ATTR_GID|ATTR_MODE; 3515e31d76fSKay Sievers mutex_lock(&dentry->d_inode->i_mutex); 3525e31d76fSKay Sievers notify_change(dentry, &newattrs); 3535e31d76fSKay Sievers mutex_unlock(&dentry->d_inode->i_mutex); 3542b2af54aSKay Sievers err = vfs_unlink(nd.path.dentry->d_inode, 3552b2af54aSKay Sievers dentry); 3562b2af54aSKay Sievers if (!err || err == -ENOENT) 3572b2af54aSKay Sievers deleted = 1; 3582b2af54aSKay Sievers } 3592b2af54aSKay Sievers } else { 3602b2af54aSKay Sievers err = -ENOENT; 3612b2af54aSKay Sievers } 3622b2af54aSKay Sievers dput(dentry); 3632b2af54aSKay Sievers } else { 3642b2af54aSKay Sievers err = PTR_ERR(dentry); 3652b2af54aSKay Sievers } 3662b2af54aSKay Sievers mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 3672b2af54aSKay Sievers 3682b2af54aSKay Sievers path_put(&nd.path); 3692b2af54aSKay Sievers if (deleted && strchr(nodename, '/')) 3702b2af54aSKay Sievers delete_path(nodename); 3712b2af54aSKay Sievers return err; 3722b2af54aSKay Sievers } 3732b2af54aSKay Sievers 3742b2af54aSKay Sievers /* 3752b2af54aSKay Sievers * If configured, or requested by the commandline, devtmpfs will be 3762b2af54aSKay Sievers * auto-mounted after the kernel mounted the root filesystem. 3772b2af54aSKay Sievers */ 378073120ccSKay Sievers int devtmpfs_mount(const char *mntdir) 3792b2af54aSKay Sievers { 3802b2af54aSKay Sievers int err; 3812b2af54aSKay Sievers 382fc14f2feSAl Viro if (!mount_dev) 3832b2af54aSKay Sievers return 0; 3842b2af54aSKay Sievers 3852780f1ffSAl Viro if (!thread) 3862b2af54aSKay Sievers return 0; 3872b2af54aSKay Sievers 388073120ccSKay Sievers err = sys_mount("devtmpfs", (char *)mntdir, "devtmpfs", MS_SILENT, NULL); 3892b2af54aSKay Sievers if (err) 3902b2af54aSKay Sievers printk(KERN_INFO "devtmpfs: error mounting %i\n", err); 3912b2af54aSKay Sievers else 3922b2af54aSKay Sievers printk(KERN_INFO "devtmpfs: mounted\n"); 3932b2af54aSKay Sievers return err; 3942b2af54aSKay Sievers } 3952b2af54aSKay Sievers 3962780f1ffSAl Viro static __initdata DECLARE_COMPLETION(setup_done); 3972780f1ffSAl Viro 3982780f1ffSAl Viro static int handle(const char *name, mode_t mode, struct device *dev) 3992780f1ffSAl Viro { 4002780f1ffSAl Viro if (mode) 4012780f1ffSAl Viro return handle_create(name, mode, dev); 4022780f1ffSAl Viro else 4032780f1ffSAl Viro return handle_remove(name, dev); 4042780f1ffSAl Viro } 4052780f1ffSAl Viro 4062780f1ffSAl Viro static int devtmpfsd(void *p) 4072780f1ffSAl Viro { 4082780f1ffSAl Viro char options[] = "mode=0755"; 4092780f1ffSAl Viro int *err = p; 4102780f1ffSAl Viro *err = sys_unshare(CLONE_NEWNS); 4112780f1ffSAl Viro if (*err) 4122780f1ffSAl Viro goto out; 4132780f1ffSAl Viro *err = sys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); 4142780f1ffSAl Viro if (*err) 4152780f1ffSAl Viro goto out; 4162780f1ffSAl Viro sys_chdir("/.."); /* will traverse into overmounted root */ 4172780f1ffSAl Viro sys_chroot("."); 4182780f1ffSAl Viro complete(&setup_done); 4192780f1ffSAl Viro while (1) { 4202780f1ffSAl Viro spin_lock(&req_lock); 4212780f1ffSAl Viro while (requests) { 4222780f1ffSAl Viro struct req *req = requests; 4232780f1ffSAl Viro requests = NULL; 4242780f1ffSAl Viro spin_unlock(&req_lock); 4252780f1ffSAl Viro while (req) { 4262780f1ffSAl Viro req->err = handle(req->name, req->mode, req->dev); 4272780f1ffSAl Viro complete(&req->done); 4282780f1ffSAl Viro req = req->next; 4292780f1ffSAl Viro } 4302780f1ffSAl Viro spin_lock(&req_lock); 4312780f1ffSAl Viro } 4322780f1ffSAl Viro set_current_state(TASK_INTERRUPTIBLE); 4332780f1ffSAl Viro spin_unlock(&req_lock); 4342780f1ffSAl Viro schedule(); 4352780f1ffSAl Viro __set_current_state(TASK_RUNNING); 4362780f1ffSAl Viro } 4372780f1ffSAl Viro return 0; 4382780f1ffSAl Viro out: 4392780f1ffSAl Viro complete(&setup_done); 4402780f1ffSAl Viro return *err; 4412780f1ffSAl Viro } 4422780f1ffSAl Viro 4432b2af54aSKay Sievers /* 4442b2af54aSKay Sievers * Create devtmpfs instance, driver-core devices will add their device 4452b2af54aSKay Sievers * nodes here. 4462b2af54aSKay Sievers */ 4472b2af54aSKay Sievers int __init devtmpfs_init(void) 4482b2af54aSKay Sievers { 4492780f1ffSAl Viro int err = register_filesystem(&dev_fs_type); 4502b2af54aSKay Sievers if (err) { 4512b2af54aSKay Sievers printk(KERN_ERR "devtmpfs: unable to register devtmpfs " 4522b2af54aSKay Sievers "type %i\n", err); 4532b2af54aSKay Sievers return err; 4542b2af54aSKay Sievers } 4552b2af54aSKay Sievers 4562780f1ffSAl Viro thread = kthread_run(devtmpfsd, &err, "kdevtmpfs"); 4572780f1ffSAl Viro if (!IS_ERR(thread)) { 4582780f1ffSAl Viro wait_for_completion(&setup_done); 4592780f1ffSAl Viro } else { 4602780f1ffSAl Viro err = PTR_ERR(thread); 4612780f1ffSAl Viro thread = NULL; 4622780f1ffSAl Viro } 4632780f1ffSAl Viro 4642780f1ffSAl Viro if (err) { 4652b2af54aSKay Sievers printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err); 4662b2af54aSKay Sievers unregister_filesystem(&dev_fs_type); 4672b2af54aSKay Sievers return err; 4682b2af54aSKay Sievers } 4692b2af54aSKay Sievers 4702b2af54aSKay Sievers printk(KERN_INFO "devtmpfs: initialized\n"); 4712b2af54aSKay Sievers return 0; 4722b2af54aSKay Sievers } 473