mail archive of the barebox mailing list
 help / color / mirror / Atom feed
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




  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