Skip to content

Commit

Permalink
mtd: partitions: add support for subpartitions
Browse files Browse the repository at this point in the history
Some flash device partitions can be containers with extra subpartitions
(volumes). All callbacks are already capable of this additional level of
indirection.

This patch makes sure we always display subpartitions using a tree
structure and takes care of deleting subpartitions when parent gets
removed.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
  • Loading branch information
Rafał Miłecki authored and Brian Norris committed Jun 22, 2017
1 parent 0a9d72b commit 97519dc
Showing 1 changed file with 16 additions and 7 deletions.
23 changes: 16 additions & 7 deletions drivers/mtd/mtdpart.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *parent,
* parent conditional on that option. Note, this is a way to
* distinguish between the master and the partition in sysfs.
*/
slave->mtd.dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) ?
slave->mtd.dev.parent = IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER) || mtd_is_partition(parent) ?
&parent->dev :
parent->dev.parent;
slave->mtd.dev.of_node = part->of_node;
Expand Down Expand Up @@ -664,8 +664,17 @@ EXPORT_SYMBOL_GPL(mtd_add_partition);
*/
static int __mtd_del_partition(struct mtd_part *priv)
{
struct mtd_part *child, *next;
int err;

list_for_each_entry_safe(child, next, &mtd_partitions, list) {
if (child->parent == &priv->mtd) {
err = __mtd_del_partition(child);
if (err)
return err;
}
}

sysfs_remove_files(&priv->mtd.dev.kobj, mtd_partition_attrs);

err = del_mtd_device(&priv->mtd);
Expand All @@ -680,16 +689,16 @@ static int __mtd_del_partition(struct mtd_part *priv)

/*
* This function unregisters and destroy all slave MTD objects which are
* attached to the given master MTD object.
* attached to the given MTD object.
*/
int del_mtd_partitions(struct mtd_info *master)
int del_mtd_partitions(struct mtd_info *mtd)
{
struct mtd_part *slave, *next;
int ret, err = 0;

mutex_lock(&mtd_partitions_mutex);
list_for_each_entry_safe(slave, next, &mtd_partitions, list)
if (slave->parent == master) {
if (slave->parent == mtd) {
ret = __mtd_del_partition(slave);
if (ret < 0)
err = ret;
Expand All @@ -699,14 +708,14 @@ int del_mtd_partitions(struct mtd_info *master)
return err;
}

int mtd_del_partition(struct mtd_info *master, int partno)
int mtd_del_partition(struct mtd_info *mtd, int partno)
{
struct mtd_part *slave, *next;
int ret = -EINVAL;

mutex_lock(&mtd_partitions_mutex);
list_for_each_entry_safe(slave, next, &mtd_partitions, list)
if ((slave->parent == master) &&
if ((slave->parent == mtd) &&
(slave->mtd.index == partno)) {
ret = __mtd_del_partition(slave);
break;
Expand Down Expand Up @@ -939,6 +948,6 @@ uint64_t mtd_get_device_size(const struct mtd_info *mtd)
if (!mtd_is_partition(mtd))
return mtd->size;

return mtd_to_part(mtd)->parent->size;
return mtd_get_device_size(mtd_to_part(mtd)->parent);
}
EXPORT_SYMBOL_GPL(mtd_get_device_size);

0 comments on commit 97519dc

Please sign in to comment.