From: Sascha Hauer <s.hauer@pengutronix.de>
To: BAREBOX <barebox@lists.infradead.org>
Subject: [PATCH 06/10] fs: retire devfs as filesystem
Date: Thu, 27 Nov 2025 10:19:28 +0100 [thread overview]
Message-ID: <20251127-devfs-v1-6-4aff12818757@pengutronix.de> (raw)
In-Reply-To: <20251127-devfs-v1-0-4aff12818757@pengutronix.de>
Switch over to device special files for implementing devfs. With this we
can drop the current devfs implementation as a filesystem driver.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
common/startup.c | 2 +-
fs/devfs-core.c | 35 +++++++++++
fs/devfs.c | 174 +------------------------------------------------------
include/driver.h | 1 +
4 files changed, 39 insertions(+), 173 deletions(-)
diff --git a/common/startup.c b/common/startup.c
index dfea8394fdee67f53cb608aea882d20151cc9c61..ba3bb79c861aaa9268121ee6868399fcce8ec36c 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -60,7 +60,7 @@ static int mount_root(void)
mkdir("/dev", 0);
mkdir("/tmp", 0);
mkdir("/mnt", 0);
- mount("none", "devfs", "/dev", NULL);
+ devfs_init();
if (IS_ENABLED(CONFIG_FS_EFIVARFS) && efi_is_payload()) {
mkdir("/efivars", 0);
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 7841ac71540675c27ec3a695f0b7333cd3b02e0c..c4ff5fe5718ea2c0236fdbf124e56a13e17702d1 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -458,6 +458,39 @@ static void cdev_free(struct cdev *cdev)
free(cdev);
}
+static bool devfs_initialized;
+
+static void devfs_mknod(struct cdev *cdev)
+{
+ char *path;
+ int ret;
+
+ if (!devfs_initialized)
+ return;
+
+ path = xasprintf("/dev/%s", cdev->name);
+
+ if (cdev->link)
+ ret = symlink(cdev->link->name, path);
+ else
+ ret = mknod(path, S_IFCHR | 0600, cdev->name);
+
+ free(path);
+
+ if (ret)
+ pr_err("Failed to create /dev/%s: %pe\n", cdev->name, ERR_PTR(ret));
+}
+
+void devfs_init(void)
+{
+ struct cdev *cdev;
+
+ devfs_initialized = true;
+
+ for_each_cdev(cdev)
+ devfs_mknod(cdev);
+}
+
int devfs_create(struct cdev *new)
{
struct cdev *cdev;
@@ -479,6 +512,8 @@ int devfs_create(struct cdev *new)
if (new->link)
list_add_tail(&new->link_entry, &new->link->links);
+ devfs_mknod(new);
+
return 0;
}
diff --git a/fs/devfs.c b/fs/devfs.c
index a48c6452697b47cbd3ffc6f993230e7993e565fe..061fbf5d2ffe11671c13ee5bd2cc315c378bb86f 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -29,6 +29,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/mtd-abi.h>
#include <block.h>
+#include <stringlist.h>
struct devfs_inode {
struct inode inode;
@@ -143,41 +144,6 @@ static int devfs_truncate(struct file *f, loff_t size)
return cdev_truncate(cdev, size);
}
-static struct inode *devfs_alloc_inode(struct super_block *sb)
-{
- struct devfs_inode *node;
-
- node = xzalloc(sizeof(*node));
- if (!node)
- return NULL;
-
- return &node->inode;
-}
-
-static void devfs_destroy_inode(struct inode *inode)
-{
- struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
-
- free(node);
-}
-
-static int devfs_iterate(struct file *file, struct dir_context *ctx)
-{
- struct cdev *cdev;
-
- dir_emit_dots(file, ctx);
-
- for_each_cdev(cdev) {
- dir_emit(ctx, cdev->name, strlen(cdev->name),
- 1 /* FIXME */, DT_REG);
- }
-
- return 0;
-}
-
-static const struct inode_operations devfs_file_inode_operations;
-static const struct file_operations devfs_dir_operations;
-static const struct inode_operations devfs_dir_inode_operations;
static const struct file_operations devfs_file_operations = {
.open = devfs_open,
.release = devfs_close,
@@ -197,141 +163,5 @@ void init_special_inode(struct inode *inode, umode_t mode, const char *cdevname)
{
inode->i_mode = mode;
inode->i_fop = &devfs_file_operations;
- inode->cdevname = strdup(cdevname);
-}
-
-static int devfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
-{
- struct devfs_inode *dinode;
- struct inode *inode;
- struct cdev *cdev;
-
- cdev = cdev_by_name(dentry->name);
- if (!cdev)
- return -ENOENT;
-
- inode = d_inode(dentry);
- if (!inode)
- return 0;
-
- dinode = container_of(inode, struct devfs_inode, inode);
-
- if (dinode->cdev != cdev)
- return 0;
-
- return 1;
+ inode->cdevname = xstrdup(cdevname);
}
-
-static const struct dentry_operations devfs_dentry_operations = {
- .d_revalidate = devfs_lookup_revalidate,
-};
-
-static struct inode *devfs_get_inode(struct super_block *sb, const struct inode *dir,
- umode_t mode)
-{
- struct inode *inode = new_inode(sb);
-
- if (!inode)
- return NULL;
-
- inode->i_ino = get_next_ino();
- inode->i_mode = mode;
-
- switch (mode & S_IFMT) {
- default:
- return NULL;
- case S_IFCHR:
- case S_IFBLK:
- inode->i_op = &devfs_file_inode_operations;
- inode->i_fop = &devfs_file_operations;
- break;
- case S_IFDIR:
- inode->i_op = &devfs_dir_inode_operations;
- inode->i_fop = &devfs_dir_operations;
- inc_nlink(inode);
- break;
- }
-
- return inode;
-}
-
-static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
- unsigned int flags)
-{
- struct devfs_inode *dinode;
- struct inode *inode;
- struct cdev *cdev;
- umode_t mode;
-
- cdev = cdev_by_name(dentry->name);
- if (!cdev)
- return ERR_PTR(-ENOENT);
-
- mode = cdev_get_block_device(cdev) ? S_IFBLK : S_IFCHR;
-
- inode = devfs_get_inode(dir->i_sb, dir, mode);
- if (!inode)
- return ERR_PTR(-ENOMEM);
-
- if (cdev->ops->write)
- inode->i_mode |= S_IWUSR;
- if (cdev->ops->read)
- inode->i_mode |= S_IRUSR;
-
- dinode = container_of(inode, struct devfs_inode, inode);
-
- inode->i_size = cdev->size;
- dinode->cdev = cdev;
-
- d_add(dentry, inode);
-
- return NULL;
-}
-
-static const struct file_operations devfs_dir_operations = {
- .iterate = devfs_iterate,
-};
-
-static const struct inode_operations devfs_dir_inode_operations =
-{
- .lookup = devfs_lookup,
-};
-
-static const struct super_operations devfs_ops = {
- .alloc_inode = devfs_alloc_inode,
- .destroy_inode = devfs_destroy_inode,
-};
-
-static int devfs_probe(struct device *dev)
-{
- struct inode *inode;
- struct fs_device *fsdev = dev_to_fs_device(dev);
- struct super_block *sb = &fsdev->sb;
-
- sb->s_op = &devfs_ops;
- sb->s_d_op = &devfs_dentry_operations;
-
- inode = devfs_get_inode(sb, NULL, S_IFDIR);
- sb->s_root = d_make_root(inode);
-
- return 0;
-}
-
-static void devfs_delete(struct device *dev)
-{
-}
-
-static struct fs_driver devfs_driver = {
- .drv = {
- .probe = devfs_probe,
- .remove = devfs_delete,
- .name = "devfs",
- }
-};
-
-static int devfs_init(void)
-{
- return register_fs_driver(&devfs_driver);
-}
-
-coredevice_initcall(devfs_init);
diff --git a/include/driver.h b/include/driver.h
index 7d93c07c402421bd449adfda3aebaddddf5d3266..5a67d20ccff3fca339e7b40c32ecfbc244f358f5 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -459,6 +459,7 @@ static inline const char *cdev_name(struct cdev *cdev)
return cdev ? cdev->name : NULL;
}
+void devfs_init(void);
int devfs_create(struct cdev *);
int devfs_create_link(struct cdev *, const char *name);
int devfs_remove(struct cdev *);
--
2.47.3
next prev parent reply other threads:[~2025-11-27 9:20 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-27 9:19 [PATCH 00/10] fs: Use device special nodes for devfs Sascha Hauer
2025-11-27 9:19 ` [PATCH 01/10] fs: implement mknod Sascha Hauer
2025-11-27 9:19 ` [PATCH 02/10] commands: add mknod command Sascha Hauer
2025-11-27 9:19 ` [PATCH 03/10] fs: ramfs: add device file support Sascha Hauer
2025-11-27 9:19 ` [PATCH 04/10] cdev: add cdev_size() helper Sascha Hauer
2025-11-27 9:19 ` [PATCH 05/10] fs: fix st_size for device files Sascha Hauer
2025-11-27 9:19 ` Sascha Hauer [this message]
2025-11-27 9:19 ` [PATCH 07/10] fs: include cdevname in struct stat Sascha Hauer
2025-11-27 9:19 ` [PATCH 08/10] fs: stat_print: get cdevname from stat Sascha Hauer
2025-11-27 9:19 ` [PATCH 09/10] fs: replace cdev links with aliases Sascha Hauer
2025-11-27 9:19 ` [PATCH 10/10] ls: use ~0 for FILE_SIZE_STREAM Sascha Hauer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251127-devfs-v1-6-4aff12818757@pengutronix.de \
--to=s.hauer@pengutronix.de \
--cc=barebox@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox