* [PATCH v2] Symlink support for devfs @ 2015-12-16 9:47 Sascha Hauer 2015-12-16 9:47 ` [PATCH 1/2] devfs: Add symlink support Sascha Hauer 2015-12-16 9:47 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer 0 siblings, 2 replies; 7+ messages in thread From: Sascha Hauer @ 2015-12-16 9:47 UTC (permalink / raw) To: Barebox List This adds symlink support for devfs and uses it to create named partition aliases. Changes since v1: - Put links to a cdev onto a list on that cdev to be able to show them in devinfo output ---------------------------------------------------------------- Sascha Hauer (2): devfs: Add symlink support partition: Create links with partition names commands/devinfo.c | 7 +++-- common/partitions.c | 20 +++++--------- fs/devfs-core.c | 76 ++++++++++++++++++++++++++++++++++++++++++++--------- fs/devfs.c | 27 ++++++++++++++++++- include/driver.h | 5 ++++ 5 files changed, 106 insertions(+), 29 deletions(-) _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] devfs: Add symlink support 2015-12-16 9:47 [PATCH v2] Symlink support for devfs Sascha Hauer @ 2015-12-16 9:47 ` Sascha Hauer 2015-12-16 9:47 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer 1 sibling, 0 replies; 7+ messages in thread From: Sascha Hauer @ 2015-12-16 9:47 UTC (permalink / raw) To: Barebox List Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- commands/devinfo.c | 7 +++-- fs/devfs-core.c | 76 ++++++++++++++++++++++++++++++++++++++++++++---------- fs/devfs.c | 27 ++++++++++++++++++- include/driver.h | 5 ++++ 4 files changed, 99 insertions(+), 16 deletions(-) diff --git a/commands/devinfo.c b/commands/devinfo.c index 3c9d6a6..c78efcb 100644 --- a/commands/devinfo.c +++ b/commands/devinfo.c @@ -21,7 +21,7 @@ static int do_devinfo_subtree(struct device_d *dev, int depth) { struct device_d *child; - struct cdev *cdev; + struct cdev *cdev, *cdevl; int i; for (i = 0; i < depth; i++) @@ -33,11 +33,14 @@ static int do_devinfo_subtree(struct device_d *dev, int depth) list_for_each_entry(cdev, &dev->cdevs, devices_list) { for (i = 0; i < depth + 1; i++) printf(" "); - printf("`-- 0x%08llx-0x%08llx (%10s): /dev/%s\n", + printf("`-- 0x%08llx-0x%08llx (%10s): /dev/%s", cdev->offset, 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); + printf("\n"); } } else { printf("\n"); diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 2541ea3..640a134 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -46,7 +46,18 @@ int devfs_partition_complete(struct string_list *sl, char *instr) } #endif -struct cdev *cdev_by_name(const char *filename) +struct cdev *cdev_readlink(struct cdev *cdev) +{ + if (cdev->link) + cdev = cdev->link; + + /* links to links are not allowed */ + BUG_ON(cdev->link); + + return cdev; +} + +struct cdev *lcdev_by_name(const char *filename) { struct cdev *cdev; @@ -57,6 +68,17 @@ struct cdev *cdev_by_name(const char *filename) 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; @@ -65,7 +87,7 @@ struct cdev *cdev_by_device_node(struct device_node *node) if (!cdev->device_node) continue; if (cdev->device_node == node) - return cdev; + return cdev_readlink(cdev); } return NULL; } @@ -111,14 +133,6 @@ int cdev_find_free_index(const char *basename) return -EBUSY; /* all indexes are used */ } -int cdev_do_open(struct cdev *cdev, unsigned long flags) -{ - if (cdev->ops->open) - return cdev->ops->open(cdev, flags); - - return 0; -} - struct cdev *cdev_open(const char *name, unsigned long flags) { struct cdev *cdev; @@ -131,9 +145,11 @@ struct cdev *cdev_open(const char *name, unsigned long flags) if (!cdev) return NULL; - ret = cdev_do_open(cdev, flags); - if (ret) - return NULL; + if (cdev->ops->open) { + ret = cdev->ops->open(cdev, flags); + if (ret) + return NULL; + } return cdev; } @@ -259,6 +275,8 @@ int devfs_create(struct cdev *new) if (cdev) return -EEXIST; + INIT_LIST_HEAD(&new->links); + list_add_tail(&new->list, &cdev_list); if (new->dev) list_add_tail(&new->devices_list, &new->dev->cdevs); @@ -266,15 +284,47 @@ int devfs_create(struct cdev *new) return 0; } +int devfs_create_link(struct cdev *cdev, const char *name) +{ + struct cdev *new; + + if (cdev_by_name(name)) + return -EEXIST; + + /* + * Create a link to the real cdev instead of creating + * a link to a link. + */ + cdev = cdev_readlink(cdev); + + new = xzalloc(sizeof(*new)); + new->name = xstrdup(name); + new->link = cdev; + INIT_LIST_HEAD(&new->links); + list_add_tail(&new->list, &cdev_list); + list_add_tail(&new->link_entry, &cdev->links); + + return 0; +} + int devfs_remove(struct cdev *cdev) { + struct cdev *c, *tmp; + if (cdev->open) return -EBUSY; list_del(&cdev->list); + if (cdev->dev) list_del(&cdev->devices_list); + list_for_each_entry_safe(c, tmp, &cdev->links, link_entry) + devfs_remove(c); + + if (cdev->link) + free(cdev); + return 0; } diff --git a/fs/devfs.c b/fs/devfs.c index 5c96682..0b8d4fd 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -212,12 +212,18 @@ static int devfs_stat(struct device_d *_dev, const char *filename, struct stat * { struct cdev *cdev; - cdev = cdev_by_name(filename + 1); + cdev = lcdev_by_name(filename + 1); if (!cdev) return -ENOENT; s->st_mode = S_IFCHR; s->st_size = cdev->size; + + if (cdev->link) + s->st_mode |= S_IFLNK; + + cdev = cdev_readlink(cdev); + if (cdev->ops->write) s->st_mode |= S_IWUSR; if (cdev->ops->read) @@ -242,6 +248,24 @@ static void devfs_delete(struct device_d *dev) { } +static int devfs_readlink(struct device_d *dev, const char *pathname, + char *buf, size_t bufsz) +{ + struct cdev *cdev; + + cdev = cdev_by_name(pathname + 1); + if (!cdev) + return -ENOENT; + + while (cdev->link) + cdev = cdev->link; + + bufsz = min(bufsz, strlen(cdev->name)); + memcpy(buf, cdev->name, bufsz); + + return 0; +} + static struct fs_driver_d devfs_driver = { .read = devfs_read, .write = devfs_write, @@ -258,6 +282,7 @@ static struct fs_driver_d devfs_driver = { .erase = devfs_erase, .protect = devfs_protect, .memmap = devfs_memmap, + .readlink = devfs_readlink, .flags = FS_DRIVER_NO_DEV, .drv = { .probe = devfs_probe, diff --git a/include/driver.h b/include/driver.h index 046dd90..31c6734 100644 --- a/include/driver.h +++ b/include/driver.h @@ -450,13 +450,18 @@ struct cdev { int open; struct mtd_info *mtd; u8 dos_partition_type; + struct cdev *link; + struct list_head link_entry, links; }; int devfs_create(struct cdev *); +int devfs_create_link(struct cdev *, const char *name); int devfs_remove(struct cdev *); int cdev_find_free_index(const char *); struct cdev *device_find_partition(struct device_d *dev, const char *name); struct cdev *cdev_by_name(const char *filename); +struct cdev *lcdev_by_name(const char *filename); +struct cdev *cdev_readlink(struct cdev *cdev); struct cdev *cdev_by_device_node(struct device_node *node); struct cdev *cdev_open(const char *name, unsigned long flags); int cdev_do_open(struct cdev *, unsigned long flags); -- 2.6.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] partition: Create links with partition names 2015-12-16 9:47 [PATCH v2] Symlink support for devfs Sascha Hauer 2015-12-16 9:47 ` [PATCH 1/2] devfs: Add symlink support Sascha Hauer @ 2015-12-16 9:47 ` Sascha Hauer 1 sibling, 0 replies; 7+ messages in thread From: Sascha Hauer @ 2015-12-16 9:47 UTC (permalink / raw) To: Barebox List When a partition has a name create a link to the original partition rather than registering a second cdev. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/partitions.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/common/partitions.c b/common/partitions.c index 4f50bfe..82ec508 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -71,20 +71,14 @@ static int register_one_partition(struct block_device *blk, if (!part->name[0]) return 0; - partition_name = asprintf("%s.%s", blk->cdev.name, part->name); - if (!partition_name) - return -ENOMEM; - - dev_dbg(blk->dev, "Registering partition %s on drive %s\n", - partition_name, blk->cdev.name); - cdev = devfs_add_partition(blk->cdev.name, - start, size, 0, partition_name); - - if (IS_ERR(cdev)) - dev_warn(blk->dev, "Registering partition %s on drive %s failed\n", - partition_name, blk->cdev.name); + partition_name = xasprintf("%s.%s", blk->cdev.name, part->name); + ret = devfs_create_link(cdev, partition_name); + if (ret) + dev_warn(blk->dev, "Failed to create link from %s to %s\n", + partition_name, blk->cdev.name); + free(partition_name); - ret = 0; + return 0; out: free(partition_name); return ret; -- 2.6.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 1/2] devfs: Add symlink support @ 2015-12-11 10:40 Sascha Hauer 2015-12-11 10:40 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer 0 siblings, 1 reply; 7+ messages in thread From: Sascha Hauer @ 2015-12-11 10:40 UTC (permalink / raw) To: Barebox List Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- fs/devfs-core.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---------- fs/devfs.c | 27 ++++++++++++++++++++- include/driver.h | 4 ++++ 3 files changed, 89 insertions(+), 14 deletions(-) diff --git a/fs/devfs-core.c b/fs/devfs-core.c index 2541ea3..1e899a1 100644 --- a/fs/devfs-core.c +++ b/fs/devfs-core.c @@ -46,7 +46,18 @@ int devfs_partition_complete(struct string_list *sl, char *instr) } #endif -struct cdev *cdev_by_name(const char *filename) +struct cdev *cdev_readlink(struct cdev *cdev) +{ + if (cdev->link) + cdev = cdev->link; + + /* links to links are not allowed */ + BUG_ON(cdev->link); + + return cdev; +} + +struct cdev *lcdev_by_name(const char *filename) { struct cdev *cdev; @@ -57,6 +68,17 @@ struct cdev *cdev_by_name(const char *filename) 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; @@ -65,7 +87,7 @@ struct cdev *cdev_by_device_node(struct device_node *node) if (!cdev->device_node) continue; if (cdev->device_node == node) - return cdev; + return cdev_readlink(cdev); } return NULL; } @@ -111,14 +133,6 @@ int cdev_find_free_index(const char *basename) return -EBUSY; /* all indexes are used */ } -int cdev_do_open(struct cdev *cdev, unsigned long flags) -{ - if (cdev->ops->open) - return cdev->ops->open(cdev, flags); - - return 0; -} - struct cdev *cdev_open(const char *name, unsigned long flags) { struct cdev *cdev; @@ -131,9 +145,11 @@ struct cdev *cdev_open(const char *name, unsigned long flags) if (!cdev) return NULL; - ret = cdev_do_open(cdev, flags); - if (ret) - return NULL; + if (cdev->ops->open) { + ret = cdev->ops->open(cdev, flags); + if (ret) + return NULL; + } return cdev; } @@ -266,8 +282,31 @@ int devfs_create(struct cdev *new) return 0; } +int devfs_create_link(struct cdev *cdev, const char *name) +{ + struct cdev *new; + + if (cdev_by_name(name)) + return -EEXIST; + + /* + * Create a link to the real cdev instead of creating + * a link to a link. + */ + cdev = cdev_readlink(cdev); + + new = xzalloc(sizeof(*new)); + new->name = xstrdup(name); + new->link = cdev; + list_add_tail(&new->list, &cdev_list); + + return 0; +} + int devfs_remove(struct cdev *cdev) { + struct cdev *c, *tmp; + if (cdev->open) return -EBUSY; @@ -275,6 +314,13 @@ int devfs_remove(struct cdev *cdev) if (cdev->dev) list_del(&cdev->devices_list); + list_for_each_entry_safe(c, tmp, &cdev_list, list) + if (c->link == cdev) + devfs_remove(c); + + if (cdev->link) + free(cdev); + return 0; } diff --git a/fs/devfs.c b/fs/devfs.c index 5c96682..0b8d4fd 100644 --- a/fs/devfs.c +++ b/fs/devfs.c @@ -212,12 +212,18 @@ static int devfs_stat(struct device_d *_dev, const char *filename, struct stat * { struct cdev *cdev; - cdev = cdev_by_name(filename + 1); + cdev = lcdev_by_name(filename + 1); if (!cdev) return -ENOENT; s->st_mode = S_IFCHR; s->st_size = cdev->size; + + if (cdev->link) + s->st_mode |= S_IFLNK; + + cdev = cdev_readlink(cdev); + if (cdev->ops->write) s->st_mode |= S_IWUSR; if (cdev->ops->read) @@ -242,6 +248,24 @@ static void devfs_delete(struct device_d *dev) { } +static int devfs_readlink(struct device_d *dev, const char *pathname, + char *buf, size_t bufsz) +{ + struct cdev *cdev; + + cdev = cdev_by_name(pathname + 1); + if (!cdev) + return -ENOENT; + + while (cdev->link) + cdev = cdev->link; + + bufsz = min(bufsz, strlen(cdev->name)); + memcpy(buf, cdev->name, bufsz); + + return 0; +} + static struct fs_driver_d devfs_driver = { .read = devfs_read, .write = devfs_write, @@ -258,6 +282,7 @@ static struct fs_driver_d devfs_driver = { .erase = devfs_erase, .protect = devfs_protect, .memmap = devfs_memmap, + .readlink = devfs_readlink, .flags = FS_DRIVER_NO_DEV, .drv = { .probe = devfs_probe, diff --git a/include/driver.h b/include/driver.h index 046dd90..29686f5 100644 --- a/include/driver.h +++ b/include/driver.h @@ -450,13 +450,17 @@ struct cdev { int open; struct mtd_info *mtd; u8 dos_partition_type; + struct cdev *link; }; int devfs_create(struct cdev *); +int devfs_create_link(struct cdev *, const char *name); int devfs_remove(struct cdev *); int cdev_find_free_index(const char *); struct cdev *device_find_partition(struct device_d *dev, const char *name); struct cdev *cdev_by_name(const char *filename); +struct cdev *lcdev_by_name(const char *filename); +struct cdev *cdev_readlink(struct cdev *cdev); struct cdev *cdev_by_device_node(struct device_node *node); struct cdev *cdev_open(const char *name, unsigned long flags); int cdev_do_open(struct cdev *, unsigned long flags); -- 2.6.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] partition: Create links with partition names 2015-12-11 10:40 [PATCH 1/2] devfs: Add symlink support Sascha Hauer @ 2015-12-11 10:40 ` Sascha Hauer 2015-12-11 19:29 ` Trent Piepho 0 siblings, 1 reply; 7+ messages in thread From: Sascha Hauer @ 2015-12-11 10:40 UTC (permalink / raw) To: Barebox List When a partition has a name create a link to the original partition rather than registering a second cdev. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- common/partitions.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/common/partitions.c b/common/partitions.c index 4f50bfe..82ec508 100644 --- a/common/partitions.c +++ b/common/partitions.c @@ -71,20 +71,14 @@ static int register_one_partition(struct block_device *blk, if (!part->name[0]) return 0; - partition_name = asprintf("%s.%s", blk->cdev.name, part->name); - if (!partition_name) - return -ENOMEM; - - dev_dbg(blk->dev, "Registering partition %s on drive %s\n", - partition_name, blk->cdev.name); - cdev = devfs_add_partition(blk->cdev.name, - start, size, 0, partition_name); - - if (IS_ERR(cdev)) - dev_warn(blk->dev, "Registering partition %s on drive %s failed\n", - partition_name, blk->cdev.name); + partition_name = xasprintf("%s.%s", blk->cdev.name, part->name); + ret = devfs_create_link(cdev, partition_name); + if (ret) + dev_warn(blk->dev, "Failed to create link from %s to %s\n", + partition_name, blk->cdev.name); + free(partition_name); - ret = 0; + return 0; out: free(partition_name); return ret; -- 2.6.2 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] partition: Create links with partition names 2015-12-11 10:40 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer @ 2015-12-11 19:29 ` Trent Piepho 2015-12-14 9:25 ` Sascha Hauer 0 siblings, 1 reply; 7+ messages in thread From: Trent Piepho @ 2015-12-11 19:29 UTC (permalink / raw) To: Sascha Hauer; +Cc: Barebox List On Fri, 2015-12-11 at 11:40 +0100, Sascha Hauer wrote: > When a partition has a name create a link to the original partition > rather than registering a second cdev. What does devinfo look like now? Do named partition still show up? _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] partition: Create links with partition names 2015-12-11 19:29 ` Trent Piepho @ 2015-12-14 9:25 ` Sascha Hauer 2015-12-14 18:44 ` Trent Piepho 0 siblings, 1 reply; 7+ messages in thread From: Sascha Hauer @ 2015-12-14 9:25 UTC (permalink / raw) To: Trent Piepho; +Cc: Barebox List On Fri, Dec 11, 2015 at 07:29:25PM +0000, Trent Piepho wrote: > On Fri, 2015-12-11 at 11:40 +0100, Sascha Hauer wrote: > > When a partition has a name create a link to the original partition > > rather than registering a second cdev. > > What does devinfo look like now? Do named partition still show up? No, they won't. Is that necessary? At least an ls -l in /dev/ now shows that the different devices are really the same. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] partition: Create links with partition names 2015-12-14 9:25 ` Sascha Hauer @ 2015-12-14 18:44 ` Trent Piepho 0 siblings, 0 replies; 7+ messages in thread From: Trent Piepho @ 2015-12-14 18:44 UTC (permalink / raw) To: Sascha Hauer; +Cc: Barebox List On Mon, 2015-12-14 at 10:25 +0100, Sascha Hauer wrote: > On Fri, Dec 11, 2015 at 07:29:25PM +0000, Trent Piepho wrote: > > On Fri, 2015-12-11 at 11:40 +0100, Sascha Hauer wrote: > > > When a partition has a name create a link to the original partition > > > rather than registering a second cdev. > > > > What does devinfo look like now? Do named partition still show up? > > No, they won't. Is that necessary? At least an ls -l in /dev/ now shows > that the different devices are really the same. It's a very nice feature to be able to see the partitions in devinfo. Especially for the named partitions, since you can't tell what order they are from the names. _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2015-12-16 9:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-12-16 9:47 [PATCH v2] Symlink support for devfs Sascha Hauer 2015-12-16 9:47 ` [PATCH 1/2] devfs: Add symlink support Sascha Hauer 2015-12-16 9:47 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer -- strict thread matches above, loose matches on Subject: below -- 2015-12-11 10:40 [PATCH 1/2] devfs: Add symlink support Sascha Hauer 2015-12-11 10:40 ` [PATCH 2/2] partition: Create links with partition names Sascha Hauer 2015-12-11 19:29 ` Trent Piepho 2015-12-14 9:25 ` Sascha Hauer 2015-12-14 18:44 ` Trent Piepho
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox