xref: /openbmc/linux/drivers/base/devtmpfs.c (revision 2780f1ff)
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