RE: [PATCH v7 01/12] mtd: core: always create master device
From: Usyskin, Alexander
Date: Thu Apr 10 2025 - 10:19:32 EST
> Subject: RE: [PATCH v7 01/12] mtd: core: always create master device
>
> Hi
>
> > Hello,
> >
> > > The mtd_master is completely different class to avoid mtd tree
> disturbances.
> > > It is real kernel device object, I'm not sure how we can do 'link to'
> > > magic here.
> >
> > Maybe we can add that later if someone needs.
> >
> > > About MTD_PARTITIONED_MASTER - we can treat it as another partition
> > and
> > > create master device plus whole device partition as it's child with all other
> > > partitions as children of master device.
> > > For unpartitioned device this mean that we create master device and
> > partition
> > > regardless of MTD_PARTITIONED_MASTER flag.
> >
> > I am not sure I follow you. I am proposing to create the mtd_master
> > device in all cases. I believe this is the future-proof approach. Can
> > you make this change?
> >
> > Regarding the hierarchy, I indeed agree with what you propose:
> > mtd_master parent of whole partition device (if any) parent of
> > partitions.
> >
>
> To be sure:
>
> You want to have this hierarchy without MTD_PARTITIONED_MASTER:
> mtd_master
> \/
> |->partition1
> |->partition2
>
> With MTD_PARTITIONED_MASTER flag:
>
> mtd_master
> \/
> |->master_partition
> \/
> |->partition1
> |->partition2
>
Like this?
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 8dc4f5c493fc..391d81ad960c 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -559,7 +559,7 @@ static int mtdchar_blkpg_ioctl(struct mtd_info *mtd,
/* Sanitize user input */
p.devname[BLKPG_DEVNAMELTH - 1] = '\0';
- return mtd_add_partition(mtd, p.devname, p.start, p.length);
+ return mtd_add_partition(mtd, p.devname, p.start, p.length, NULL);
case BLKPG_DEL_PARTITION:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index ee46766d74f1..a32cea0ba535 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -1108,6 +1108,7 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
const struct mtd_partition *parts,
int nr_parts)
{
+ struct mtd_info *parent;
int ret, err;
mtd_set_dev_defaults(mtd);
@@ -1116,17 +1117,31 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types,
if (ret)
goto out;
+ ret = add_mtd_device(mtd, false);
+ if (ret)
+ goto out;
+
+ if (IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+ {
+ ret = mtd_add_partition(mtd, dev_name(&mtd->dev), 0, MTDPART_SIZ_FULL, &parent);
+ if (ret)
+ goto out;
+
+ } else {
+ parent = mtd;
+ }
+
/* Prefer parsed partitions over driver-provided fallback */
- ret = parse_mtd_partitions(mtd, types, parser_data);
+ ret = parse_mtd_partitions(parent, types, parser_data);
if (ret == -EPROBE_DEFER)
goto out;
if (ret > 0)
ret = 0;
else if (nr_parts)
- ret = add_mtd_partitions(mtd, parts, nr_parts);
- else
- ret = add_mtd_device(mtd, true);
+ ret = add_mtd_partitions(parent, parts, nr_parts);
+ else if (!IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER))
+ ret = mtd_add_partition(parent, dev_name(&mtd->dev), 0, MTDPART_SIZ_FULL, NULL);
if (ret)
goto out;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 8a019cf0360d..cd5ae919b80c 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -242,7 +242,7 @@ static int mtd_add_partition_attrs(struct mtd_info *new)
}
int mtd_add_partition(struct mtd_info *parent, const char *name,
- long long offset, long long length)
+ long long offset, long long length, struct mtd_info **out)
{
struct mtd_info *master = mtd_get_master(parent);
u64 parent_size = mtd_is_partition(parent) ?
@@ -281,6 +281,9 @@ int mtd_add_partition(struct mtd_info *parent, const char *name,
mtd_add_partition_attrs(child);
+ if (*out)
+ *out = child;
+
return 0;
err_remove_part:
@@ -401,12 +404,6 @@ int add_mtd_partitions(struct mtd_info *parent,
printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n",
nbparts, parent->name);
- if (!mtd_is_partition(parent)) {
- ret = add_mtd_device(parent, IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER));
- if (ret)
- return ret;
- }
-
for (i = 0; i < nbparts; i++) {
child = allocate_partition(parent, parts + i, i, cur_offset);
if (IS_ERR(child)) {
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index b74a539ec581..5daf80df9e89 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -108,7 +108,7 @@ extern void deregister_mtd_parser(struct mtd_part_parser *parser);
deregister_mtd_parser)
int mtd_add_partition(struct mtd_info *master, const char *name,
- long long offset, long long length);
+ long long offset, long long length, struct mtd_info **part);
int mtd_del_partition(struct mtd_info *master, int partno);
uint64_t mtd_get_device_size(const struct mtd_info *mtd);