2
* devtmpfs - kernel-maintained tmpfs-based /dev
4
* Copyright (C) 2009, Kay Sievers <kay.sievers@vrfy.org>
6
* During bootup, before any driver core device is registered,
7
* devtmpfs, a tmpfs-based filesystem is created. Every driver-core
8
* device which requests a device node, will add a node in this
9
* filesystem. The node is named after the the name of the device,
10
* or the susbsytem can provide a custom name. All devices are
11
* owned by root and have a mode of 0600.
14
#include <linux/kernel.h>
15
#include <linux/syscalls.h>
16
#include <linux/mount.h>
17
#include <linux/device.h>
18
#include <linux/genhd.h>
19
#include <linux/namei.h>
21
#include <linux/shmem_fs.h>
22
#include <linux/cred.h>
23
#include <linux/init_task.h>
25
static struct vfsmount *dev_mnt;
27
#if defined CONFIG_DEVTMPFS_MOUNT
28
static int dev_mount = 1;
33
static int __init mount_param(char *str)
35
dev_mount = simple_strtoul(str, NULL, 0);
38
__setup("devtmpfs.mount=", mount_param);
40
static int dev_get_sb(struct file_system_type *fs_type, int flags,
41
const char *dev_name, void *data, struct vfsmount *mnt)
43
return get_sb_single(fs_type, flags, data, shmem_fill_super, mnt);
46
static struct file_system_type dev_fs_type = {
49
.kill_sb = kill_litter_super,
53
static inline int is_blockdev(struct device *dev)
55
return dev->class == &block_class;
58
static inline int is_blockdev(struct device *dev) { return 0; }
61
static int dev_mkdir(const char *name, mode_t mode)
64
struct dentry *dentry;
67
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
68
name, LOOKUP_PARENT, &nd);
72
dentry = lookup_create(&nd, 1);
73
if (!IS_ERR(dentry)) {
74
err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
77
err = PTR_ERR(dentry);
79
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
85
static int create_path(const char *nodepath)
91
path = kstrdup(nodepath, GFP_KERNEL);
95
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
96
path, LOOKUP_PARENT, &nd);
98
struct dentry *dentry;
100
/* create directory right away */
101
dentry = lookup_create(&nd, 1);
102
if (!IS_ERR(dentry)) {
103
err = vfs_mkdir(nd.path.dentry->d_inode,
107
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
110
} else if (err == -ENOENT) {
113
/* parent directories do not exist, create them */
120
err = dev_mkdir(path, 0755);
121
if (err && err != -EEXIST)
132
int devtmpfs_create_node(struct device *dev)
134
const char *tmp = NULL;
135
const char *nodename;
136
const struct cred *curr_cred;
139
struct dentry *dentry;
145
nodename = device_get_nodename(dev, &tmp);
149
if (is_blockdev(dev))
154
curr_cred = override_creds(&init_cred);
155
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
156
nodename, LOOKUP_PARENT, &nd);
157
if (err == -ENOENT) {
158
/* create missing parent directories */
159
create_path(nodename);
160
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
161
nodename, LOOKUP_PARENT, &nd);
166
dentry = lookup_create(&nd, 0);
167
if (!IS_ERR(dentry)) {
168
err = vfs_mknod(nd.path.dentry->d_inode,
169
dentry, mode, dev->devt);
170
/* mark as kernel created inode */
172
dentry->d_inode->i_private = &dev_mnt;
175
err = PTR_ERR(dentry);
177
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
182
revert_creds(curr_cred);
186
static int dev_rmdir(const char *name)
189
struct dentry *dentry;
192
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
193
name, LOOKUP_PARENT, &nd);
197
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
198
dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
199
if (!IS_ERR(dentry)) {
201
err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
206
err = PTR_ERR(dentry);
208
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
214
static int delete_path(const char *nodepath)
219
path = kstrdup(nodepath, GFP_KERNEL);
226
base = strrchr(path, '/');
230
err = dev_rmdir(path);
239
static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat)
241
/* did we create it */
242
if (inode->i_private != &dev_mnt)
245
/* does the dev_t match */
246
if (is_blockdev(dev)) {
247
if (!S_ISBLK(stat->mode))
250
if (!S_ISCHR(stat->mode))
253
if (stat->rdev != dev->devt)
260
int devtmpfs_delete_node(struct device *dev)
262
const char *tmp = NULL;
263
const char *nodename;
264
const struct cred *curr_cred;
266
struct dentry *dentry;
274
nodename = device_get_nodename(dev, &tmp);
278
curr_cred = override_creds(&init_cred);
279
err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
280
nodename, LOOKUP_PARENT, &nd);
284
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
285
dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
286
if (!IS_ERR(dentry)) {
287
if (dentry->d_inode) {
288
err = vfs_getattr(nd.path.mnt, dentry, &stat);
289
if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
290
err = vfs_unlink(nd.path.dentry->d_inode,
292
if (!err || err == -ENOENT)
300
err = PTR_ERR(dentry);
302
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
305
if (deleted && strchr(nodename, '/'))
306
delete_path(nodename);
309
revert_creds(curr_cred);
314
* If configured, or requested by the commandline, devtmpfs will be
315
* auto-mounted after the kernel mounted the root filesystem.
317
int devtmpfs_mount(const char *mountpoint)
328
err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
331
err = do_add_mount(dev_mnt, &path, 0, NULL);
333
printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
335
printk(KERN_INFO "devtmpfs: mounted\n");
341
* Create devtmpfs instance, driver-core devices will add their device
344
int __init devtmpfs_init(void)
347
struct vfsmount *mnt;
348
char options[] = "mode=0755";
350
err = register_filesystem(&dev_fs_type);
352
printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
357
mnt = kern_mount_data(&dev_fs_type, options);
360
printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
361
unregister_filesystem(&dev_fs_type);
366
printk(KERN_INFO "devtmpfs: initialized\n");