mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH v2 00/13] fs: Use device special nodes for devfs
@ 2025-12-09 12:51 Sascha Hauer
  2025-12-09 12:51 ` [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node() Sascha Hauer
                   ` (13 more replies)
  0 siblings, 14 replies; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

Until now we have a devfs which is a filesystem of its own. This
comes with a few limitations:

- we cannot create directories under /dev/
- Links are implemented in the devfs filesystem. They do not show
  up as regular links

This series overcomes these limitations by implementing device special
nodes. These nodes are limited to ramfs, so we cannot mount arbitrary
filesystems and use the device special files found on them. Nevertheless
we can create and use device special files on ramfs which is enough
to drop the devfs filesystem implementation and just use ramfs on /dev/.

This will in future allow us to create /dev/disk/by-* structures under
/dev/.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Changes in v2:
- Fix storage-by-uuid driver for devfs changes
- remove created device special files and links on devfs_remove()
- Link to v1: https://lore.barebox.org/20251127-devfs-v1-0-4aff12818757@pengutronix.de

---
Sascha Hauer (13):
      fs: devfs-core: add devfs_create_link_node()
      storage-by-alias: drop fake cdev
      fs: implement mknod
      commands: add mknod command
      fs: ramfs: add device file support
      cdev: add cdev_size() helper
      fs: fix st_size for device files
      fs: retire devfs as filesystem
      fs: include cdevname in struct stat
      fs: stat_print: get cdevname from stat
      common: cdev-alias: rename struct
      fs: replace cdev links with aliases
      ls: use ~0 for FILE_SIZE_STREAM

 commands/Kconfig                |   4 +
 commands/Makefile               |   1 +
 commands/devinfo.c              |   7 +-
 commands/ls.c                   |   8 +-
 commands/mknod.c                |  43 ++++++++
 common/cdev-alias.c             |  12 +--
 common/partitions.c             |   2 +-
 common/startup.c                |   2 +-
 drivers/block/dm/dm-core.c      |   1 -
 drivers/misc/storage-by-alias.c | 120 ++--------------------
 fs/devfs-core.c                 | 214 +++++++++++++++++++++++++---------------
 fs/devfs.c                      | 180 +++------------------------------
 fs/fs.c                         |  75 +++++++++-----
 fs/ramfs.c                      |  18 ++++
 include/block.h                 |   2 -
 include/driver.h                |  20 +++-
 include/fcntl.h                 |   6 ++
 include/linux/fs.h              |  13 +++
 include/linux/stat.h            |   1 +
 19 files changed, 327 insertions(+), 402 deletions(-)
---
base-commit: 500df27eb054f86ce232c5bb30c3a7ea8f771e61
change-id: 20251127-devfs-c138cff5482a

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node()
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:14   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 02/13] storage-by-alias: drop fake cdev Sascha Hauer
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

Allow to create a devfs link that not only has its own name, but also
its own device_node.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/devfs-core.c  | 8 +++++++-
 include/driver.h | 2 ++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 92e7c5823ed0d3a4c54cc7b2b1c9bf32ac535907..91082265d1aaa965160de5e414364e3fb14824d1 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -476,7 +476,7 @@ int devfs_create(struct cdev *new)
 	return 0;
 }
 
-int devfs_create_link(struct cdev *cdev, const char *name)
+int devfs_create_link_node(struct cdev *cdev, const char *name, struct device_node *node)
 {
 	struct cdev *new;
 	int ret;
@@ -489,6 +489,7 @@ int devfs_create_link(struct cdev *cdev, const char *name)
 
 	new = cdev_alloc(name);
 	new->link = cdev;
+	new->device_node = node;
 
 	ret = devfs_create(new);
 	if (ret) {
@@ -512,6 +513,11 @@ int devfs_create_link(struct cdev *cdev, const char *name)
 	return 0;
 }
 
+int devfs_create_link(struct cdev *cdev, const char *name)
+{
+	return devfs_create_link_node(cdev, name, NULL);
+}
+
 int devfs_remove(struct cdev *cdev)
 {
 	struct cdev *c, *tmp;
diff --git a/include/driver.h b/include/driver.h
index c130a3cd63fd5e6dc365a33c765a22dc4e2ca90a..e0fddecd085c991db4f1fe34c56405d28b6f53ad 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -461,6 +461,8 @@ static inline const char *cdev_name(struct cdev *cdev)
 
 int devfs_create(struct cdev *);
 int devfs_create_link(struct cdev *, const char *name);
+int devfs_create_link_node(struct cdev *cdev, const char *name,
+			   struct device_node *node);
 int devfs_remove(struct cdev *);
 int cdev_find_free_index(const char *);
 struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name);

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 02/13] storage-by-alias: drop fake cdev
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
  2025-12-09 12:51 ` [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node() Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:15   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 03/13] fs: implement mknod Sascha Hauer
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

storage-by-alias creates its own cdev, but that is never used. The only
purpose is to create a cdev with its own device node which otherwise
links to the original cdev. This means we can drop all the cdev
operations and use the newly created devfs_create_link_node() with the
same effect.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/misc/storage-by-alias.c | 120 +++-------------------------------------
 1 file changed, 7 insertions(+), 113 deletions(-)

diff --git a/drivers/misc/storage-by-alias.c b/drivers/misc/storage-by-alias.c
index 2c498e0d0483ca71093612382c78372df399c437..6c759867ccbb7a7b4bc922152699eb346d42d271 100644
--- a/drivers/misc/storage-by-alias.c
+++ b/drivers/misc/storage-by-alias.c
@@ -24,102 +24,8 @@ static LIST_HEAD(sba_list);
 struct sba {
 	char *alias;
 	struct device *dev;
-	struct cdev *rcdev;
-	struct cdev cdev;
 	struct list_head list;
-};
-
-static ssize_t sba_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_read(sba->rcdev, buf, count, offset, flags);
-}
-
-static ssize_t sba_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_write(sba->rcdev, buf, count, offset, flags);
-}
-
-static int sba_ioctl(struct cdev *cdev, unsigned int request, void *buf)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_ioctl(sba->rcdev, request, buf);
-}
-
-static int sba_open(struct cdev *cdev, unsigned long flags)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_open(sba->rcdev, flags);
-}
-
-static int sba_close(struct cdev *cdev)
-{
-	struct sba *sba = cdev->priv;
-
-	cdev_close(sba->rcdev);
-
-	return 0;
-}
-
-static int sba_flush(struct cdev *cdev)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_flush(sba->rcdev);
-}
-
-static int sba_erase(struct cdev *cdev, loff_t count, loff_t offset)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_erase(sba->rcdev, count, offset);
-}
-
-static int sba_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_protect(sba->rcdev, count, offset, prot);
-}
-
-static int sba_discard_range(struct cdev *cdev, loff_t count, loff_t offset)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_discard_range(sba->rcdev, count, offset);
-}
-
-static int sba_memmap(struct cdev *cdev, void **map, int flags)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_memmap(sba->rcdev, map, flags);
-}
-
-static int sba_truncate(struct cdev *cdev, size_t size)
-{
-	struct sba *sba = cdev->priv;
-
-	return cdev_truncate(sba->rcdev, size);
-}
-
-static struct cdev_operations sba_ops = {
-	.read = sba_read,
-	.write = sba_write,
-	.ioctl = sba_ioctl,
-	.open = sba_open,
-	.close = sba_close,
-	.flush = sba_flush,
-	.erase = sba_erase,
-	.protect = sba_protect,
-	.discard_range = sba_discard_range,
-	.memmap = sba_memmap,
-	.truncate = sba_truncate,
+	bool populated;
 };
 
 static int sba_add_partitions(struct cdev *rcdev, void *data)
@@ -127,29 +33,17 @@ static int sba_add_partitions(struct cdev *rcdev, void *data)
 	struct sba *sba = data;
 	int ret;
 
-	dev_dbg(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
-
-	if (sba->rcdev)
+	if (sba->populated)
 		return 0;
 
-	sba->rcdev = rcdev;
-	sba->cdev.link = rcdev;
-	sba->cdev.name = sba->alias;
-	sba->cdev.size = rcdev->size;
-	sba->cdev.ops = &sba_ops;
-	sba->cdev.dev = sba->dev;
-	sba->cdev.priv = sba;
+	dev_info(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
 
-	if (rcdev->flags & DEVFS_WRITE_AUTOERASE)
-		sba->cdev.flags |= DEVFS_WRITE_AUTOERASE;
+	ret = devfs_create_link_node(rcdev, sba->alias, sba->dev->device_node);
+	if (ret)
+		return ret;
 
-	ret = devfs_create(&sba->cdev);
-	if (ret) {
-		dev_err(sba->dev, "Failed to create cdev: %pe\n", ERR_PTR(ret));
-		return 0;
-	}
+	sba->populated = true;
 
-	of_parse_partitions(&sba->cdev, sba->dev->of_node);
 	return 0;
 }
 

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 03/13] fs: implement mknod
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
  2025-12-09 12:51 ` [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node() Sascha Hauer
  2025-12-09 12:51 ` [PATCH v2 02/13] storage-by-alias: drop fake cdev Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:19   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 04/13] commands: add mknod command Sascha Hauer
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

This implements mknod for the barebox VFS. Use the cdevname for
connecting a device special node with a cdev. In Linux this is done with
major/minor numbers which shouldn't be necessary for barebox as we do
not intend to mount filesystems which contain device special nodes, but
instead create them in ramfs. If a mounted filesystem contains special
nodes then these won't work with barebox.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/devfs.c         | 13 +++++++++++++
 fs/fs.c            | 35 +++++++++++++++++++++++++++++++++++
 include/fcntl.h    |  6 ++++++
 include/linux/fs.h | 13 +++++++++++++
 4 files changed, 67 insertions(+)

diff --git a/fs/devfs.c b/fs/devfs.c
index 15c7a63d3949a5fa7c5ec15f58bc9f4c53b7852b..be3272be49e66eb843823b3ff664a1565f326790 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -103,6 +103,12 @@ static int devfs_open(struct inode *inode, struct file *f)
 	struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
 	struct cdev *cdev = node->cdev;
 
+	if (inode->cdevname) {
+		cdev = cdev_by_name(inode->cdevname);
+		if (!cdev)
+			return -ENOENT;
+	}
+
 	f->f_size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
 			FILE_SIZE_STREAM : cdev->size;
 	f->private_data = cdev;
@@ -188,6 +194,13 @@ static const struct file_operations devfs_file_operations = {
 	.memmap = devfs_memmap,
 };
 
+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;
diff --git a/fs/fs.c b/fs/fs.c
index d884726187dd526213f8b51a68a2e0db1bb50e58..45bf89653c7c2e4e9546f1d41f79a6389e0b796d 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -826,6 +826,8 @@ static int dentry_delete_subtree(struct super_block *sb, struct dentry *parent)
 
 static void destroy_inode(struct inode *inode)
 {
+	free(inode->cdevname);
+
 	if (inode->i_sb->s_op->destroy_inode)
 		inode->i_sb->s_op->destroy_inode(inode);
 	else
@@ -2747,6 +2749,39 @@ int openat(int dirfd, const char *pathname, int flags)
 }
 EXPORT_SYMBOL(openat);
 
+static int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
+		     const char *cdevname)
+{
+	int error;
+
+	if (!dir->i_op->mknod)
+		return -EPERM;
+
+	error = dir->i_op->mknod(dir, dentry, mode, cdevname);
+
+	return error;
+}
+
+int mknodat(int dirfd, const char *pathname, mode_t mode, const char *devname)
+{
+	struct dentry *dentry;
+	struct path path;
+	int error;
+
+	dentry = filename_create(dirfd, getname(pathname), &path, 0);
+	if (IS_ERR(dentry)) {
+		error = PTR_ERR(dentry);
+		goto out;
+	}
+
+	error = vfs_mknod(path.dentry->d_inode, dentry, mode, devname);
+
+	dput(dentry);
+	path_put(&path);
+out:
+	return errno_set(error);
+}
+
 int unlinkat(int dirfd, const char *pathname, int flags)
 {
 	int ret;
diff --git a/include/fcntl.h b/include/fcntl.h
index db7926ee25fbe14607063d420697964801cd8321..57c01002cc9290bfae53f3b5be5615eda874c720 100644
--- a/include/fcntl.h
+++ b/include/fcntl.h
@@ -46,6 +46,8 @@ static inline int openat(int dirfd, const char *pathname, int flags, ...)
 }
 #endif
 
+int mknodat(int dirfd, const char *pathname, mode_t mode, const char *devname);
+
 static inline int open(const char *pathname, int flags, ...)
 {
 	return openat(AT_FDCWD, pathname, flags);
@@ -56,4 +58,8 @@ static inline int creat(const char *pathname, mode_t mode)
 	return open(pathname, O_CREAT | O_WRONLY | O_TRUNC);
 }
 
+static inline int mknod(const char *pathname, mode_t mode, const char *devname)
+{
+	return mknodat(AT_FDCWD, pathname, mode, devname);
+}
 #endif /* __FCNTL_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index ed4332c79d496b18b37b120b6008e1e474316e76..f6b8f6a8e08b7e56716005453d6f9c4488ba853f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -149,6 +149,8 @@ struct inode {
 
 	char			*i_link;
 
+	char			*cdevname;
+
 	void			*i_private; /* fs or device private pointer */
 };
 
@@ -429,6 +431,16 @@ void ihold(struct inode *inode);
 void inc_nlink(struct inode *inode);
 void clear_nlink(struct inode *inode);
 void set_nlink(struct inode *inode, unsigned int nlink);
+#ifdef CONFIG_FS_DEVFS
+void init_special_inode(struct inode *inode, umode_t mode, const char *cdevname);
+#else
+static inline void init_special_inode(struct inode *inode, umode_t mode,
+				      const char *cdevname)
+{
+}
+#endif
+
+struct cdev;
 
 struct inode_operations {
 	struct dentry * (*lookup) (struct inode *,struct dentry *, unsigned int);
@@ -436,6 +448,7 @@ struct inode_operations {
 	const char *(*get_link) (struct dentry *dentry, struct inode *inode);
 
 	int (*create) (struct inode *,struct dentry *, umode_t);
+	int (*mknod) (struct inode *,struct dentry *, umode_t, const char *name);
 	int (*link) (struct dentry *,struct inode *,struct dentry *);
 	int (*unlink) (struct inode *,struct dentry *);
 	int (*symlink) (struct inode *,struct dentry *,const char *);

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 04/13] commands: add mknod command
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (2 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 03/13] fs: implement mknod Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:21   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 05/13] fs: ramfs: add device file support Sascha Hauer
                   ` (9 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

Add a mknod command. This is intended for testing/debugging purposes as
normally device special nodes are created automatically in devfs.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/Kconfig  |  4 ++++
 commands/Makefile |  1 +
 commands/mknod.c  | 43 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+)

diff --git a/commands/Kconfig b/commands/Kconfig
index c7c03a65477b4f083c256dc55053aab8c8ad2741..6b8e19533dc07b54c41326b84adabb1553bc415d 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -1144,6 +1144,10 @@ config CMD_MKDIR
 	  Options:
 		  -p	make parent directories as needed
 
+config CMD_MKNOD
+	tristate
+	prompt "mknod"
+
 config CMD_PWD
 	tristate
 	default y
diff --git a/commands/Makefile b/commands/Makefile
index 8fffac8fd4428d275f86c5ad9898fed96c5b18ac..356957cab56bd97f80dbac67a3e17c333d4be45c 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -34,6 +34,7 @@ obj-$(CONFIG_CMD_CD)		+= cd.o
 obj-$(CONFIG_CMD_PWD)		+= pwd.o
 obj-$(CONFIG_CMD_MKDIR)		+= mkdir.o
 obj-$(CONFIG_CMD_RMDIR)		+= rmdir.o
+obj-$(CONFIG_CMD_MKNOD)		+= mknod.o
 obj-$(CONFIG_CMD_CP)		+= cp.o
 obj-$(CONFIG_CMD_RM)		+= rm.o
 obj-$(CONFIG_CMD_CAT)		+= cat.o
diff --git a/commands/mknod.c b/commands/mknod.c
new file mode 100644
index 0000000000000000000000000000000000000000..e99078995f995f54ba1d06587fc3d27e09f79e3b
--- /dev/null
+++ b/commands/mknod.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <command.h>
+#include <fs.h>
+
+static int do_mknod(int argc, char *argv[])
+{
+	const char *filename, *cdevname;
+	umode_t mode;
+
+	if (argc < 4)
+		return COMMAND_ERROR_USAGE;
+
+	filename = argv[1];
+	if (!strcmp(argv[2], "b"))
+		mode = S_IFBLK;
+	else if (!strcmp(argv[2], "c"))
+		mode = S_IFCHR;
+	else
+		return COMMAND_ERROR_USAGE;
+
+	cdevname = argv[3];
+
+	return mknod(filename, mode, cdevname);
+}
+
+BAREBOX_CMD_HELP_START(mknod)
+BAREBOX_CMD_HELP_TEXT("make a device special node.")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("usage: mknod <name> c|b <cdevname>")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Create a device special node named <name> directing")
+BAREBOX_CMD_HELP_TEXT("to cdev <cdevname>. This can either be a block (b) or")
+BAREBOX_CMD_HELP_TEXT("character (c) device.")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(mknod)
+        .cmd            = do_mknod,
+        BAREBOX_CMD_DESC("make device nodes")
+        BAREBOX_CMD_OPTS("NAME TYPE CDEVNAME")
+        BAREBOX_CMD_GROUP(CMD_GRP_FILE)
+        BAREBOX_CMD_HELP(cmd_mknod_help)
+BAREBOX_CMD_END

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 05/13] fs: ramfs: add device file support
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (3 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 04/13] commands: add mknod command Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:22   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 06/13] cdev: add cdev_size() helper Sascha Hauer
                   ` (8 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

Implement the mknod hook in ramfs for creating device special files.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/ramfs.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/fs/ramfs.c b/fs/ramfs.c
index 1caace0183a58e8a07001eb6ce9df8ea1895ac0b..d86bf6144e8485269c589ba0024377f9852a8eaa 100644
--- a/fs/ramfs.c
+++ b/fs/ramfs.c
@@ -89,6 +89,9 @@ static struct inode *ramfs_get_inode(struct super_block *sb, const struct inode
 	case S_IFLNK:
 		inode->i_op = &ramfs_symlink_inode_operations;
 		break;
+	case S_IFBLK:
+	case S_IFCHR:
+		break;
 	}
 
 	return inode;
@@ -149,6 +152,20 @@ static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode)
 	return ramfs_mknod(dir, dentry, mode | S_IFREG);
 }
 
+static int __ramfs_mknod(struct inode *dir,struct dentry *dentry, umode_t mode,
+			 const char *cdevname)
+{
+	int ret;
+
+	ret = ramfs_mknod(dir, dentry, mode);
+	if (ret)
+		return ret;
+
+	init_special_inode(dentry->d_inode, mode, cdevname);
+
+	return 0;
+}
+
 static int ramfs_symlink(struct inode *dir, struct dentry *dentry,
 			 const char *symname)
 {
@@ -196,6 +213,7 @@ static const struct inode_operations ramfs_dir_inode_operations =
 	.unlink = simple_unlink,
 	.create = ramfs_create,
 	.tmpfile = ramfs_tmpfile,
+	.mknod = __ramfs_mknod,
 };
 
 static struct ramfs_chunk *ramfs_find_chunk(struct ramfs_inode *node,

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 06/13] cdev: add cdev_size() helper
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (4 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 05/13] fs: ramfs: add device file support Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:22   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 07/13] fs: fix st_size for device files Sascha Hauer
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

We'll need the size of a cdev later, add a helper for retrieving the
size.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/devfs-core.c  | 6 ++++++
 fs/devfs.c       | 3 +--
 include/driver.h | 1 +
 3 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 91082265d1aaa965160de5e414364e3fb14824d1..467aa51c858a8bde6ab4e17cc4c838b989606486 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -435,6 +435,12 @@ int cdev_truncate(struct cdev *cdev, size_t size)
 	return -EPERM;
 }
 
+loff_t cdev_size(struct cdev *cdev)
+{
+	return cdev->flags & DEVFS_IS_CHARACTER_DEV ?
+		FILE_SIZE_STREAM : cdev->size;
+}
+
 static struct cdev *cdev_alloc(const char *name)
 {
 	struct cdev *new;
diff --git a/fs/devfs.c b/fs/devfs.c
index be3272be49e66eb843823b3ff664a1565f326790..a48c6452697b47cbd3ffc6f993230e7993e565fe 100644
--- a/fs/devfs.c
+++ b/fs/devfs.c
@@ -109,8 +109,7 @@ static int devfs_open(struct inode *inode, struct file *f)
 			return -ENOENT;
 	}
 
-	f->f_size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
-			FILE_SIZE_STREAM : cdev->size;
+	f->f_size = cdev_size(cdev);
 	f->private_data = cdev;
 
 	return cdev_open(cdev, f->f_flags);
diff --git a/include/driver.h b/include/driver.h
index e0fddecd085c991db4f1fe34c56405d28b6f53ad..0c7a75b3d5632fdbde65ac52667e3bdee325dcf2 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -526,6 +526,7 @@ int cdev_protect(struct cdev*, size_t count, loff_t offset, int prot);
 int cdev_discard_range(struct cdev*, loff_t count, loff_t offset);
 int cdev_memmap(struct cdev*, void **map, int flags);
 int cdev_truncate(struct cdev*, size_t size);
+loff_t cdev_size(struct cdev *cdev);
 loff_t cdev_unallocated_space(struct cdev *cdev);
 static inline bool cdev_is_partition(const struct cdev *cdev)
 {

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 07/13] fs: fix st_size for device files
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (5 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 06/13] cdev: add cdev_size() helper Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:24   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 08/13] fs: retire devfs as filesystem Sascha Hauer
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

In Linux device special files have zero size, but in barebox the
device files traditionally have the size of the underlying device.
Initialize struct stat::s_size with the cdev size.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/fs/fs.c b/fs/fs.c
index 45bf89653c7c2e4e9546f1d41f79a6389e0b796d..9e2c95c6352cc63400f997bb8de53af44f4741cf 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1100,11 +1100,23 @@ EXPORT_SYMBOL(readdir);
 
 static void stat_inode(struct inode *inode, struct stat *s)
 {
+	if (inode->cdevname) {
+		struct cdev *cdev;
+
+		cdev = cdev_by_name(inode->cdevname);
+		if (cdev) {
+			s->st_size = cdev_size(cdev);
+		} else {
+			s->st_size = 0;
+		}
+	} else {
+		s->st_size = inode->i_size;
+	}
+
 	s->st_ino = inode->i_ino;
 	s->st_mode = inode->i_mode;
 	s->st_uid = inode->i_uid;
 	s->st_gid = inode->i_gid;
-	s->st_size = inode->i_size;
 }
 
 int fstat(int fd, struct stat *s)

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 08/13] fs: retire devfs as filesystem
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (6 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 07/13] fs: fix st_size for device files Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:25   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 09/13] fs: include cdevname in struct stat Sascha Hauer
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

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 467aa51c858a8bde6ab4e17cc4c838b989606486..3a5667b9f723fa718453bdc58827f4b760f3565a 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 0c7a75b3d5632fdbde65ac52667e3bdee325dcf2..802917f1c20727272364d094552e4e5b40a6165b 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_create_link_node(struct cdev *cdev, const char *name,

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 09/13] fs: include cdevname in struct stat
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (7 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 08/13] fs: retire devfs as filesystem Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:25   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 10/13] fs: stat_print: get cdevname from stat Sascha Hauer
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

In Linux struct stat contains the major/minor numbers of the underlying
device, consequently we put the cdev name into struct stat.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c              | 1 +
 include/linux/stat.h | 1 +
 2 files changed, 2 insertions(+)

diff --git a/fs/fs.c b/fs/fs.c
index 9e2c95c6352cc63400f997bb8de53af44f4741cf..9022287dff2f4959f64eac76c544634b3978d238 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -1117,6 +1117,7 @@ static void stat_inode(struct inode *inode, struct stat *s)
 	s->st_mode = inode->i_mode;
 	s->st_uid = inode->i_uid;
 	s->st_gid = inode->i_gid;
+	s->st_cdevname = inode->cdevname;
 }
 
 int fstat(int fd, struct stat *s)
diff --git a/include/linux/stat.h b/include/linux/stat.h
index 6ee05b52873f47e5d17a4387829187512be29ea8..84b6484a1f2149d1f2d770f0f11bf0ae0ef63744 100644
--- a/include/linux/stat.h
+++ b/include/linux/stat.h
@@ -55,6 +55,7 @@ struct stat {
 	unsigned short st_mode;
 	unsigned short st_uid;
 	unsigned short st_gid;
+	const char *st_cdevname; /* barebox specific */
 	loff_t  st_size;
 };
 

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 10/13] fs: stat_print: get cdevname from stat
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (8 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 09/13] fs: include cdevname in struct stat Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:26   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 11/13] common: cdev-alias: rename struct Sascha Hauer
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

In stat_print() we have to take the filename component of the input path
and retrieve the cdev from that name. Now that we have the cdevname in
struct stat we can simplify this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 fs/fs.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)

diff --git a/fs/fs.c b/fs/fs.c
index 9022287dff2f4959f64eac76c544634b3978d238..30fe5db4d2800ebfdc0c44603caea15bdff807aa 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -137,7 +137,6 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
 	struct fs_device *fdev;
 	struct cdev *cdev = NULL;
 	const char *type = NULL, *typeprefix = "";
-	bool is_cdev_link = false;
 	char modestr[11];
 
 	mkmodestr(st->st_mode, modestr);
@@ -152,23 +151,10 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
 		case S_IFREG:    type = "regular file"; break;
 	}
 
-	if (st->st_mode & S_IFCHR) {
-		char *path;
-
-		path = canonicalize_path(dirfd, filename);
-		if (path) {
-			const char *devicefile = devpath_to_name(path);
-			struct cdev *lcdev;
-
-			lcdev = lcdev_by_name(devicefile);
-			cdev = cdev_readlink(lcdev);
-			if (cdev != lcdev)
-				is_cdev_link = true;
-			if (cdev)
-				bdev = cdev_get_block_device(cdev);
-
-			free(path);
-		}
+	if ((st->st_mode & S_IFCHR) && st->st_cdevname) {
+		cdev = cdev_by_name(st->st_cdevname);
+		if (cdev)
+			bdev = cdev_get_block_device(cdev);
 	}
 
 	printf("  File: %s", filename);
@@ -182,9 +168,6 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
 			printf(" -> <readlink error %pe>", ERR_PTR(ret));
 		else
 			printf(" -> %s", realname);
-	} else if (is_cdev_link) {
-		printf(" ~> %s", cdev->name);
-		typeprefix = "cdev link to ";
 	}
 
 	printf("\nSize: ");

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 11/13] common: cdev-alias: rename struct
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (9 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 10/13] fs: stat_print: get cdevname from stat Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:27   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 12/13] fs: replace cdev links with aliases Sascha Hauer
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

We'll introduce a globally available struct cdev_alias in the next step,
so rename struct cdev_alias in common/cdev-alias.c to avoid name
conflicts.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 common/cdev-alias.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/common/cdev-alias.c b/common/cdev-alias.c
index 329ba9e97c16fe7a90d09c0bb31ef3359b72b5d0..e5a059ad7f4d9bc447c44072c5c7744051d12a0e 100644
--- a/common/cdev-alias.c
+++ b/common/cdev-alias.c
@@ -11,13 +11,13 @@
 #include <driver.h>
 #include <init.h>
 
-struct cdev_alias {
+struct cdev_alias_res {
 	const char *name;
-	int (*resolve)(struct cdev_alias *, const char *arg,
+	int (*resolve)(struct cdev_alias_res *, const char *arg,
 		       cdev_alias_processor_t fn, void *data);
 };
 
-static int cdev_alias_resolve_bootsource(struct cdev_alias *cdev_alias,
+static int cdev_alias_resolve_bootsource(struct cdev_alias_res *cdev_alias_res,
 					 const char *partname,
 					 cdev_alias_processor_t fn,
 					 void *data)
@@ -37,7 +37,7 @@ static int cdev_alias_resolve_bootsource(struct cdev_alias *cdev_alias,
 	return fn(cdev, data);
 }
 
-static int cdev_alias_resolve_diskuuid(struct cdev_alias *cdev_alias,
+static int cdev_alias_resolve_diskuuid(struct cdev_alias_res *cdev_alias_res,
 				       const char *uuid,
 				       cdev_alias_processor_t fn,
 				       void *data)
@@ -67,7 +67,7 @@ static int cdev_alias_resolve_diskuuid(struct cdev_alias *cdev_alias,
 	return 0;
 }
 
-static struct cdev_alias cdev_alias_aliases[] = {
+static struct cdev_alias_res cdev_alias_aliases[] = {
 	{ "bootsource", cdev_alias_resolve_bootsource },
 	{ "diskuuid", cdev_alias_resolve_diskuuid },
 	{ /* sentinel */}
@@ -76,7 +76,7 @@ static struct cdev_alias cdev_alias_aliases[] = {
 int cdev_alias_resolve_for_each(const char *name,
 				cdev_alias_processor_t fn, void *data)
 {
-	struct cdev_alias *alias;
+	struct cdev_alias_res *alias;
 	int ret = 0;
 	char *buf, *arg;
 

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 12/13] fs: replace cdev links with aliases
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (10 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 11/13] common: cdev-alias: rename struct Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:31   ` Ahmad Fatoum
  2025-12-09 12:51 ` [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM Sascha Hauer
  2025-12-15 12:16 ` [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/devinfo.c              |   7 +-
 common/partitions.c             |   2 +-
 drivers/block/dm/dm-core.c      |   1 -
 drivers/misc/storage-by-alias.c |   2 +-
 fs/devfs-core.c                 | 191 +++++++++++++++++++++-------------------
 include/block.h                 |   2 -
 include/driver.h                |  20 +++--
 7 files changed, 121 insertions(+), 104 deletions(-)

diff --git a/commands/devinfo.c b/commands/devinfo.c
index c87b30e84307e5053bc35e8bd70ac7af63f688b8..c5417cb7bbe9c7beacd85888fb34405bdc279aea 100644
--- a/commands/devinfo.c
+++ b/commands/devinfo.c
@@ -9,7 +9,8 @@
 static int do_devinfo_subtree(struct device *dev, int depth)
 {
 	struct device *child;
-	struct cdev *cdev, *cdevl;
+	struct cdev *cdev;
+	struct cdev_alias *alias;
 	int i;
 
 	for (i = 0; i < depth; i++)
@@ -26,8 +27,8 @@ static int do_devinfo_subtree(struct device *dev, int depth)
 					cdev->offset + cdev->size - 1,
 					size_human_readable(cdev->size),
 					cdev->name);
-			list_for_each_entry(cdevl, &cdev->links, link_entry)
-				printf(", %s", cdevl->name);
+			cdev_for_each_alias(alias, cdev)
+				printf(", %s", alias->name);
 			printf("\n");
 		}
 	} else {
diff --git a/common/partitions.c b/common/partitions.c
index 7563cb0e6767891ee7f1fe264ce86703408f790a..1a4e046c5f55314ccb2abf5094b0966def8c5b55 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -63,7 +63,7 @@ static int register_one_partition(struct block_device *blk, struct partition *pa
 		return 0;
 
 	partition_name = xasprintf("%s.%s", blk->cdev.name, part->name);
-	ret = devfs_create_link(cdev, partition_name);
+	ret = devfs_add_alias(cdev, partition_name);
 	if (ret)
 		dev_warn(blk->dev, "Failed to create link from %s to %s\n",
 			 partition_name, cdev->name);
diff --git a/drivers/block/dm/dm-core.c b/drivers/block/dm/dm-core.c
index fd7ed0d84ed7388f8c1cd4aa19e0466191459fd6..2f48cfeb06f7b2da6d26850820f228a6f522fc2f 100644
--- a/drivers/block/dm/dm-core.c
+++ b/drivers/block/dm/dm-core.c
@@ -77,7 +77,6 @@ int dm_cdev_open(struct dm_cdev *dmcdev, const char *path, ulong flags,
 			return -ENODEV;
 		}
 
-		dmcdev->cdev = cdev_readlink(dmcdev->cdev);
 		break;
 	default:
 		*errmsg = xstrdup("Only regular files and device specials are supported");
diff --git a/drivers/misc/storage-by-alias.c b/drivers/misc/storage-by-alias.c
index 6c759867ccbb7a7b4bc922152699eb346d42d271..196346c8eafcc7868aa279353414409617e1e907 100644
--- a/drivers/misc/storage-by-alias.c
+++ b/drivers/misc/storage-by-alias.c
@@ -38,7 +38,7 @@ static int sba_add_partitions(struct cdev *rcdev, void *data)
 
 	dev_info(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
 
-	ret = devfs_create_link_node(rcdev, sba->alias, sba->dev->device_node);
+	ret = devfs_add_alias_node(rcdev, sba->alias, sba->dev->device_node);
 	if (ret)
 		return ret;
 
diff --git a/fs/devfs-core.c b/fs/devfs-core.c
index 3a5667b9f723fa718453bdc58827f4b760f3565a..b285b7ede029b14bb0bbc1dbf60ba8a8895c3f26 100644
--- a/fs/devfs-core.c
+++ b/fs/devfs-core.c
@@ -50,42 +50,21 @@ int devfs_partition_complete(struct string_list *sl, char *instr)
 }
 #endif
 
-struct cdev *cdev_readlink(const struct cdev *cdev)
-{
-	if (!cdev)
-		return NULL;
-
-	if (cdev->link)
-		cdev = cdev->link;
-
-	/* links to links are not allowed */
-	BUG_ON(cdev->link);
-
-	return (void *)cdev;
-}
-
-struct cdev *lcdev_by_name(const char *filename)
+struct cdev *cdev_by_name(const char *filename)
 {
 	struct cdev *cdev;
+	struct cdev_alias *alias;
 
 	for_each_cdev(cdev) {
 		if (!strcmp(cdev->name, filename))
 			return cdev;
+		cdev_for_each_alias(alias, cdev)
+			if (!strcmp(alias->name, filename))
+				return cdev;
 	}
 	return NULL;
 }
 
-struct cdev *cdev_by_name(const char *filename)
-{
-	struct cdev *cdev;
-
-	cdev = lcdev_by_name(filename);
-	if (!cdev)
-		return NULL;
-
-	return cdev_readlink(cdev);
-}
-
 struct cdev *cdev_by_device_node(struct device_node *node)
 {
 	struct cdev *cdev;
@@ -94,8 +73,14 @@ struct cdev *cdev_by_device_node(struct device_node *node)
 		return NULL;
 
 	for_each_cdev(cdev) {
+		struct cdev_alias *alias;
+
 		if (cdev_of_node(cdev) == node)
-			return cdev_readlink(cdev);
+			return cdev;
+
+		cdev_for_each_alias(alias, cdev)
+			if (alias->device_node == node)
+				return cdev;
 	}
 	return NULL;
 }
@@ -133,9 +118,6 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
 {
 	struct cdev *partcdev;
 
-        /* Follow links to support storage-by-alias */
-        cdev = cdev_readlink(cdev);
-
 	if (!cdev_is_gpt_partitioned(cdev))
 		return ERR_PTR(-EINVAL);
 
@@ -153,6 +135,29 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
 	return ERR_PTR(-ENOENT);
 }
 
+static bool cdev_has_partname_alias(struct cdev *cdev, const char *partname)
+{
+	char *fullname;
+	struct cdev_alias *alias;
+	bool ret = false;
+
+	if (!cdev->master)
+		return false;
+
+	fullname = xasprintf("%s.%s", cdev->master->name, partname);
+
+	cdev_for_each_alias(alias, cdev) {
+		if (streq_ptr(alias->name, fullname)) {
+			ret = true;
+			break;
+		}
+	}
+
+	free(fullname);
+
+	return ret;
+}
+
 /**
  * cdev_find_partition - find a partition belonging to a physical device
  *
@@ -164,15 +169,10 @@ struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name)
 	struct cdev *partcdev;
 
 	for_each_cdev_partition(partcdev, cdevm) {
-		struct cdev *cdevl;
-
 		if (streq_ptr(partcdev->partname, name))
 			return partcdev;
-
-		list_for_each_entry(cdevl, &partcdev->links, link_entry) {
-			if (streq_ptr(cdevl->partname, name))
-				return cdevl;
-		}
+		if (cdev_has_partname_alias(partcdev, name))
+			return partcdev;
 	}
 
 	return NULL;
@@ -190,15 +190,11 @@ struct cdev *device_find_partition(struct device *dev, const char *name)
 	struct device *child;
 
 	list_for_each_entry(cdev, &dev->cdevs, devices_list) {
-		struct cdev *cdevl;
-
 		if (streq_ptr(cdev->partname, name))
 			return cdev;
 
-		list_for_each_entry(cdevl, &cdev->links, link_entry) {
-			if (streq_ptr(cdevl->partname, name))
-				return cdev_readlink(cdevl);
-		}
+		if (cdev_has_partname_alias(cdev, name))
+			return cdev;
 	}
 
 	device_for_each_child(dev, child) {
@@ -460,25 +456,54 @@ static void cdev_free(struct cdev *cdev)
 
 static bool devfs_initialized;
 
+static int cdev_symlink(struct cdev *cdev, const char *linkname)
+{
+	char *path;
+	int ret;
+
+	if (!devfs_initialized)
+		return 0;
+
+	path = xasprintf("/dev/%s", linkname);
+	ret = symlink(cdev->name, path);
+	free(path);
+
+	return ret;
+}
+
 static void devfs_mknod(struct cdev *cdev)
 {
 	char *path;
 	int ret;
+	struct cdev_alias *alias;
 
 	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);
+	cdev_for_each_alias(alias, cdev)
+		cdev_symlink(cdev, alias->name);
+
+	ret = mknod(path, S_IFCHR | 0600, cdev->name);
 
 	free(path);
 
-	if (ret)
+	if (ret) {
 		pr_err("Failed to create /dev/%s: %pe\n", cdev->name, ERR_PTR(ret));
+		dump_stack();
+	}
+}
+
+static void devfs_unlink(const char *name)
+{
+	char *path;
+
+	path = xasprintf("/dev/%s", name);
+
+	unlink(path);
+
+	free(path);
 }
 
 void devfs_init(void)
@@ -499,8 +524,8 @@ int devfs_create(struct cdev *new)
 	if (cdev)
 		return -EEXIST;
 
-	INIT_LIST_HEAD(&new->links);
 	INIT_LIST_HEAD(&new->partitions);
+	INIT_LIST_HEAD(&new->aliases);
 
 	list_add_tail(&new->list, &cdev_list);
 	if (new->dev) {
@@ -509,54 +534,44 @@ int devfs_create(struct cdev *new)
 			new->device_node = new->dev->of_node;
 	}
 
-	if (new->link)
-		list_add_tail(&new->link_entry, &new->link->links);
-
 	devfs_mknod(new);
 
 	return 0;
 }
 
-int devfs_create_link_node(struct cdev *cdev, const char *name, struct device_node *node)
+int devfs_add_alias_node(struct cdev *cdev, const char *name, struct device_node *np)
 {
-	struct cdev *new;
-	int ret;
-
-	/*
-	 * Create a link to the real cdev instead of creating
-	 * a link to a link.
-	 */
-	cdev = cdev_readlink(cdev);
-
-	new = cdev_alloc(name);
-	new->link = cdev;
-	new->device_node = node;
-
-	ret = devfs_create(new);
-	if (ret) {
-		cdev_free(new);
-		return ret;
-	}
-
-	if (cdev->partname) {
-		size_t partnameoff = 0;
+	struct cdev *conflict;
+	struct cdev_alias *alias;
 
-		if (cdev->master) {
-			size_t masterlen = strlen(cdev->master->name);
+	conflict = cdev_by_name(name);
+	if (conflict)
+		return -EEXIST;
 
-			if (!strncmp(name, cdev->master->name, masterlen))
-				partnameoff += masterlen + 1;
-		}
+	alias = xzalloc(sizeof(*alias));
+	alias->name = xstrdup(name);
+	alias->device_node = np;
+	list_add_tail(&alias->list, &cdev->aliases);
 
-		new->partname = xstrdup(name + partnameoff);
-	}
+	cdev_symlink(cdev, name);
 
 	return 0;
 }
 
-int devfs_create_link(struct cdev *cdev, const char *name)
+int devfs_add_alias(struct cdev *cdev, const char *name)
+{
+	return devfs_add_alias_node(cdev, name, NULL);
+}
+
+static void devfs_remove_aliases(struct cdev *cdev)
 {
-	return devfs_create_link_node(cdev, name, NULL);
+	struct cdev_alias *alias, *tmp;
+
+	list_for_each_entry_safe(alias, tmp, &cdev->aliases, list) {
+		devfs_unlink(alias->name);
+		free(alias->name);
+		free(alias);
+	}
 }
 
 int devfs_remove(struct cdev *cdev)
@@ -571,8 +586,9 @@ int devfs_remove(struct cdev *cdev)
 	if (cdev->dev)
 		list_del(&cdev->devices_list);
 
-	list_for_each_entry_safe(c, tmp, &cdev->links, link_entry)
-		devfs_remove(c);
+	devfs_unlink(cdev->name);
+
+	devfs_remove_aliases(cdev);
 
 	list_for_each_entry_safe(c, tmp, &cdev->partitions, partition_entry)
 		cdevfs_del_partition(c);
@@ -580,9 +596,6 @@ int devfs_remove(struct cdev *cdev)
 	if (cdev_is_partition(cdev))
 		list_del(&cdev->partition_entry);
 
-	if (cdev->link)
-		cdev_free(cdev);
-
 	return 0;
 }
 
@@ -687,7 +700,7 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
 	if (overlap) {
 		if (!IS_ERR(overlap)) {
 			/* only fails with -EEXIST, which is fine */
-			(void)devfs_create_link(overlap, partinfo->name);
+			(void)devfs_add_alias(overlap, partinfo->name);
 		}
 
 		return overlap;
diff --git a/include/block.h b/include/block.h
index fc7a0a32fb2d6bc579aa6305433fb2a9e39f336a..a8ebe202288fff83677948f3d67bc12cae5dc107 100644
--- a/include/block.h
+++ b/include/block.h
@@ -104,13 +104,11 @@ static inline bool cdev_is_block_device(const struct cdev *cdev)
 
 static inline bool cdev_is_block_partition(const struct cdev *cdev)
 {
-	cdev = cdev_readlink(cdev);
 	return cdev_is_block_device(cdev) && cdev_is_partition(cdev);
 }
 
 static inline bool cdev_is_block_disk(const struct cdev *cdev)
 {
-	cdev = cdev_readlink(cdev);
 	return cdev_is_block_device(cdev) && !cdev_is_partition(cdev);
 }
 
diff --git a/include/driver.h b/include/driver.h
index 802917f1c20727272364d094552e4e5b40a6165b..1c78f35f7eb960ac231ee6ad20db8a2a7cbb6a19 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -17,6 +17,7 @@
 #include <init.h>
 #include <errno.h>
 #include <filetype.h>
+#include <stringlist.h>
 
 #define FORMAT_DRIVER_NAME_ID	"%s%d"
 
@@ -432,8 +433,7 @@ struct cdev {
 	u16 typeflags; /* GPT type-specific attributes */
 	int open;
 	struct mtd_info *mtd;
-	struct cdev *link;
-	struct list_head link_entry, links;
+	struct list_head aliases;
 	struct list_head partition_entry, partitions;
 	struct cdev *master;
 	enum filetype filetype;
@@ -443,6 +443,15 @@ struct cdev {
 	};
 };
 
+#define cdev_for_each_alias(alias, cdev) \
+	list_for_each_entry(alias, &cdev->aliases, list)
+
+struct cdev_alias {
+	char *name;
+	struct device_node *device_node;
+	struct list_head list;
+};
+
 static inline struct device_node *cdev_of_node(const struct cdev *cdev)
 {
 	return IS_ENABLED(CONFIG_OFDEVICE) ? cdev->device_node : NULL;
@@ -461,15 +470,12 @@ static inline const char *cdev_name(struct cdev *cdev)
 
 void devfs_init(void);
 int devfs_create(struct cdev *);
-int devfs_create_link(struct cdev *, const char *name);
-int devfs_create_link_node(struct cdev *cdev, const char *name,
-			   struct device_node *node);
+int devfs_add_alias(struct cdev *, const char *name);
+int devfs_add_alias_node(struct cdev *, const char *name, struct device_node *np);
 int devfs_remove(struct cdev *);
 int cdev_find_free_index(const char *);
 struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name);
 struct cdev *device_find_partition(struct device *dev, const char *name);
-struct cdev *lcdev_by_name(const char *filename);
-struct cdev *cdev_readlink(const struct cdev *cdev);
 struct cdev *cdev_by_device_node(struct device_node *node);
 struct cdev *cdev_by_partuuid(const char *partuuid);
 struct cdev *cdev_by_diskuuid(const char *partuuid);

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (11 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 12/13] fs: replace cdev links with aliases Sascha Hauer
@ 2025-12-09 12:51 ` Sascha Hauer
  2025-12-15 11:32   ` Ahmad Fatoum
  2025-12-15 12:16 ` [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
  13 siblings, 1 reply; 29+ messages in thread
From: Sascha Hauer @ 2025-12-09 12:51 UTC (permalink / raw)
  To: BAREBOX

For stream size files we used to show ((loff_t) -1) as file size which
is quite unreadable. Use ~0 in this case.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 commands/ls.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/commands/ls.c b/commands/ls.c
index 1ccd44f7bbc00a03b773b56020a7117ce94b24cd..5c9e0f738b03ae36655b04ec1037811a4abc0423 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -33,8 +33,12 @@ static void ls_one(const char *path, const char* fullname)
 		return;
 
 	mkmodestr(s.st_mode, modestr);
-	printf("%s %*llu %*.*s", modestr, SIZELEN, s.st_size, namelen,
-	       namelen, path);
+	if (s.st_size == FILE_SIZE_STREAM)
+		printf("%s %*s %*.*s", modestr, SIZELEN, "~0", namelen,
+		       namelen, path);
+	else
+		printf("%s %*llu %*.*s", modestr, SIZELEN, s.st_size, namelen,
+			namelen, path);
 
 	if (S_ISLNK(s.st_mode)) {
 		char realname[PATH_MAX];

-- 
2.47.3




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node()
  2025-12-09 12:51 ` [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node() Sascha Hauer
@ 2025-12-15 11:14   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:14 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> Allow to create a devfs link that not only has its own name, but also
> its own device_node.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/devfs-core.c  | 8 +++++++-
>  include/driver.h | 2 ++
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/devfs-core.c b/fs/devfs-core.c
> index 92e7c5823ed0d3a4c54cc7b2b1c9bf32ac535907..91082265d1aaa965160de5e414364e3fb14824d1 100644
> --- a/fs/devfs-core.c
> +++ b/fs/devfs-core.c
> @@ -476,7 +476,7 @@ int devfs_create(struct cdev *new)
>  	return 0;
>  }
>  
> -int devfs_create_link(struct cdev *cdev, const char *name)
> +int devfs_create_link_node(struct cdev *cdev, const char *name, struct device_node *node)
>  {
>  	struct cdev *new;
>  	int ret;
> @@ -489,6 +489,7 @@ int devfs_create_link(struct cdev *cdev, const char *name)
>  
>  	new = cdev_alloc(name);
>  	new->link = cdev;
> +	new->device_node = node;
>  
>  	ret = devfs_create(new);
>  	if (ret) {
> @@ -512,6 +513,11 @@ int devfs_create_link(struct cdev *cdev, const char *name)
>  	return 0;
>  }
>  
> +int devfs_create_link(struct cdev *cdev, const char *name)
> +{
> +	return devfs_create_link_node(cdev, name, NULL);
> +}
> +
>  int devfs_remove(struct cdev *cdev)
>  {
>  	struct cdev *c, *tmp;
> diff --git a/include/driver.h b/include/driver.h
> index c130a3cd63fd5e6dc365a33c765a22dc4e2ca90a..e0fddecd085c991db4f1fe34c56405d28b6f53ad 100644
> --- a/include/driver.h
> +++ b/include/driver.h
> @@ -461,6 +461,8 @@ static inline const char *cdev_name(struct cdev *cdev)
>  
>  int devfs_create(struct cdev *);
>  int devfs_create_link(struct cdev *, const char *name);
> +int devfs_create_link_node(struct cdev *cdev, const char *name,
> +			   struct device_node *node);
>  int devfs_remove(struct cdev *);
>  int cdev_find_free_index(const char *);
>  struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name);
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 02/13] storage-by-alias: drop fake cdev
  2025-12-09 12:51 ` [PATCH v2 02/13] storage-by-alias: drop fake cdev Sascha Hauer
@ 2025-12-15 11:15   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:15 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> storage-by-alias creates its own cdev, but that is never used. The only
> purpose is to create a cdev with its own device node which otherwise
> links to the original cdev. This means we can drop all the cdev
> operations and use the newly created devfs_create_link_node() with the
> same effect.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  drivers/misc/storage-by-alias.c | 120 +++-------------------------------------
>  1 file changed, 7 insertions(+), 113 deletions(-)
> 
> diff --git a/drivers/misc/storage-by-alias.c b/drivers/misc/storage-by-alias.c
> index 2c498e0d0483ca71093612382c78372df399c437..6c759867ccbb7a7b4bc922152699eb346d42d271 100644
> --- a/drivers/misc/storage-by-alias.c
> +++ b/drivers/misc/storage-by-alias.c
> @@ -24,102 +24,8 @@ static LIST_HEAD(sba_list);
>  struct sba {
>  	char *alias;
>  	struct device *dev;
> -	struct cdev *rcdev;
> -	struct cdev cdev;
>  	struct list_head list;
> -};
> -
> -static ssize_t sba_read(struct cdev *cdev, void *buf, size_t count, loff_t offset, ulong flags)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_read(sba->rcdev, buf, count, offset, flags);
> -}
> -
> -static ssize_t sba_write(struct cdev *cdev, const void *buf, size_t count, loff_t offset, ulong flags)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_write(sba->rcdev, buf, count, offset, flags);
> -}
> -
> -static int sba_ioctl(struct cdev *cdev, unsigned int request, void *buf)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_ioctl(sba->rcdev, request, buf);
> -}
> -
> -static int sba_open(struct cdev *cdev, unsigned long flags)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_open(sba->rcdev, flags);
> -}
> -
> -static int sba_close(struct cdev *cdev)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	cdev_close(sba->rcdev);
> -
> -	return 0;
> -}
> -
> -static int sba_flush(struct cdev *cdev)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_flush(sba->rcdev);
> -}
> -
> -static int sba_erase(struct cdev *cdev, loff_t count, loff_t offset)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_erase(sba->rcdev, count, offset);
> -}
> -
> -static int sba_protect(struct cdev *cdev, size_t count, loff_t offset, int prot)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_protect(sba->rcdev, count, offset, prot);
> -}
> -
> -static int sba_discard_range(struct cdev *cdev, loff_t count, loff_t offset)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_discard_range(sba->rcdev, count, offset);
> -}
> -
> -static int sba_memmap(struct cdev *cdev, void **map, int flags)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_memmap(sba->rcdev, map, flags);
> -}
> -
> -static int sba_truncate(struct cdev *cdev, size_t size)
> -{
> -	struct sba *sba = cdev->priv;
> -
> -	return cdev_truncate(sba->rcdev, size);
> -}
> -
> -static struct cdev_operations sba_ops = {
> -	.read = sba_read,
> -	.write = sba_write,
> -	.ioctl = sba_ioctl,
> -	.open = sba_open,
> -	.close = sba_close,
> -	.flush = sba_flush,
> -	.erase = sba_erase,
> -	.protect = sba_protect,
> -	.discard_range = sba_discard_range,
> -	.memmap = sba_memmap,
> -	.truncate = sba_truncate,
> +	bool populated;
>  };
>  
>  static int sba_add_partitions(struct cdev *rcdev, void *data)
> @@ -127,29 +33,17 @@ static int sba_add_partitions(struct cdev *rcdev, void *data)
>  	struct sba *sba = data;
>  	int ret;
>  
> -	dev_dbg(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
> -
> -	if (sba->rcdev)
> +	if (sba->populated)
>  		return 0;
>  
> -	sba->rcdev = rcdev;
> -	sba->cdev.link = rcdev;
> -	sba->cdev.name = sba->alias;
> -	sba->cdev.size = rcdev->size;
> -	sba->cdev.ops = &sba_ops;
> -	sba->cdev.dev = sba->dev;
> -	sba->cdev.priv = sba;
> +	dev_info(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
>  
> -	if (rcdev->flags & DEVFS_WRITE_AUTOERASE)
> -		sba->cdev.flags |= DEVFS_WRITE_AUTOERASE;
> +	ret = devfs_create_link_node(rcdev, sba->alias, sba->dev->device_node);
> +	if (ret)
> +		return ret;
>  
> -	ret = devfs_create(&sba->cdev);
> -	if (ret) {
> -		dev_err(sba->dev, "Failed to create cdev: %pe\n", ERR_PTR(ret));
> -		return 0;
> -	}
> +	sba->populated = true;
>  
> -	of_parse_partitions(&sba->cdev, sba->dev->of_node);
>  	return 0;
>  }
>  
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 03/13] fs: implement mknod
  2025-12-09 12:51 ` [PATCH v2 03/13] fs: implement mknod Sascha Hauer
@ 2025-12-15 11:19   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:19 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> This implements mknod for the barebox VFS. Use the cdevname for
> connecting a device special node with a cdev. In Linux this is done with
> major/minor numbers which shouldn't be necessary for barebox as we do
> not intend to mount filesystems which contain device special nodes, but
> instead create them in ramfs. If a mounted filesystem contains special
> nodes then these won't work with barebox.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

With two minor points below addressed:

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/devfs.c         | 13 +++++++++++++
>  fs/fs.c            | 35 +++++++++++++++++++++++++++++++++++
>  include/fcntl.h    |  6 ++++++
>  include/linux/fs.h | 13 +++++++++++++
>  4 files changed, 67 insertions(+)
> 
> diff --git a/fs/devfs.c b/fs/devfs.c
> index 15c7a63d3949a5fa7c5ec15f58bc9f4c53b7852b..be3272be49e66eb843823b3ff664a1565f326790 100644
> --- a/fs/devfs.c
> +++ b/fs/devfs.c
> @@ -103,6 +103,12 @@ static int devfs_open(struct inode *inode, struct file *f)
>  	struct devfs_inode *node = container_of(inode, struct devfs_inode, inode);
>  	struct cdev *cdev = node->cdev;
>  
> +	if (inode->cdevname) {
> +		cdev = cdev_by_name(inode->cdevname);
> +		if (!cdev)
> +			return -ENOENT;
> +	}
> +
>  	f->f_size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
>  			FILE_SIZE_STREAM : cdev->size;
>  	f->private_data = cdev;
> @@ -188,6 +194,13 @@ static const struct file_operations devfs_file_operations = {
>  	.memmap = devfs_memmap,
>  };
>  
> +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);

xstrdup_const? or return an error?

> +}
> +
>  static int devfs_lookup_revalidate(struct dentry *dentry, unsigned int flags)
>  {
>  	struct devfs_inode *dinode;
> diff --git a/fs/fs.c b/fs/fs.c
> index d884726187dd526213f8b51a68a2e0db1bb50e58..45bf89653c7c2e4e9546f1d41f79a6389e0b796d 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -826,6 +826,8 @@ static int dentry_delete_subtree(struct super_block *sb, struct dentry *parent)
>  
>  static void destroy_inode(struct inode *inode)
>  {
> +	free(inode->cdevname);

free_const?

Cheers,
Ahmad

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 04/13] commands: add mknod command
  2025-12-09 12:51 ` [PATCH v2 04/13] commands: add mknod command Sascha Hauer
@ 2025-12-15 11:21   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:21 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX

Hi,

On 12/9/25 1:51 PM, Sascha Hauer wrote:
> Add a mknod command. This is intended for testing/debugging purposes as
> normally device special nodes are created automatically in devfs.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

Single nitpick below:

> +static int do_mknod(int argc, char *argv[])
> +{
> +	const char *filename, *cdevname;
> +	umode_t mode;
> +
> +	if (argc < 4)

argc != 4 to reduce misuse.

> +		return COMMAND_ERROR_USAGE;
> +
> +	filename = argv[1];
> +	if (!strcmp(argv[2], "b"))
> +		mode = S_IFBLK;
> +	else if (!strcmp(argv[2], "c"))
> +		mode = S_IFCHR;
> +	else
> +		return COMMAND_ERROR_USAGE;
> +
> +	cdevname = argv[3];
> +
> +	return mknod(filename, mode, cdevname);
> +}
> +
> +BAREBOX_CMD_HELP_START(mknod)
> +BAREBOX_CMD_HELP_TEXT("make a device special node.")
> +BAREBOX_CMD_HELP_TEXT("")
> +BAREBOX_CMD_HELP_TEXT("usage: mknod <name> c|b <cdevname>")
> +BAREBOX_CMD_HELP_TEXT("")
> +BAREBOX_CMD_HELP_TEXT("Create a device special node named <name> directing")
> +BAREBOX_CMD_HELP_TEXT("to cdev <cdevname>. This can either be a block (b) or")
> +BAREBOX_CMD_HELP_TEXT("character (c) device.")
> +BAREBOX_CMD_HELP_END
> +
> +BAREBOX_CMD_START(mknod)
> +        .cmd            = do_mknod,
> +        BAREBOX_CMD_DESC("make device nodes")
> +        BAREBOX_CMD_OPTS("NAME TYPE CDEVNAME")
> +        BAREBOX_CMD_GROUP(CMD_GRP_FILE)
> +        BAREBOX_CMD_HELP(cmd_mknod_help)
> +BAREBOX_CMD_END
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 05/13] fs: ramfs: add device file support
  2025-12-09 12:51 ` [PATCH v2 05/13] fs: ramfs: add device file support Sascha Hauer
@ 2025-12-15 11:22   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:22 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX

Hi,

On 12/9/25 1:51 PM, Sascha Hauer wrote:
> Implement the mknod hook in ramfs for creating device special files.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/ramfs.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/fs/ramfs.c b/fs/ramfs.c
> index 1caace0183a58e8a07001eb6ce9df8ea1895ac0b..d86bf6144e8485269c589ba0024377f9852a8eaa 100644
> --- a/fs/ramfs.c
> +++ b/fs/ramfs.c
> @@ -89,6 +89,9 @@ static struct inode *ramfs_get_inode(struct super_block *sb, const struct inode
>  	case S_IFLNK:
>  		inode->i_op = &ramfs_symlink_inode_operations;
>  		break;
> +	case S_IFBLK:
> +	case S_IFCHR:
> +		break;
>  	}
>  
>  	return inode;
> @@ -149,6 +152,20 @@ static int ramfs_create(struct inode *dir, struct dentry *dentry, umode_t mode)
>  	return ramfs_mknod(dir, dentry, mode | S_IFREG);
>  }
>  
> +static int __ramfs_mknod(struct inode *dir,struct dentry *dentry, umode_t mode,
> +			 const char *cdevname)
> +{
> +	int ret;
> +
> +	ret = ramfs_mknod(dir, dentry, mode);
> +	if (ret)
> +		return ret;
> +
> +	init_special_inode(dentry->d_inode, mode, cdevname);
> +
> +	return 0;
> +}
> +
>  static int ramfs_symlink(struct inode *dir, struct dentry *dentry,
>  			 const char *symname)
>  {
> @@ -196,6 +213,7 @@ static const struct inode_operations ramfs_dir_inode_operations =
>  	.unlink = simple_unlink,
>  	.create = ramfs_create,
>  	.tmpfile = ramfs_tmpfile,
> +	.mknod = __ramfs_mknod,
>  };
>  
>  static struct ramfs_chunk *ramfs_find_chunk(struct ramfs_inode *node,
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 06/13] cdev: add cdev_size() helper
  2025-12-09 12:51 ` [PATCH v2 06/13] cdev: add cdev_size() helper Sascha Hauer
@ 2025-12-15 11:22   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:22 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> We'll need the size of a cdev later, add a helper for retrieving the
> size.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/devfs-core.c  | 6 ++++++
>  fs/devfs.c       | 3 +--
>  include/driver.h | 1 +
>  3 files changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/devfs-core.c b/fs/devfs-core.c
> index 91082265d1aaa965160de5e414364e3fb14824d1..467aa51c858a8bde6ab4e17cc4c838b989606486 100644
> --- a/fs/devfs-core.c
> +++ b/fs/devfs-core.c
> @@ -435,6 +435,12 @@ int cdev_truncate(struct cdev *cdev, size_t size)
>  	return -EPERM;
>  }
>  
> +loff_t cdev_size(struct cdev *cdev)
> +{
> +	return cdev->flags & DEVFS_IS_CHARACTER_DEV ?
> +		FILE_SIZE_STREAM : cdev->size;
> +}
> +
>  static struct cdev *cdev_alloc(const char *name)
>  {
>  	struct cdev *new;
> diff --git a/fs/devfs.c b/fs/devfs.c
> index be3272be49e66eb843823b3ff664a1565f326790..a48c6452697b47cbd3ffc6f993230e7993e565fe 100644
> --- a/fs/devfs.c
> +++ b/fs/devfs.c
> @@ -109,8 +109,7 @@ static int devfs_open(struct inode *inode, struct file *f)
>  			return -ENOENT;
>  	}
>  
> -	f->f_size = cdev->flags & DEVFS_IS_CHARACTER_DEV ?
> -			FILE_SIZE_STREAM : cdev->size;
> +	f->f_size = cdev_size(cdev);
>  	f->private_data = cdev;
>  
>  	return cdev_open(cdev, f->f_flags);
> diff --git a/include/driver.h b/include/driver.h
> index e0fddecd085c991db4f1fe34c56405d28b6f53ad..0c7a75b3d5632fdbde65ac52667e3bdee325dcf2 100644
> --- a/include/driver.h
> +++ b/include/driver.h
> @@ -526,6 +526,7 @@ int cdev_protect(struct cdev*, size_t count, loff_t offset, int prot);
>  int cdev_discard_range(struct cdev*, loff_t count, loff_t offset);
>  int cdev_memmap(struct cdev*, void **map, int flags);
>  int cdev_truncate(struct cdev*, size_t size);
> +loff_t cdev_size(struct cdev *cdev);
>  loff_t cdev_unallocated_space(struct cdev *cdev);
>  static inline bool cdev_is_partition(const struct cdev *cdev)
>  {
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 07/13] fs: fix st_size for device files
  2025-12-09 12:51 ` [PATCH v2 07/13] fs: fix st_size for device files Sascha Hauer
@ 2025-12-15 11:24   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:24 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX

On 12/9/25 1:51 PM, Sascha Hauer wrote:
> In Linux device special files have zero size, but in barebox the
> device files traditionally have the size of the underlying device.
> Initialize struct stat::s_size with the cdev size.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

Single nitpick below:

> ---
>  fs/fs.c | 14 +++++++++++++-
>  1 file changed, 13 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/fs.c b/fs/fs.c
> index 45bf89653c7c2e4e9546f1d41f79a6389e0b796d..9e2c95c6352cc63400f997bb8de53af44f4741cf 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -1100,11 +1100,23 @@ EXPORT_SYMBOL(readdir);
>  
>  static void stat_inode(struct inode *inode, struct stat *s)
>  {
> +	if (inode->cdevname) {
> +		struct cdev *cdev;
> +
> +		cdev = cdev_by_name(inode->cdevname);
> +		if (cdev) {
> +			s->st_size = cdev_size(cdev);
> +		} else {
> +			s->st_size = 0;
> +		}

s->st_size = cdev ? cdev_size(cdev) : 0;

> +	} else {
> +		s->st_size = inode->i_size;
> +	}
> +
>  	s->st_ino = inode->i_ino;
>  	s->st_mode = inode->i_mode;
>  	s->st_uid = inode->i_uid;
>  	s->st_gid = inode->i_gid;
> -	s->st_size = inode->i_size;
>  }
>  
>  int fstat(int fd, struct stat *s)
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 08/13] fs: retire devfs as filesystem
  2025-12-09 12:51 ` [PATCH v2 08/13] fs: retire devfs as filesystem Sascha Hauer
@ 2025-12-15 11:25   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:25 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> 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>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> +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);

\o/

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 09/13] fs: include cdevname in struct stat
  2025-12-09 12:51 ` [PATCH v2 09/13] fs: include cdevname in struct stat Sascha Hauer
@ 2025-12-15 11:25   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:25 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> In Linux struct stat contains the major/minor numbers of the underlying
> device, consequently we put the cdev name into struct stat.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/fs.c              | 1 +
>  include/linux/stat.h | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/fs/fs.c b/fs/fs.c
> index 9e2c95c6352cc63400f997bb8de53af44f4741cf..9022287dff2f4959f64eac76c544634b3978d238 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -1117,6 +1117,7 @@ static void stat_inode(struct inode *inode, struct stat *s)
>  	s->st_mode = inode->i_mode;
>  	s->st_uid = inode->i_uid;
>  	s->st_gid = inode->i_gid;
> +	s->st_cdevname = inode->cdevname;
>  }
>  
>  int fstat(int fd, struct stat *s)
> diff --git a/include/linux/stat.h b/include/linux/stat.h
> index 6ee05b52873f47e5d17a4387829187512be29ea8..84b6484a1f2149d1f2d770f0f11bf0ae0ef63744 100644
> --- a/include/linux/stat.h
> +++ b/include/linux/stat.h
> @@ -55,6 +55,7 @@ struct stat {
>  	unsigned short st_mode;
>  	unsigned short st_uid;
>  	unsigned short st_gid;
> +	const char *st_cdevname; /* barebox specific */
>  	loff_t  st_size;
>  };
>  
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 10/13] fs: stat_print: get cdevname from stat
  2025-12-09 12:51 ` [PATCH v2 10/13] fs: stat_print: get cdevname from stat Sascha Hauer
@ 2025-12-15 11:26   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:26 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> In stat_print() we have to take the filename component of the input path
> and retrieve the cdev from that name. Now that we have the cdevname in
> struct stat we can simplify this.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  fs/fs.c | 25 ++++---------------------
>  1 file changed, 4 insertions(+), 21 deletions(-)
> 
> diff --git a/fs/fs.c b/fs/fs.c
> index 9022287dff2f4959f64eac76c544634b3978d238..30fe5db4d2800ebfdc0c44603caea15bdff807aa 100644
> --- a/fs/fs.c
> +++ b/fs/fs.c
> @@ -137,7 +137,6 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
>  	struct fs_device *fdev;
>  	struct cdev *cdev = NULL;
>  	const char *type = NULL, *typeprefix = "";
> -	bool is_cdev_link = false;
>  	char modestr[11];
>  
>  	mkmodestr(st->st_mode, modestr);
> @@ -152,23 +151,10 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
>  		case S_IFREG:    type = "regular file"; break;
>  	}
>  
> -	if (st->st_mode & S_IFCHR) {
> -		char *path;
> -
> -		path = canonicalize_path(dirfd, filename);
> -		if (path) {
> -			const char *devicefile = devpath_to_name(path);
> -			struct cdev *lcdev;
> -
> -			lcdev = lcdev_by_name(devicefile);
> -			cdev = cdev_readlink(lcdev);
> -			if (cdev != lcdev)
> -				is_cdev_link = true;
> -			if (cdev)
> -				bdev = cdev_get_block_device(cdev);
> -
> -			free(path);
> -		}
> +	if ((st->st_mode & S_IFCHR) && st->st_cdevname) {
> +		cdev = cdev_by_name(st->st_cdevname);
> +		if (cdev)
> +			bdev = cdev_get_block_device(cdev);
>  	}
>  
>  	printf("  File: %s", filename);
> @@ -182,9 +168,6 @@ void stat_print(int dirfd, const char *filename, const struct stat *st)
>  			printf(" -> <readlink error %pe>", ERR_PTR(ret));
>  		else
>  			printf(" -> %s", realname);
> -	} else if (is_cdev_link) {
> -		printf(" ~> %s", cdev->name);
> -		typeprefix = "cdev link to ";
>  	}
>  
>  	printf("\nSize: ");
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 11/13] common: cdev-alias: rename struct
  2025-12-09 12:51 ` [PATCH v2 11/13] common: cdev-alias: rename struct Sascha Hauer
@ 2025-12-15 11:27   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:27 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> We'll introduce a globally available struct cdev_alias in the next step,
> so rename struct cdev_alias in common/cdev-alias.c to avoid name
> conflicts.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  common/cdev-alias.c | 12 ++++++------
>  1 file changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/common/cdev-alias.c b/common/cdev-alias.c
> index 329ba9e97c16fe7a90d09c0bb31ef3359b72b5d0..e5a059ad7f4d9bc447c44072c5c7744051d12a0e 100644
> --- a/common/cdev-alias.c
> +++ b/common/cdev-alias.c
> @@ -11,13 +11,13 @@
>  #include <driver.h>
>  #include <init.h>
>  
> -struct cdev_alias {
> +struct cdev_alias_res {
>  	const char *name;
> -	int (*resolve)(struct cdev_alias *, const char *arg,
> +	int (*resolve)(struct cdev_alias_res *, const char *arg,
>  		       cdev_alias_processor_t fn, void *data);
>  };
>  
> -static int cdev_alias_resolve_bootsource(struct cdev_alias *cdev_alias,
> +static int cdev_alias_resolve_bootsource(struct cdev_alias_res *cdev_alias_res,
>  					 const char *partname,
>  					 cdev_alias_processor_t fn,
>  					 void *data)
> @@ -37,7 +37,7 @@ static int cdev_alias_resolve_bootsource(struct cdev_alias *cdev_alias,
>  	return fn(cdev, data);
>  }
>  
> -static int cdev_alias_resolve_diskuuid(struct cdev_alias *cdev_alias,
> +static int cdev_alias_resolve_diskuuid(struct cdev_alias_res *cdev_alias_res,
>  				       const char *uuid,
>  				       cdev_alias_processor_t fn,
>  				       void *data)
> @@ -67,7 +67,7 @@ static int cdev_alias_resolve_diskuuid(struct cdev_alias *cdev_alias,
>  	return 0;
>  }
>  
> -static struct cdev_alias cdev_alias_aliases[] = {
> +static struct cdev_alias_res cdev_alias_aliases[] = {
>  	{ "bootsource", cdev_alias_resolve_bootsource },
>  	{ "diskuuid", cdev_alias_resolve_diskuuid },
>  	{ /* sentinel */}
> @@ -76,7 +76,7 @@ static struct cdev_alias cdev_alias_aliases[] = {
>  int cdev_alias_resolve_for_each(const char *name,
>  				cdev_alias_processor_t fn, void *data)
>  {
> -	struct cdev_alias *alias;
> +	struct cdev_alias_res *alias;
>  	int ret = 0;
>  	char *buf, *arg;
>  
> 


-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 12/13] fs: replace cdev links with aliases
  2025-12-09 12:51 ` [PATCH v2 12/13] fs: replace cdev links with aliases Sascha Hauer
@ 2025-12-15 11:31   ` Ahmad Fatoum
  2025-12-15 12:17     ` Sascha Hauer
  0 siblings, 1 reply; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:31 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX

Hi,

On 12/9/25 1:51 PM, Sascha Hauer wrote:

A commit message would be grand. :)

> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Acked-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  commands/devinfo.c              |   7 +-
>  common/partitions.c             |   2 +-
>  drivers/block/dm/dm-core.c      |   1 -
>  drivers/misc/storage-by-alias.c |   2 +-
>  fs/devfs-core.c                 | 191 +++++++++++++++++++++-------------------
>  include/block.h                 |   2 -
>  include/driver.h                |  20 +++--
>  7 files changed, 121 insertions(+), 104 deletions(-)
> 
> diff --git a/commands/devinfo.c b/commands/devinfo.c
> index c87b30e84307e5053bc35e8bd70ac7af63f688b8..c5417cb7bbe9c7beacd85888fb34405bdc279aea 100644
> --- a/commands/devinfo.c
> +++ b/commands/devinfo.c
> @@ -9,7 +9,8 @@
>  static int do_devinfo_subtree(struct device *dev, int depth)
>  {
>  	struct device *child;
> -	struct cdev *cdev, *cdevl;
> +	struct cdev *cdev;
> +	struct cdev_alias *alias;
>  	int i;
>  
>  	for (i = 0; i < depth; i++)
> @@ -26,8 +27,8 @@ static int do_devinfo_subtree(struct device *dev, int depth)
>  					cdev->offset + cdev->size - 1,
>  					size_human_readable(cdev->size),
>  					cdev->name);
> -			list_for_each_entry(cdevl, &cdev->links, link_entry)
> -				printf(", %s", cdevl->name);
> +			cdev_for_each_alias(alias, cdev)
> +				printf(", %s", alias->name);
>  			printf("\n");
>  		}
>  	} else {
> diff --git a/common/partitions.c b/common/partitions.c
> index 7563cb0e6767891ee7f1fe264ce86703408f790a..1a4e046c5f55314ccb2abf5094b0966def8c5b55 100644
> --- a/common/partitions.c
> +++ b/common/partitions.c
> @@ -63,7 +63,7 @@ static int register_one_partition(struct block_device *blk, struct partition *pa
>  		return 0;
>  
>  	partition_name = xasprintf("%s.%s", blk->cdev.name, part->name);
> -	ret = devfs_create_link(cdev, partition_name);
> +	ret = devfs_add_alias(cdev, partition_name);
>  	if (ret)
>  		dev_warn(blk->dev, "Failed to create link from %s to %s\n",
>  			 partition_name, cdev->name);
> diff --git a/drivers/block/dm/dm-core.c b/drivers/block/dm/dm-core.c
> index fd7ed0d84ed7388f8c1cd4aa19e0466191459fd6..2f48cfeb06f7b2da6d26850820f228a6f522fc2f 100644
> --- a/drivers/block/dm/dm-core.c
> +++ b/drivers/block/dm/dm-core.c
> @@ -77,7 +77,6 @@ int dm_cdev_open(struct dm_cdev *dmcdev, const char *path, ulong flags,
>  			return -ENODEV;
>  		}
>  
> -		dmcdev->cdev = cdev_readlink(dmcdev->cdev);
>  		break;
>  	default:
>  		*errmsg = xstrdup("Only regular files and device specials are supported");
> diff --git a/drivers/misc/storage-by-alias.c b/drivers/misc/storage-by-alias.c
> index 6c759867ccbb7a7b4bc922152699eb346d42d271..196346c8eafcc7868aa279353414409617e1e907 100644
> --- a/drivers/misc/storage-by-alias.c
> +++ b/drivers/misc/storage-by-alias.c
> @@ -38,7 +38,7 @@ static int sba_add_partitions(struct cdev *rcdev, void *data)
>  
>  	dev_info(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
>  
> -	ret = devfs_create_link_node(rcdev, sba->alias, sba->dev->device_node);
> +	ret = devfs_add_alias_node(rcdev, sba->alias, sba->dev->device_node);
>  	if (ret)
>  		return ret;
>  
> diff --git a/fs/devfs-core.c b/fs/devfs-core.c
> index 3a5667b9f723fa718453bdc58827f4b760f3565a..b285b7ede029b14bb0bbc1dbf60ba8a8895c3f26 100644
> --- a/fs/devfs-core.c
> +++ b/fs/devfs-core.c
> @@ -50,42 +50,21 @@ int devfs_partition_complete(struct string_list *sl, char *instr)
>  }
>  #endif
>  
> -struct cdev *cdev_readlink(const struct cdev *cdev)
> -{
> -	if (!cdev)
> -		return NULL;
> -
> -	if (cdev->link)
> -		cdev = cdev->link;
> -
> -	/* links to links are not allowed */
> -	BUG_ON(cdev->link);
> -
> -	return (void *)cdev;
> -}
> -
> -struct cdev *lcdev_by_name(const char *filename)
> +struct cdev *cdev_by_name(const char *filename)
>  {
>  	struct cdev *cdev;
> +	struct cdev_alias *alias;
>  
>  	for_each_cdev(cdev) {
>  		if (!strcmp(cdev->name, filename))
>  			return cdev;
> +		cdev_for_each_alias(alias, cdev)
> +			if (!strcmp(alias->name, filename))
> +				return cdev;
>  	}
>  	return NULL;
>  }
>  
> -struct cdev *cdev_by_name(const char *filename)
> -{
> -	struct cdev *cdev;
> -
> -	cdev = lcdev_by_name(filename);
> -	if (!cdev)
> -		return NULL;
> -
> -	return cdev_readlink(cdev);
> -}
> -
>  struct cdev *cdev_by_device_node(struct device_node *node)
>  {
>  	struct cdev *cdev;
> @@ -94,8 +73,14 @@ struct cdev *cdev_by_device_node(struct device_node *node)
>  		return NULL;
>  
>  	for_each_cdev(cdev) {
> +		struct cdev_alias *alias;
> +
>  		if (cdev_of_node(cdev) == node)
> -			return cdev_readlink(cdev);
> +			return cdev;
> +
> +		cdev_for_each_alias(alias, cdev)
> +			if (alias->device_node == node)
> +				return cdev;
>  	}
>  	return NULL;
>  }
> @@ -133,9 +118,6 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
>  {
>  	struct cdev *partcdev;
>  
> -        /* Follow links to support storage-by-alias */
> -        cdev = cdev_readlink(cdev);
> -
>  	if (!cdev_is_gpt_partitioned(cdev))
>  		return ERR_PTR(-EINVAL);
>  
> @@ -153,6 +135,29 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
>  	return ERR_PTR(-ENOENT);
>  }
>  
> +static bool cdev_has_partname_alias(struct cdev *cdev, const char *partname)
> +{
> +	char *fullname;
> +	struct cdev_alias *alias;
> +	bool ret = false;
> +
> +	if (!cdev->master)
> +		return false;
> +
> +	fullname = xasprintf("%s.%s", cdev->master->name, partname);
> +
> +	cdev_for_each_alias(alias, cdev) {
> +		if (streq_ptr(alias->name, fullname)) {
> +			ret = true;
> +			break;
> +		}
> +	}
> +
> +	free(fullname);
> +
> +	return ret;
> +}
> +
>  /**
>   * cdev_find_partition - find a partition belonging to a physical device
>   *
> @@ -164,15 +169,10 @@ struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name)
>  	struct cdev *partcdev;
>  
>  	for_each_cdev_partition(partcdev, cdevm) {
> -		struct cdev *cdevl;
> -
>  		if (streq_ptr(partcdev->partname, name))
>  			return partcdev;
> -
> -		list_for_each_entry(cdevl, &partcdev->links, link_entry) {
> -			if (streq_ptr(cdevl->partname, name))
> -				return cdevl;
> -		}
> +		if (cdev_has_partname_alias(partcdev, name))
> +			return partcdev;
>  	}
>  
>  	return NULL;
> @@ -190,15 +190,11 @@ struct cdev *device_find_partition(struct device *dev, const char *name)
>  	struct device *child;
>  
>  	list_for_each_entry(cdev, &dev->cdevs, devices_list) {
> -		struct cdev *cdevl;
> -
>  		if (streq_ptr(cdev->partname, name))
>  			return cdev;
>  
> -		list_for_each_entry(cdevl, &cdev->links, link_entry) {
> -			if (streq_ptr(cdevl->partname, name))
> -				return cdev_readlink(cdevl);
> -		}
> +		if (cdev_has_partname_alias(cdev, name))
> +			return cdev;
>  	}
>  
>  	device_for_each_child(dev, child) {
> @@ -460,25 +456,54 @@ static void cdev_free(struct cdev *cdev)
>  
>  static bool devfs_initialized;
>  
> +static int cdev_symlink(struct cdev *cdev, const char *linkname)
> +{
> +	char *path;
> +	int ret;
> +
> +	if (!devfs_initialized)
> +		return 0;
> +
> +	path = xasprintf("/dev/%s", linkname);
> +	ret = symlink(cdev->name, path);
> +	free(path);
> +
> +	return ret;
> +}
> +
>  static void devfs_mknod(struct cdev *cdev)
>  {
>  	char *path;
>  	int ret;
> +	struct cdev_alias *alias;
>  
>  	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);
> +	cdev_for_each_alias(alias, cdev)
> +		cdev_symlink(cdev, alias->name);
> +
> +	ret = mknod(path, S_IFCHR | 0600, cdev->name);
>  
>  	free(path);
>  
> -	if (ret)
> +	if (ret) {
>  		pr_err("Failed to create /dev/%s: %pe\n", cdev->name, ERR_PTR(ret));
> +		dump_stack();
> +	}
> +}
> +
> +static void devfs_unlink(const char *name)
> +{
> +	char *path;
> +
> +	path = xasprintf("/dev/%s", name);
> +
> +	unlink(path);
> +
> +	free(path);
>  }
>  
>  void devfs_init(void)
> @@ -499,8 +524,8 @@ int devfs_create(struct cdev *new)
>  	if (cdev)
>  		return -EEXIST;
>  
> -	INIT_LIST_HEAD(&new->links);
>  	INIT_LIST_HEAD(&new->partitions);
> +	INIT_LIST_HEAD(&new->aliases);
>  
>  	list_add_tail(&new->list, &cdev_list);
>  	if (new->dev) {
> @@ -509,54 +534,44 @@ int devfs_create(struct cdev *new)
>  			new->device_node = new->dev->of_node;
>  	}
>  
> -	if (new->link)
> -		list_add_tail(&new->link_entry, &new->link->links);
> -
>  	devfs_mknod(new);
>  
>  	return 0;
>  }
>  
> -int devfs_create_link_node(struct cdev *cdev, const char *name, struct device_node *node)
> +int devfs_add_alias_node(struct cdev *cdev, const char *name, struct device_node *np)
>  {
> -	struct cdev *new;
> -	int ret;
> -
> -	/*
> -	 * Create a link to the real cdev instead of creating
> -	 * a link to a link.
> -	 */
> -	cdev = cdev_readlink(cdev);
> -
> -	new = cdev_alloc(name);
> -	new->link = cdev;
> -	new->device_node = node;
> -
> -	ret = devfs_create(new);
> -	if (ret) {
> -		cdev_free(new);
> -		return ret;
> -	}
> -
> -	if (cdev->partname) {
> -		size_t partnameoff = 0;
> +	struct cdev *conflict;
> +	struct cdev_alias *alias;
>  
> -		if (cdev->master) {
> -			size_t masterlen = strlen(cdev->master->name);
> +	conflict = cdev_by_name(name);
> +	if (conflict)
> +		return -EEXIST;
>  
> -			if (!strncmp(name, cdev->master->name, masterlen))
> -				partnameoff += masterlen + 1;
> -		}
> +	alias = xzalloc(sizeof(*alias));
> +	alias->name = xstrdup(name);
> +	alias->device_node = np;
> +	list_add_tail(&alias->list, &cdev->aliases);
>  
> -		new->partname = xstrdup(name + partnameoff);
> -	}
> +	cdev_symlink(cdev, name);
>  
>  	return 0;
>  }
>  
> -int devfs_create_link(struct cdev *cdev, const char *name)
> +int devfs_add_alias(struct cdev *cdev, const char *name)
> +{
> +	return devfs_add_alias_node(cdev, name, NULL);
> +}
> +
> +static void devfs_remove_aliases(struct cdev *cdev)
>  {
> -	return devfs_create_link_node(cdev, name, NULL);
> +	struct cdev_alias *alias, *tmp;
> +
> +	list_for_each_entry_safe(alias, tmp, &cdev->aliases, list) {
> +		devfs_unlink(alias->name);
> +		free(alias->name);
> +		free(alias);
> +	}
>  }
>  
>  int devfs_remove(struct cdev *cdev)
> @@ -571,8 +586,9 @@ int devfs_remove(struct cdev *cdev)
>  	if (cdev->dev)
>  		list_del(&cdev->devices_list);
>  
> -	list_for_each_entry_safe(c, tmp, &cdev->links, link_entry)
> -		devfs_remove(c);
> +	devfs_unlink(cdev->name);
> +
> +	devfs_remove_aliases(cdev);
>  
>  	list_for_each_entry_safe(c, tmp, &cdev->partitions, partition_entry)
>  		cdevfs_del_partition(c);
> @@ -580,9 +596,6 @@ int devfs_remove(struct cdev *cdev)
>  	if (cdev_is_partition(cdev))
>  		list_del(&cdev->partition_entry);
>  
> -	if (cdev->link)
> -		cdev_free(cdev);
> -
>  	return 0;
>  }
>  
> @@ -687,7 +700,7 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
>  	if (overlap) {
>  		if (!IS_ERR(overlap)) {
>  			/* only fails with -EEXIST, which is fine */
> -			(void)devfs_create_link(overlap, partinfo->name);
> +			(void)devfs_add_alias(overlap, partinfo->name);
>  		}
>  
>  		return overlap;
> diff --git a/include/block.h b/include/block.h
> index fc7a0a32fb2d6bc579aa6305433fb2a9e39f336a..a8ebe202288fff83677948f3d67bc12cae5dc107 100644
> --- a/include/block.h
> +++ b/include/block.h
> @@ -104,13 +104,11 @@ static inline bool cdev_is_block_device(const struct cdev *cdev)
>  
>  static inline bool cdev_is_block_partition(const struct cdev *cdev)
>  {
> -	cdev = cdev_readlink(cdev);
>  	return cdev_is_block_device(cdev) && cdev_is_partition(cdev);
>  }
>  
>  static inline bool cdev_is_block_disk(const struct cdev *cdev)
>  {
> -	cdev = cdev_readlink(cdev);
>  	return cdev_is_block_device(cdev) && !cdev_is_partition(cdev);
>  }
>  
> diff --git a/include/driver.h b/include/driver.h
> index 802917f1c20727272364d094552e4e5b40a6165b..1c78f35f7eb960ac231ee6ad20db8a2a7cbb6a19 100644
> --- a/include/driver.h
> +++ b/include/driver.h
> @@ -17,6 +17,7 @@
>  #include <init.h>
>  #include <errno.h>
>  #include <filetype.h>
> +#include <stringlist.h>
>  
>  #define FORMAT_DRIVER_NAME_ID	"%s%d"
>  
> @@ -432,8 +433,7 @@ struct cdev {
>  	u16 typeflags; /* GPT type-specific attributes */
>  	int open;
>  	struct mtd_info *mtd;
> -	struct cdev *link;
> -	struct list_head link_entry, links;
> +	struct list_head aliases;
>  	struct list_head partition_entry, partitions;
>  	struct cdev *master;
>  	enum filetype filetype;
> @@ -443,6 +443,15 @@ struct cdev {
>  	};
>  };
>  
> +#define cdev_for_each_alias(alias, cdev) \
> +	list_for_each_entry(alias, &cdev->aliases, list)
> +
> +struct cdev_alias {
> +	char *name;
> +	struct device_node *device_node;
> +	struct list_head list;
> +};
> +
>  static inline struct device_node *cdev_of_node(const struct cdev *cdev)
>  {
>  	return IS_ENABLED(CONFIG_OFDEVICE) ? cdev->device_node : NULL;
> @@ -461,15 +470,12 @@ static inline const char *cdev_name(struct cdev *cdev)
>  
>  void devfs_init(void);
>  int devfs_create(struct cdev *);
> -int devfs_create_link(struct cdev *, const char *name);
> -int devfs_create_link_node(struct cdev *cdev, const char *name,
> -			   struct device_node *node);
> +int devfs_add_alias(struct cdev *, const char *name);
> +int devfs_add_alias_node(struct cdev *, const char *name, struct device_node *np);
>  int devfs_remove(struct cdev *);
>  int cdev_find_free_index(const char *);
>  struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name);
>  struct cdev *device_find_partition(struct device *dev, const char *name);
> -struct cdev *lcdev_by_name(const char *filename);
> -struct cdev *cdev_readlink(const struct cdev *cdev);
>  struct cdev *cdev_by_device_node(struct device_node *node);
>  struct cdev *cdev_by_partuuid(const char *partuuid);
>  struct cdev *cdev_by_diskuuid(const char *partuuid);
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM
  2025-12-09 12:51 ` [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM Sascha Hauer
@ 2025-12-15 11:32   ` Ahmad Fatoum
  0 siblings, 0 replies; 29+ messages in thread
From: Ahmad Fatoum @ 2025-12-15 11:32 UTC (permalink / raw)
  To: Sascha Hauer, BAREBOX



On 12/9/25 1:51 PM, Sascha Hauer wrote:
> For stream size files we used to show ((loff_t) -1) as file size which
> is quite unreadable. Use ~0 in this case.
> 
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

Reviewed-by: Ahmad Fatoum <a.fatoum@pengutronix.de>

> ---
>  commands/ls.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/commands/ls.c b/commands/ls.c
> index 1ccd44f7bbc00a03b773b56020a7117ce94b24cd..5c9e0f738b03ae36655b04ec1037811a4abc0423 100644
> --- a/commands/ls.c
> +++ b/commands/ls.c
> @@ -33,8 +33,12 @@ static void ls_one(const char *path, const char* fullname)
>  		return;
>  
>  	mkmodestr(s.st_mode, modestr);
> -	printf("%s %*llu %*.*s", modestr, SIZELEN, s.st_size, namelen,
> -	       namelen, path);
> +	if (s.st_size == FILE_SIZE_STREAM)
> +		printf("%s %*s %*.*s", modestr, SIZELEN, "~0", namelen,
> +		       namelen, path);
> +	else
> +		printf("%s %*llu %*.*s", modestr, SIZELEN, s.st_size, namelen,
> +			namelen, path);
>  
>  	if (S_ISLNK(s.st_mode)) {
>  		char realname[PATH_MAX];
> 

-- 
Pengutronix e.K.                  |                             |
Steuerwalder Str. 21              | http://www.pengutronix.de/  |
31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 00/13] fs: Use device special nodes for devfs
  2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
                   ` (12 preceding siblings ...)
  2025-12-09 12:51 ` [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM Sascha Hauer
@ 2025-12-15 12:16 ` Sascha Hauer
  13 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2025-12-15 12:16 UTC (permalink / raw)
  To: BAREBOX, Sascha Hauer


On Tue, 09 Dec 2025 13:51:19 +0100, Sascha Hauer wrote:
> Until now we have a devfs which is a filesystem of its own. This
> comes with a few limitations:
> 
> - we cannot create directories under /dev/
> - Links are implemented in the devfs filesystem. They do not show
>   up as regular links
> 
> [...]

Applied, thanks!

[01/13] fs: devfs-core: add devfs_create_link_node()
        https://git.pengutronix.de/cgit/barebox/commit/?id=0532ad160214 (link may not be stable)
[02/13] storage-by-alias: drop fake cdev
        https://git.pengutronix.de/cgit/barebox/commit/?id=50f91eaeac24 (link may not be stable)
[03/13] fs: implement mknod
        https://git.pengutronix.de/cgit/barebox/commit/?id=d37d0ed18ddc (link may not be stable)
[04/13] commands: add mknod command
        https://git.pengutronix.de/cgit/barebox/commit/?id=65a86ce343b3 (link may not be stable)
[05/13] fs: ramfs: add device file support
        https://git.pengutronix.de/cgit/barebox/commit/?id=84efacef29bf (link may not be stable)
[06/13] cdev: add cdev_size() helper
        https://git.pengutronix.de/cgit/barebox/commit/?id=1935728cfea8 (link may not be stable)
[07/13] fs: fix st_size for device files
        https://git.pengutronix.de/cgit/barebox/commit/?id=37b73179a340 (link may not be stable)
[08/13] fs: retire devfs as filesystem
        https://git.pengutronix.de/cgit/barebox/commit/?id=cff48c7caba4 (link may not be stable)
[09/13] fs: include cdevname in struct stat
        https://git.pengutronix.de/cgit/barebox/commit/?id=f7950b1fac33 (link may not be stable)
[10/13] fs: stat_print: get cdevname from stat
        https://git.pengutronix.de/cgit/barebox/commit/?id=6f646eccbf9f (link may not be stable)
[11/13] common: cdev-alias: rename struct
        https://git.pengutronix.de/cgit/barebox/commit/?id=0511991f9c04 (link may not be stable)
[12/13] fs: replace cdev links with aliases
        https://git.pengutronix.de/cgit/barebox/commit/?id=224b5a781f34 (link may not be stable)
[13/13] ls: use ~0 for FILE_SIZE_STREAM
        https://git.pengutronix.de/cgit/barebox/commit/?id=6bcded4d13b3 (link may not be stable)

Best regards,
-- 
Sascha Hauer <s.hauer@pengutronix.de>




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH v2 12/13] fs: replace cdev links with aliases
  2025-12-15 11:31   ` Ahmad Fatoum
@ 2025-12-15 12:17     ` Sascha Hauer
  0 siblings, 0 replies; 29+ messages in thread
From: Sascha Hauer @ 2025-12-15 12:17 UTC (permalink / raw)
  To: Ahmad Fatoum; +Cc: BAREBOX

On Mon, Dec 15, 2025 at 12:31:50PM +0100, Ahmad Fatoum wrote:
> Hi,
> 
> On 12/9/25 1:51 PM, Sascha Hauer wrote:
> 
> A commit message would be grand. :)

Added one and also integrated the other changes you suggested, thanks
Ahamd.

Sascha

> 
> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> 
> Acked-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
> 
> > ---
> >  commands/devinfo.c              |   7 +-
> >  common/partitions.c             |   2 +-
> >  drivers/block/dm/dm-core.c      |   1 -
> >  drivers/misc/storage-by-alias.c |   2 +-
> >  fs/devfs-core.c                 | 191 +++++++++++++++++++++-------------------
> >  include/block.h                 |   2 -
> >  include/driver.h                |  20 +++--
> >  7 files changed, 121 insertions(+), 104 deletions(-)
> > 
> > diff --git a/commands/devinfo.c b/commands/devinfo.c
> > index c87b30e84307e5053bc35e8bd70ac7af63f688b8..c5417cb7bbe9c7beacd85888fb34405bdc279aea 100644
> > --- a/commands/devinfo.c
> > +++ b/commands/devinfo.c
> > @@ -9,7 +9,8 @@
> >  static int do_devinfo_subtree(struct device *dev, int depth)
> >  {
> >  	struct device *child;
> > -	struct cdev *cdev, *cdevl;
> > +	struct cdev *cdev;
> > +	struct cdev_alias *alias;
> >  	int i;
> >  
> >  	for (i = 0; i < depth; i++)
> > @@ -26,8 +27,8 @@ static int do_devinfo_subtree(struct device *dev, int depth)
> >  					cdev->offset + cdev->size - 1,
> >  					size_human_readable(cdev->size),
> >  					cdev->name);
> > -			list_for_each_entry(cdevl, &cdev->links, link_entry)
> > -				printf(", %s", cdevl->name);
> > +			cdev_for_each_alias(alias, cdev)
> > +				printf(", %s", alias->name);
> >  			printf("\n");
> >  		}
> >  	} else {
> > diff --git a/common/partitions.c b/common/partitions.c
> > index 7563cb0e6767891ee7f1fe264ce86703408f790a..1a4e046c5f55314ccb2abf5094b0966def8c5b55 100644
> > --- a/common/partitions.c
> > +++ b/common/partitions.c
> > @@ -63,7 +63,7 @@ static int register_one_partition(struct block_device *blk, struct partition *pa
> >  		return 0;
> >  
> >  	partition_name = xasprintf("%s.%s", blk->cdev.name, part->name);
> > -	ret = devfs_create_link(cdev, partition_name);
> > +	ret = devfs_add_alias(cdev, partition_name);
> >  	if (ret)
> >  		dev_warn(blk->dev, "Failed to create link from %s to %s\n",
> >  			 partition_name, cdev->name);
> > diff --git a/drivers/block/dm/dm-core.c b/drivers/block/dm/dm-core.c
> > index fd7ed0d84ed7388f8c1cd4aa19e0466191459fd6..2f48cfeb06f7b2da6d26850820f228a6f522fc2f 100644
> > --- a/drivers/block/dm/dm-core.c
> > +++ b/drivers/block/dm/dm-core.c
> > @@ -77,7 +77,6 @@ int dm_cdev_open(struct dm_cdev *dmcdev, const char *path, ulong flags,
> >  			return -ENODEV;
> >  		}
> >  
> > -		dmcdev->cdev = cdev_readlink(dmcdev->cdev);
> >  		break;
> >  	default:
> >  		*errmsg = xstrdup("Only regular files and device specials are supported");
> > diff --git a/drivers/misc/storage-by-alias.c b/drivers/misc/storage-by-alias.c
> > index 6c759867ccbb7a7b4bc922152699eb346d42d271..196346c8eafcc7868aa279353414409617e1e907 100644
> > --- a/drivers/misc/storage-by-alias.c
> > +++ b/drivers/misc/storage-by-alias.c
> > @@ -38,7 +38,7 @@ static int sba_add_partitions(struct cdev *rcdev, void *data)
> >  
> >  	dev_info(sba->dev, "Adding %s -> %s\n", sba->alias, rcdev->name);
> >  
> > -	ret = devfs_create_link_node(rcdev, sba->alias, sba->dev->device_node);
> > +	ret = devfs_add_alias_node(rcdev, sba->alias, sba->dev->device_node);
> >  	if (ret)
> >  		return ret;
> >  
> > diff --git a/fs/devfs-core.c b/fs/devfs-core.c
> > index 3a5667b9f723fa718453bdc58827f4b760f3565a..b285b7ede029b14bb0bbc1dbf60ba8a8895c3f26 100644
> > --- a/fs/devfs-core.c
> > +++ b/fs/devfs-core.c
> > @@ -50,42 +50,21 @@ int devfs_partition_complete(struct string_list *sl, char *instr)
> >  }
> >  #endif
> >  
> > -struct cdev *cdev_readlink(const struct cdev *cdev)
> > -{
> > -	if (!cdev)
> > -		return NULL;
> > -
> > -	if (cdev->link)
> > -		cdev = cdev->link;
> > -
> > -	/* links to links are not allowed */
> > -	BUG_ON(cdev->link);
> > -
> > -	return (void *)cdev;
> > -}
> > -
> > -struct cdev *lcdev_by_name(const char *filename)
> > +struct cdev *cdev_by_name(const char *filename)
> >  {
> >  	struct cdev *cdev;
> > +	struct cdev_alias *alias;
> >  
> >  	for_each_cdev(cdev) {
> >  		if (!strcmp(cdev->name, filename))
> >  			return cdev;
> > +		cdev_for_each_alias(alias, cdev)
> > +			if (!strcmp(alias->name, filename))
> > +				return cdev;
> >  	}
> >  	return NULL;
> >  }
> >  
> > -struct cdev *cdev_by_name(const char *filename)
> > -{
> > -	struct cdev *cdev;
> > -
> > -	cdev = lcdev_by_name(filename);
> > -	if (!cdev)
> > -		return NULL;
> > -
> > -	return cdev_readlink(cdev);
> > -}
> > -
> >  struct cdev *cdev_by_device_node(struct device_node *node)
> >  {
> >  	struct cdev *cdev;
> > @@ -94,8 +73,14 @@ struct cdev *cdev_by_device_node(struct device_node *node)
> >  		return NULL;
> >  
> >  	for_each_cdev(cdev) {
> > +		struct cdev_alias *alias;
> > +
> >  		if (cdev_of_node(cdev) == node)
> > -			return cdev_readlink(cdev);
> > +			return cdev;
> > +
> > +		cdev_for_each_alias(alias, cdev)
> > +			if (alias->device_node == node)
> > +				return cdev;
> >  	}
> >  	return NULL;
> >  }
> > @@ -133,9 +118,6 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
> >  {
> >  	struct cdev *partcdev;
> >  
> > -        /* Follow links to support storage-by-alias */
> > -        cdev = cdev_readlink(cdev);
> > -
> >  	if (!cdev_is_gpt_partitioned(cdev))
> >  		return ERR_PTR(-EINVAL);
> >  
> > @@ -153,6 +135,29 @@ cdev_find_child_by_gpt_typeuuid(struct cdev *cdev, const guid_t *typeuuid)
> >  	return ERR_PTR(-ENOENT);
> >  }
> >  
> > +static bool cdev_has_partname_alias(struct cdev *cdev, const char *partname)
> > +{
> > +	char *fullname;
> > +	struct cdev_alias *alias;
> > +	bool ret = false;
> > +
> > +	if (!cdev->master)
> > +		return false;
> > +
> > +	fullname = xasprintf("%s.%s", cdev->master->name, partname);
> > +
> > +	cdev_for_each_alias(alias, cdev) {
> > +		if (streq_ptr(alias->name, fullname)) {
> > +			ret = true;
> > +			break;
> > +		}
> > +	}
> > +
> > +	free(fullname);
> > +
> > +	return ret;
> > +}
> > +
> >  /**
> >   * cdev_find_partition - find a partition belonging to a physical device
> >   *
> > @@ -164,15 +169,10 @@ struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name)
> >  	struct cdev *partcdev;
> >  
> >  	for_each_cdev_partition(partcdev, cdevm) {
> > -		struct cdev *cdevl;
> > -
> >  		if (streq_ptr(partcdev->partname, name))
> >  			return partcdev;
> > -
> > -		list_for_each_entry(cdevl, &partcdev->links, link_entry) {
> > -			if (streq_ptr(cdevl->partname, name))
> > -				return cdevl;
> > -		}
> > +		if (cdev_has_partname_alias(partcdev, name))
> > +			return partcdev;
> >  	}
> >  
> >  	return NULL;
> > @@ -190,15 +190,11 @@ struct cdev *device_find_partition(struct device *dev, const char *name)
> >  	struct device *child;
> >  
> >  	list_for_each_entry(cdev, &dev->cdevs, devices_list) {
> > -		struct cdev *cdevl;
> > -
> >  		if (streq_ptr(cdev->partname, name))
> >  			return cdev;
> >  
> > -		list_for_each_entry(cdevl, &cdev->links, link_entry) {
> > -			if (streq_ptr(cdevl->partname, name))
> > -				return cdev_readlink(cdevl);
> > -		}
> > +		if (cdev_has_partname_alias(cdev, name))
> > +			return cdev;
> >  	}
> >  
> >  	device_for_each_child(dev, child) {
> > @@ -460,25 +456,54 @@ static void cdev_free(struct cdev *cdev)
> >  
> >  static bool devfs_initialized;
> >  
> > +static int cdev_symlink(struct cdev *cdev, const char *linkname)
> > +{
> > +	char *path;
> > +	int ret;
> > +
> > +	if (!devfs_initialized)
> > +		return 0;
> > +
> > +	path = xasprintf("/dev/%s", linkname);
> > +	ret = symlink(cdev->name, path);
> > +	free(path);
> > +
> > +	return ret;
> > +}
> > +
> >  static void devfs_mknod(struct cdev *cdev)
> >  {
> >  	char *path;
> >  	int ret;
> > +	struct cdev_alias *alias;
> >  
> >  	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);
> > +	cdev_for_each_alias(alias, cdev)
> > +		cdev_symlink(cdev, alias->name);
> > +
> > +	ret = mknod(path, S_IFCHR | 0600, cdev->name);
> >  
> >  	free(path);
> >  
> > -	if (ret)
> > +	if (ret) {
> >  		pr_err("Failed to create /dev/%s: %pe\n", cdev->name, ERR_PTR(ret));
> > +		dump_stack();
> > +	}
> > +}
> > +
> > +static void devfs_unlink(const char *name)
> > +{
> > +	char *path;
> > +
> > +	path = xasprintf("/dev/%s", name);
> > +
> > +	unlink(path);
> > +
> > +	free(path);
> >  }
> >  
> >  void devfs_init(void)
> > @@ -499,8 +524,8 @@ int devfs_create(struct cdev *new)
> >  	if (cdev)
> >  		return -EEXIST;
> >  
> > -	INIT_LIST_HEAD(&new->links);
> >  	INIT_LIST_HEAD(&new->partitions);
> > +	INIT_LIST_HEAD(&new->aliases);
> >  
> >  	list_add_tail(&new->list, &cdev_list);
> >  	if (new->dev) {
> > @@ -509,54 +534,44 @@ int devfs_create(struct cdev *new)
> >  			new->device_node = new->dev->of_node;
> >  	}
> >  
> > -	if (new->link)
> > -		list_add_tail(&new->link_entry, &new->link->links);
> > -
> >  	devfs_mknod(new);
> >  
> >  	return 0;
> >  }
> >  
> > -int devfs_create_link_node(struct cdev *cdev, const char *name, struct device_node *node)
> > +int devfs_add_alias_node(struct cdev *cdev, const char *name, struct device_node *np)
> >  {
> > -	struct cdev *new;
> > -	int ret;
> > -
> > -	/*
> > -	 * Create a link to the real cdev instead of creating
> > -	 * a link to a link.
> > -	 */
> > -	cdev = cdev_readlink(cdev);
> > -
> > -	new = cdev_alloc(name);
> > -	new->link = cdev;
> > -	new->device_node = node;
> > -
> > -	ret = devfs_create(new);
> > -	if (ret) {
> > -		cdev_free(new);
> > -		return ret;
> > -	}
> > -
> > -	if (cdev->partname) {
> > -		size_t partnameoff = 0;
> > +	struct cdev *conflict;
> > +	struct cdev_alias *alias;
> >  
> > -		if (cdev->master) {
> > -			size_t masterlen = strlen(cdev->master->name);
> > +	conflict = cdev_by_name(name);
> > +	if (conflict)
> > +		return -EEXIST;
> >  
> > -			if (!strncmp(name, cdev->master->name, masterlen))
> > -				partnameoff += masterlen + 1;
> > -		}
> > +	alias = xzalloc(sizeof(*alias));
> > +	alias->name = xstrdup(name);
> > +	alias->device_node = np;
> > +	list_add_tail(&alias->list, &cdev->aliases);
> >  
> > -		new->partname = xstrdup(name + partnameoff);
> > -	}
> > +	cdev_symlink(cdev, name);
> >  
> >  	return 0;
> >  }
> >  
> > -int devfs_create_link(struct cdev *cdev, const char *name)
> > +int devfs_add_alias(struct cdev *cdev, const char *name)
> > +{
> > +	return devfs_add_alias_node(cdev, name, NULL);
> > +}
> > +
> > +static void devfs_remove_aliases(struct cdev *cdev)
> >  {
> > -	return devfs_create_link_node(cdev, name, NULL);
> > +	struct cdev_alias *alias, *tmp;
> > +
> > +	list_for_each_entry_safe(alias, tmp, &cdev->aliases, list) {
> > +		devfs_unlink(alias->name);
> > +		free(alias->name);
> > +		free(alias);
> > +	}
> >  }
> >  
> >  int devfs_remove(struct cdev *cdev)
> > @@ -571,8 +586,9 @@ int devfs_remove(struct cdev *cdev)
> >  	if (cdev->dev)
> >  		list_del(&cdev->devices_list);
> >  
> > -	list_for_each_entry_safe(c, tmp, &cdev->links, link_entry)
> > -		devfs_remove(c);
> > +	devfs_unlink(cdev->name);
> > +
> > +	devfs_remove_aliases(cdev);
> >  
> >  	list_for_each_entry_safe(c, tmp, &cdev->partitions, partition_entry)
> >  		cdevfs_del_partition(c);
> > @@ -580,9 +596,6 @@ int devfs_remove(struct cdev *cdev)
> >  	if (cdev_is_partition(cdev))
> >  		list_del(&cdev->partition_entry);
> >  
> > -	if (cdev->link)
> > -		cdev_free(cdev);
> > -
> >  	return 0;
> >  }
> >  
> > @@ -687,7 +700,7 @@ static struct cdev *__devfs_add_partition(struct cdev *cdev,
> >  	if (overlap) {
> >  		if (!IS_ERR(overlap)) {
> >  			/* only fails with -EEXIST, which is fine */
> > -			(void)devfs_create_link(overlap, partinfo->name);
> > +			(void)devfs_add_alias(overlap, partinfo->name);
> >  		}
> >  
> >  		return overlap;
> > diff --git a/include/block.h b/include/block.h
> > index fc7a0a32fb2d6bc579aa6305433fb2a9e39f336a..a8ebe202288fff83677948f3d67bc12cae5dc107 100644
> > --- a/include/block.h
> > +++ b/include/block.h
> > @@ -104,13 +104,11 @@ static inline bool cdev_is_block_device(const struct cdev *cdev)
> >  
> >  static inline bool cdev_is_block_partition(const struct cdev *cdev)
> >  {
> > -	cdev = cdev_readlink(cdev);
> >  	return cdev_is_block_device(cdev) && cdev_is_partition(cdev);
> >  }
> >  
> >  static inline bool cdev_is_block_disk(const struct cdev *cdev)
> >  {
> > -	cdev = cdev_readlink(cdev);
> >  	return cdev_is_block_device(cdev) && !cdev_is_partition(cdev);
> >  }
> >  
> > diff --git a/include/driver.h b/include/driver.h
> > index 802917f1c20727272364d094552e4e5b40a6165b..1c78f35f7eb960ac231ee6ad20db8a2a7cbb6a19 100644
> > --- a/include/driver.h
> > +++ b/include/driver.h
> > @@ -17,6 +17,7 @@
> >  #include <init.h>
> >  #include <errno.h>
> >  #include <filetype.h>
> > +#include <stringlist.h>
> >  
> >  #define FORMAT_DRIVER_NAME_ID	"%s%d"
> >  
> > @@ -432,8 +433,7 @@ struct cdev {
> >  	u16 typeflags; /* GPT type-specific attributes */
> >  	int open;
> >  	struct mtd_info *mtd;
> > -	struct cdev *link;
> > -	struct list_head link_entry, links;
> > +	struct list_head aliases;
> >  	struct list_head partition_entry, partitions;
> >  	struct cdev *master;
> >  	enum filetype filetype;
> > @@ -443,6 +443,15 @@ struct cdev {
> >  	};
> >  };
> >  
> > +#define cdev_for_each_alias(alias, cdev) \
> > +	list_for_each_entry(alias, &cdev->aliases, list)
> > +
> > +struct cdev_alias {
> > +	char *name;
> > +	struct device_node *device_node;
> > +	struct list_head list;
> > +};
> > +
> >  static inline struct device_node *cdev_of_node(const struct cdev *cdev)
> >  {
> >  	return IS_ENABLED(CONFIG_OFDEVICE) ? cdev->device_node : NULL;
> > @@ -461,15 +470,12 @@ static inline const char *cdev_name(struct cdev *cdev)
> >  
> >  void devfs_init(void);
> >  int devfs_create(struct cdev *);
> > -int devfs_create_link(struct cdev *, const char *name);
> > -int devfs_create_link_node(struct cdev *cdev, const char *name,
> > -			   struct device_node *node);
> > +int devfs_add_alias(struct cdev *, const char *name);
> > +int devfs_add_alias_node(struct cdev *, const char *name, struct device_node *np);
> >  int devfs_remove(struct cdev *);
> >  int cdev_find_free_index(const char *);
> >  struct cdev *cdev_find_partition(struct cdev *cdevm, const char *name);
> >  struct cdev *device_find_partition(struct device *dev, const char *name);
> > -struct cdev *lcdev_by_name(const char *filename);
> > -struct cdev *cdev_readlink(const struct cdev *cdev);
> >  struct cdev *cdev_by_device_node(struct device_node *node);
> >  struct cdev *cdev_by_partuuid(const char *partuuid);
> >  struct cdev *cdev_by_diskuuid(const char *partuuid);
> > 
> 
> -- 
> Pengutronix e.K.                  |                             |
> Steuerwalder Str. 21              | http://www.pengutronix.de/  |
> 31137 Hildesheim, Germany         | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686  | Fax:   +49-5121-206917-5555 |
> 
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2025-12-15 12:17 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-09 12:51 [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer
2025-12-09 12:51 ` [PATCH v2 01/13] fs: devfs-core: add devfs_create_link_node() Sascha Hauer
2025-12-15 11:14   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 02/13] storage-by-alias: drop fake cdev Sascha Hauer
2025-12-15 11:15   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 03/13] fs: implement mknod Sascha Hauer
2025-12-15 11:19   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 04/13] commands: add mknod command Sascha Hauer
2025-12-15 11:21   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 05/13] fs: ramfs: add device file support Sascha Hauer
2025-12-15 11:22   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 06/13] cdev: add cdev_size() helper Sascha Hauer
2025-12-15 11:22   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 07/13] fs: fix st_size for device files Sascha Hauer
2025-12-15 11:24   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 08/13] fs: retire devfs as filesystem Sascha Hauer
2025-12-15 11:25   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 09/13] fs: include cdevname in struct stat Sascha Hauer
2025-12-15 11:25   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 10/13] fs: stat_print: get cdevname from stat Sascha Hauer
2025-12-15 11:26   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 11/13] common: cdev-alias: rename struct Sascha Hauer
2025-12-15 11:27   ` Ahmad Fatoum
2025-12-09 12:51 ` [PATCH v2 12/13] fs: replace cdev links with aliases Sascha Hauer
2025-12-15 11:31   ` Ahmad Fatoum
2025-12-15 12:17     ` Sascha Hauer
2025-12-09 12:51 ` [PATCH v2 13/13] ls: use ~0 for FILE_SIZE_STREAM Sascha Hauer
2025-12-15 11:32   ` Ahmad Fatoum
2025-12-15 12:16 ` [PATCH v2 00/13] fs: Use device special nodes for devfs Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox